This commit is contained in:
chacha
2025-09-09 00:13:06 +02:00
parent 4f5dade949
commit ab11052c8f
3 changed files with 83 additions and 12 deletions

View File

@@ -13,6 +13,7 @@ Main module __init__ file.
from .__metadata__ import __version__, __Summuary__, __Name__
from .model import (
DABFieldInfo,
DABField,
BaseAppliance,
BaseFeature,
DABModelException,

View File

@@ -476,7 +476,7 @@ class BaseMeta(type):
mcs: type["BaseMeta"], name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any] # pylint: disable=unused-argument
) -> None:
"""early BaseElement checks"""
# print("__NEW__ Defining:", name, "with keys:", list(namespace))
print("__NEW__ Defining:", name, "with keys:", list(namespace))
if len(bases) > 1:
raise MultipleInheritanceForbidden("Multiple inheritance is not supported by dabmodel")
@@ -532,9 +532,9 @@ class BaseMeta(type):
mcs: type["BaseMeta"], name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any], _fname: str, _fvalue: Any
): # pylint: disable=unused-argument
"""preprocessing BaseElement modified Fields"""
# print(f"Modified field: {_fname}")
print(f"Modified field: {_fname}")
if "__annotations__" in namespace and _fname in namespace["__annotations__"]:
raise ReadOnlyFieldAnnotation("annotations cannot be modified on derived classes")
raise ReadOnlyFieldAnnotation(f"annotations cannot be modified on derived classes {_fname}")
try:
check_type(
_fvalue,
@@ -552,7 +552,7 @@ class BaseMeta(type):
mcs: type["BaseMeta"], name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any], _fname: str, _fvalue: Any
): # pylint: disable=unused-argument
"""preprocessing BaseElement new Fields"""
# print(f"New field: {_fname}")
print(f"New field: {_fname}")
# print(f"type is: {type(_fvalue)}")
# print(f"value is: {_fvalue}")
@@ -694,27 +694,54 @@ class BaseFeature(BaseElement,metaclass=BaseMetaFeature):
Base class for Appliance's Features.
Features are optional traits of an appliance.
"""
Enabled:bool=False
class BaseMetaAppliance(BaseMeta):
@classmethod
def pre_check(
mcs: type["BaseMeta"], name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any] # pylint: disable=unused-argument
) -> None:
"""early BaseElement checks"""
print("__NEW__ Defining:", name, "with keys:", list(namespace))
super().pre_check(name,bases,namespace)
print(bases)
if len(bases)>0 and ("__DABFeatures__" not in dir(bases[0])):
print("add missing fields")
namespace["__DABFeatures__"] = {}
else:
print(f"bases[0]:{bases[0].__name__}")
print(dir(bases[0]))
# check class tree origin
if "__DABFeatures__" not in dir(bases[0]):
raise BrokenInheritance("__DABFeatures__ not found in base class, broken inheritance chain.")
# copy inherited schema
print("COPY")
namespace["__DABFeatures__"] = copy(bases[0].__DABFeatures__)
@classmethod
def pre_processing(mcs: type["BaseMeta"], name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any]):
mcs.features: dict[str,type[BaseFeature]] = {}
super().pre_processing(name,bases,namespace)
for _ftname in mcs.features.keys():
del namespace[_ftname]
#for _ftname in mcs.features.keys():
# del namespace[_ftname]
@classmethod
def pre_processing_new_fields(
mcs: type["BaseMeta"], name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any], _fname: str, _fvalue: Any
): # pylint: disable=unused-argument
"""preprocessing BaseElement new Fields"""
print('pre_processing_new_fields')
if _fname == "features":
raise ReservedFieldName("feature is a reserved field name")
elif _fname =="get_features":
pass
elif isinstance(_fvalue,BaseMetaFeature):
print("find Feature")
print(namespace["__DABFeatures__"])
if _fname in namespace["__DABFeatures__"].keys():
print("existing Feature !")
mcs.features[_fname]=_fvalue
#namespace["__DABFeatures__"][_fname] = _fvalue
else:
super().pre_processing_new_fields(name,bases,namespace,_fname,_fvalue)
@@ -723,13 +750,14 @@ class BaseMetaAppliance(BaseMeta):
mcs: type["BaseMeta"], cls, name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any] # pylint: disable=unused-argument
):
super().save_values(cls,name,bases,namespace)
print(dir(mcs))
cls.__DABFeatures__ = mcs.features
def modify_object(self, obj): # intentionally untyped
for _ftname,_ftvalue in self.features.items():
for _ftname,_ftvalue in self.__DABFeatures__.items():
instft = _ftvalue()
setattr(self, _ftname,instft )
self.__DABFeatures__[_ftname] = instft
#self.__DABFeatures__[_ftname] = instft
class BaseAppliance(BaseElement,metaclass=BaseMetaAppliance):
"""BaseFeature class

View File

@@ -1176,7 +1176,7 @@ class TestConfigWithoutEnabledFlag(unittest.TestCase):
test_initializer_safe_testfc()
def test_feature(self):
"""Testing first appliance level, and Field types (simple)"""
"""Testing first appliance feature, and Field types (simple)"""
@@ -1193,6 +1193,48 @@ class TestConfigWithoutEnabledFlag(unittest.TestCase):
self.assertIn("Feature1",app1.__DABFeatures__)
self.assertIn("VarStrInner",app1.__DABFeatures__["Feature1"].__DABSchema__)
self.assertIsInstance(app1.__DABFeatures__["Feature1"].__DABSchema__["VarStrInner"],dm.FrozenDABField)
def test_feature_inheritance(self):
"""Testing first appliance feature, and Field types (simple)"""
# class can be created
class Appliance1(dm.BaseAppliance):
VarStrOuter: str = "testvalue APPLIANCE1"
class Feature1(dm.BaseFeature):
VarStrInner: str = "testvalue FEATURE1"
VarInt:int=42
print(dir(Appliance1))
class Appliance2(Appliance1):
VarStrOuter = "testvalue APPLIANCE2"
class Feature2(dm.BaseFeature):
VarStrInner: str = "testvalue FEATURE2"
print(dir(Appliance2))
class Appliance3(Appliance2):
VarStrOuter = "testvalue APPLIANCE3"
class Feature1(Appliance1.Feature1):
VarStrInner = "testvalue FEATURE1 modded"
class Feature3(dm.BaseFeature):
VarStrInner: str = "testvalue FEATURE3"
print(dir(Appliance3))
app1 = Appliance1()
app2 = Appliance2()
app3 = Appliance3()
self.assertIsInstance(app1.__DABSchema__["VarStrOuter"],dm.FrozenDABField)
self.assertTrue(hasattr(app1, "Feature1"))
self.assertTrue(hasattr(app1.Feature1, "VarStrInner"))
self.assertIn("Feature1",app1.__DABFeatures__)
self.assertIn("VarStrInner",app1.__DABFeatures__["Feature1"].__DABSchema__)
self.assertIsInstance(app1.Feature1.__DABSchema__["VarStrInner"],dm.FrozenDABField)
self.assertIsInstance(app1.__DABFeatures__["Feature1"].__DABSchema__["VarStrInner"],dm.DABField)
# ---------- main ----------
if __name__ == "__main__":