[docs]classIPrinter(ABC):"""Base interface for all printers. Each printer receives a dispatcher in its constructor and must implement `print(target)` to produce the output for a node."""def__init__(self,dispatcher:"PrinterDispatcher")->None:self._dispatcher=dispatcher
[docs]@abstractmethoddefprint(self,target:Any)->str:"""Produced output of the printer."""
[docs]classPrinterDispatcher:"""Collects printers and chooses the right one for each node. You can register printers with `add`, remove them with `remove`, and use `print` to get code for any supported node."""def__init__(self,configuration:Optional[PrinterConfiguration]=None)->None:self.configuration=configurationorPrinterConfiguration()self._printers:dict[type,IPrinter]={}
[docs]defadd(self,target_type:type,target_printer_type:type[IPrinter])->None:"""Register a printer for the given node type."""self._printers[target_type]=target_printer_type(self)
[docs]defremove(self,target_type:type)->None:"""Unregister the printer for the given node type."""delself._printers[target_type]
[docs]defprint(self,target:Any)->str:"""Produces source code for the given AST node."""target_type=type(target)ifprinter:=self._printers.get(target_type):returnprinter.print(target)raiseKeyError(f"No printer registered for node: {target}.")