Source code for cement.core.meta

"""Cement core meta functionality."""

from typing import Any


[docs] class Meta: """ Container class for meta attributes of a larger class. Keyword arguments are set as attributes of ``self``. """ # D-09: Meta classes carry user-arbitrary attributes by design # (config_defaults, extensions, handlers, hooks, ...). The wide kwargs # type IS the public Meta contract (D-12). `_merge` is internal but the # dict it merges has the same arbitrary-value contract. def __init__(self, **kwargs: Any) -> None: self._merge(kwargs) # D-09: same arbitrary-value contract as `__init__` above. def _merge(self, dict_obj: dict[str, Any]) -> None: for key in dict_obj.keys(): setattr(self, key, dict_obj[key])
[docs] class MetaMixin: """ Mixin that provides the meta class support to add settings to instances of objects. Meta keys cannot start with a ``_``. """ # D-09: same Meta arbitrary-attribute contract — `*args` accepts any # positional cooperative-multi-inheritance super() chain payload. def __init__(self, *args: Any, **kwargs: Any) -> None: # Get a List of all the Classes we in our MRO, find any attribute named # Meta on them, and then merge them together in order of MRO metas = reversed([x.Meta for x in self.__class__.mro() if hasattr(x, "Meta")]) final_meta = {} # Merge the Meta classes into one dict for meta in metas: final_meta.update(dict([x for x in meta.__dict__.items() if not x[0].startswith("_")])) # Update the final Meta with any kwargs passed in for key in final_meta.keys(): if key in kwargs: final_meta[key] = kwargs.pop(key) self._meta = Meta(**final_meta) # FIX ME: object.__init__() doesn't take params without exception super().__init__()