jmri_logixng.registry
Type registry — maps type_tag strings to concrete node classes.
Used by the serializer: a serialized tree carries type: <tag> fields,
and the deserializer looks up the class by tag, then calls
cls.from_dict(payload, registry) (or a default reflection-based
constructor) to rebuild the node.
The registry is populated at import time by every action/expression
module via register(). Tests use snapshot() /
restore() to isolate registrations.
1"""Type registry — maps ``type_tag`` strings to concrete node classes. 2 3Used by the serializer: a serialized tree carries ``type: <tag>`` fields, 4and the deserializer looks up the class by tag, then calls 5``cls.from_dict(payload, registry)`` (or a default reflection-based 6constructor) to rebuild the node. 7 8The registry is populated at import time by every action/expression 9module via :func:`register`. Tests use :func:`snapshot` / 10:func:`restore` to isolate registrations. 11""" 12from __future__ import annotations 13 14from typing import TYPE_CHECKING 15 16if TYPE_CHECKING: 17 from jmri_logixng.tree import Node 18 19 20_REGISTRY: dict[str, type[Node]] = {} 21 22 23def register(cls: type[Node]) -> type[Node]: 24 """Register a node class by its ``type_tag``. Usable as a decorator. 25 26 Raises if the tag is already registered to a different class. 27 """ 28 tag = cls.type_tag 29 if not tag: 30 raise ValueError(f"{cls.__name__}.type_tag must be set before registration") 31 existing = _REGISTRY.get(tag) 32 if existing is not None and existing is not cls: 33 raise ValueError( 34 f"type_tag {tag!r} already registered to {existing.__name__}, " 35 f"can't re-register to {cls.__name__}" 36 ) 37 _REGISTRY[tag] = cls 38 return cls 39 40 41def lookup(tag: str) -> type[Node]: 42 """Find the class for *tag*. Raises ``KeyError`` if unknown.""" 43 if tag not in _REGISTRY: 44 raise KeyError(f"unknown LogixNG type tag: {tag!r}") 45 return _REGISTRY[tag] 46 47 48def known_tags() -> list[str]: 49 return sorted(_REGISTRY) 50 51 52def snapshot() -> dict[str, type[Node]]: 53 return dict(_REGISTRY) 54 55 56def restore(snap: dict[str, type[Node]]) -> None: 57 _REGISTRY.clear() 58 _REGISTRY.update(snap)
24def register(cls: type[Node]) -> type[Node]: 25 """Register a node class by its ``type_tag``. Usable as a decorator. 26 27 Raises if the tag is already registered to a different class. 28 """ 29 tag = cls.type_tag 30 if not tag: 31 raise ValueError(f"{cls.__name__}.type_tag must be set before registration") 32 existing = _REGISTRY.get(tag) 33 if existing is not None and existing is not cls: 34 raise ValueError( 35 f"type_tag {tag!r} already registered to {existing.__name__}, " 36 f"can't re-register to {cls.__name__}" 37 ) 38 _REGISTRY[tag] = cls 39 return cls
Register a node class by its type_tag. Usable as a decorator.
Raises if the tag is already registered to a different class.
42def lookup(tag: str) -> type[Node]: 43 """Find the class for *tag*. Raises ``KeyError`` if unknown.""" 44 if tag not in _REGISTRY: 45 raise KeyError(f"unknown LogixNG type tag: {tag!r}") 46 return _REGISTRY[tag]
Find the class for tag. Raises KeyError if unknown.