Source code for segram.utils.meta

"""Metaprogramming utilities."""
from typing import Any
from types import FunctionType, MethodType


[docs] def get_cname(obj: Any) -> str: """Get class name.""" if not isinstance(obj, type): obj = type(obj) return obj.__name__
[docs] def get_ppath(obj: Any) -> str: """Get full python path a named python object.""" if not isinstance(obj, type | FunctionType | MethodType): obj = type(obj) return f"{obj.__module__}.{obj.__qualname__}"
[docs] def init_class_attrs( cls, attrs: dict[str, str], *, check_slots: bool = True ) -> None: """Initialize special class attributes if they are not already defined and set final values. Parameters ---------- attrs Dictionary from class special attribute names to the names of final attributes. check_slots Check if attribute names are correctly declared as slots. """ for attr in attrs: if attr not in cls.__dict__: setattr(cls, attr, ()) for attr, final in attrs.items(): slots = getattr(cls, attr) if check_slots and (incorrect := set(slots) - set(cls.__slots__)): raise TypeError( f"names in '{attr}' are not declared " f"in '__slots__': {tuple(incorrect)}" ) names = [] for typ in reversed(cls.mro()): names.extend(typ.__dict__.get(attr, ())) if len(names) != len(set(names)): raise TypeError(f"repeated '{attr}' slots: {names}") setattr(cls, final, tuple(names))