1"""Rendering engine parameter handling.""" 
    2 
    3from collections.abc import Set 
    4from typing import Final 
    5 
    6from . import base 
    7 
    8__all__ = ['ENGINES', 'verify_engine', 'Engine'] 
    9 
    10ENGINES: Final[Set[str]] = {'dot',  # https://www.graphviz.org/pdf/dot.1.pdf 
    11                            'neato', 
    12                            'twopi', 
    13                            'circo', 
    14                            'fdp', 
    15                            'sfdp', 
    16                            'patchwork', 
    17                            'osage'} 
    18 
    19DEFAULT_ENGINE: Final = 'dot' 
    20 
    21REQUIRED: Final = True 
    22 
    23 
    24def verify_engine(engine: str, *, required: bool = REQUIRED) -> None: 
    25    if engine is None: 
    26        if required: 
    27            raise ValueError('missing engine') 
    28    elif engine.lower() not in ENGINES: 
    29        raise ValueError(f'unknown engine: {engine!r}' 
    30                         f' (must be one of {sorted(ENGINES)})') 
    31 
    32 
    33class Engine(base.ParameterBase): 
    34    """Rendering engine parameter with ``'dot''`` default.""" 
    35 
    36    _engine = DEFAULT_ENGINE 
    37 
    38    _verify_engine = staticmethod(verify_engine) 
    39 
    40    def __init__(self, *, engine: str | None = None, **kwargs) -> None: 
    41        super().__init__(**kwargs) 
    42 
    43        if engine is not None: 
    44            self.engine = engine 
    45 
    46    def _copy_kwargs(self, **kwargs): 
    47        """Return the kwargs to create a copy of the instance.""" 
    48        engine = self._getattr_from_dict('_engine') 
    49        if engine is not None: 
    50            kwargs['engine'] = engine 
    51        return super()._copy_kwargs(**kwargs) 
    52 
    53    @property 
    54    def engine(self) -> str: 
    55        """The layout engine used for rendering 
    56            (``'dot'``, ``'neato'``, ...).""" 
    57        return self._engine 
    58 
    59    @engine.setter 
    60    def engine(self, engine: str) -> None: 
    61        engine = engine.lower() 
    62        self._verify_engine(engine) 
    63        self._engine = engine