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