work
This commit is contained in:
@@ -13,6 +13,7 @@ Main module __init__ file.
|
||||
from .__metadata__ import __version__, __Summuary__, __Name__
|
||||
from .model import (
|
||||
DABFieldInfo,
|
||||
DABField,
|
||||
BaseAppliance,
|
||||
BaseFeature,
|
||||
DABModelException,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__":
|
||||
|
||||
Reference in New Issue
Block a user