diff --git a/src/viur/core/bones/relational.py b/src/viur/core/bones/relational.py index cf40766ed..57965cc78 100644 --- a/src/viur/core/bones/relational.py +++ b/src/viur/core/bones/relational.py @@ -309,6 +309,10 @@ def setSystemInitialized(self): raise NotImplementedError( f"Skeleton {self.skel_cls!r} {self.__class__.__name__} {self.name!r}: Kind {self.kind!r} unknown" ) + logging.debug(f"RelationalBone.setSystemInitialized {self.kind} {self.name} {self._refSkelCache=} {list(self._refSkelCache.__boneMap__.keys())=}") + # logging.debug(f"RelationalBone.setSystemInitialized {self.kind} {self.name} {self._refSkelCache=} {list(self._refSkelCache.__boneMap__.keys())=} {self._refSkelCache().structure()=}") + # logging.debug(f"RelationalBone.setSystemInitialized {self.kind} {self.name} {self._refSkelCache()=} {list(self._refSkelCache().boneMap.keys())=}") + # logging.debug(f"RelationalBone.setSystemInitialized {self.kind} {self.name} {self._refSkelCache=} {list(self._refSkelCache.boneMap)=}") self._skeletonInstanceClassRef = SkeletonInstance self._ref_keys = set(self._refSkelCache.__boneMap__.keys()) @@ -1268,6 +1272,7 @@ def getUniquePropertyIndexValues(self, valuesCache: dict, name: str) -> list[str return self._hashValueForUniquePropertyIndex([entry["dest"]["key"] for entry in value if entry]) def structure(self) -> dict: + print(f"RelationalBone structure: {self.kind=} {self.name=} ") return super().structure() | { "type": f"{self.type}.{self.kind}", "module": self.module, diff --git a/src/viur/core/skeleton/instance.py b/src/viur/core/skeleton/instance.py index 7b024171d..12f0328c8 100644 --- a/src/viur/core/skeleton/instance.py +++ b/src/viur/core/skeleton/instance.py @@ -214,6 +214,8 @@ def __getattr__(self, item: str): }: return partial(getattr(self.skeletonCls, item), self) + print(f"Accessing {item} from {self.skeletonCls}") + # Load a @property from the Skeleton class try: # Use try/except to save an if check @@ -329,6 +331,7 @@ def setEntity(self, entity: db.Entity): self.renderAccessedValues = {} def structure(self) -> dict: + print(f"SkeletonInstance structure: {self.skeletonCls=} {list(self.keys())=}") return { key: bone.structure() | {"sortindex": i} for i, (key, bone) in enumerate(self.items()) diff --git a/src/viur/core/skeleton/meta.py b/src/viur/core/skeleton/meta.py index 7c6450cce..0473be6fc 100644 --- a/src/viur/core/skeleton/meta.py +++ b/src/viur/core/skeleton/meta.py @@ -5,13 +5,14 @@ import string import sys import typing as t + from deprecated.sphinx import deprecated + from .adapter import ViurTagsSearchAdapter -from ..bones.base import BaseBone, ReadFromClientErrorSeverity, getSystemInitialized from .. import db, utils +from ..bones.base import BaseBone, ReadFromClientErrorSeverity, getSystemInitialized from ..config import conf - _UNDEFINED_KINDNAME = object() ABSTRACT_SKEL_CLS_SUFFIX = "AbstractSkel" KeyType: t.TypeAlias = db.Key | str | int @@ -76,9 +77,20 @@ def generate_bonemap(cls): """ Recursively constructs a dict of bones from """ + print(f"{cls.__name__} generated") map = {} + # from .relskel import RefSkel, RelSkel + # from .skeleton import Skeleton + ignore_base = getattr(cls, "_ignore_base", None) + + print(f"{cls=} {cls.__bases__=} {ignore_base=}") for base in cls.__bases__: + + # if issubclass(base, RefSkel) and issubclass(base,Skeleton): + # continue + if base is ignore_base: + continue if "__viurBaseSkeletonMarker__" in dir(base): map |= MetaBaseSkel.generate_bonemap(base) @@ -109,6 +121,10 @@ class MetaSkel(MetaBaseSkel): def __init__(cls, name, bases, dct, **kwargs): super().__init__(name, bases, dct, **kwargs) + from .relskel import RefSkel + + if issubclass(cls, RefSkel): + return relNewFileName = inspect.getfile(cls) \ .replace(str(conf.instance.project_base_path), "") \ @@ -124,9 +140,9 @@ def __init__(cls, name, bases, dct, **kwargs): # Automatic determination of the kindName, if the class is not part of viur.core. if ( - cls.kindName is _UNDEFINED_KINDNAME - and not relNewFileName.strip(os.path.sep).startswith("viur") - and "viur_doc_build" not in dir(sys) # do not check during documentation build + cls.kindName is _UNDEFINED_KINDNAME + and not relNewFileName.strip(os.path.sep).startswith("viur") + and "viur_doc_build" not in dir(sys) # do not check during documentation build ): if cls.__name__.endswith("Skel"): cls.kindName = cls.__name__.lower()[:-4] @@ -157,8 +173,8 @@ def __init__(cls, name, bases, dct, **kwargs): # Ensure that all skeletons are defined in folders listed in conf.skeleton_search_path if ( - not any([relNewFileName.startswith(path) for path in conf.skeleton_search_path]) - and "viur_doc_build" not in dir(sys) # do not check during documentation build + not any([relNewFileName.startswith(path) for path in conf.skeleton_search_path]) + and "viur_doc_build" not in dir(sys) # do not check during documentation build ): raise NotImplementedError( f"""{relNewFileName} must be defined in a folder listed in {conf.skeleton_search_path}""") @@ -451,4 +467,5 @@ def readonly(cls, skel: "SkeletonInstance"): def __new__(cls, *args, **kwargs) -> "SkeletonInstance": from .instance import SkeletonInstance + print(f"BaseSkeleton.NEW {cls=} {args} {kwargs} {list(cls.__boneMap__.keys())=}") return SkeletonInstance(cls, *args, **kwargs) diff --git a/src/viur/core/skeleton/relskel.py b/src/viur/core/skeleton/relskel.py index 09a2a5dd4..6f8663ea3 100644 --- a/src/viur/core/skeleton/relskel.py +++ b/src/viur/core/skeleton/relskel.py @@ -1,11 +1,11 @@ from __future__ import annotations # noqa: required for pre-defined annotations -import typing as t import fnmatch +import typing as t -from .. import db, utils from .meta import BaseSkeleton from .utils import skeletonByKind +from .. import db, utils class RelSkel(BaseSkeleton): @@ -58,13 +58,16 @@ def fromSkel(cls, kindName: str, *args: list[str]) -> t.Type[RefSkel]: :param args: List of bone names we'll adapt :return: A new instance of RefSkel """ - newClass = type("RefSkelFor" + kindName, (RefSkel,), {}) fromSkel = skeletonByKind(kindName) + newClass = type("RefSkelFor" + kindName, (RefSkel, fromSkel), {}) newClass.kindName = kindName + newClass._ignore_base = fromSkel bone_map = {} for arg in args: bone_map |= {k: fromSkel.__boneMap__[k] for k in fnmatch.filter(fromSkel.__boneMap__.keys(), arg)} newClass.__boneMap__ = bone_map + print(f"RefSkelFor{kindName}: {bone_map.keys()}") + print(f"RefSkelFor{kindName}: {newClass.__boneMap__.keys()}") return newClass def read( diff --git a/src/viur/core/skeleton/skeleton.py b/src/viur/core/skeleton/skeleton.py index 7db5fe54b..15e9e7cde 100644 --- a/src/viur/core/skeleton/skeleton.py +++ b/src/viur/core/skeleton/skeleton.py @@ -101,7 +101,7 @@ class Skeleton(BaseSkeleton, metaclass=MetaSkel): shortkey = RawBone( descr="Shortkey", - compute=Compute(lambda skel: skel["key"].id_or_name if skel["key"] else None), + compute=Compute(lambda skel: 'skel["key"].id_or_name' if skel["key"] else None), readOnly=True, visible=False, searchable=True,