Compare commits

...

1 Commits

Author SHA1 Message Date
cclecle
87682c2c9c cleaning a little bit... 2025-01-08 18:00:33 +01:00
4 changed files with 58 additions and 50 deletions

View File

@@ -12,3 +12,4 @@ Main module __init__ file.
from .__metadata__ import __version__, __Summuary__, __Name__
from .model import DABField, BaseFeature, BaseAppliance, default_values_override
from .tools import DABJSONEncoder

View File

@@ -90,9 +90,9 @@ class BaseElementMeta(ModelMetaclass, ABCMeta):
cls_name,
bases,
namespace,
None, #__pydantic_generic_metadata__,
True, #__pydantic_reset_parent_namespace__,
None, #_create_model_module,
None, # __pydantic_generic_metadata__,
True, # __pydantic_reset_parent_namespace__,
None, # _create_model_module,
**kwargs,
)
@@ -148,9 +148,7 @@ class BaseElement(
cls._saved_default_value = {}
for field_key, field_val in cls.model_fields.items():
assert field_val.annotation is not None, "all fields must have annotation"
assert not runtype_issubclass(
field_val.annotation, BaseFeature
), "Features can only be in Appliance's features[] dict attribute"
assert not runtype_issubclass(field_val.annotation, BaseFeature), "Features can only be contained within an Appliance"
if field_val.default != PydanticUndefined:
cls._saved_default_value[field_key] = deepcopy(field_val.default)
for method, _ in cls._config_element.default_values_override_methods.items():
@@ -172,11 +170,12 @@ class BaseElement(
cls._saved_default_value[attr_key] = attr_val
class BaseFeature(BaseElement, ABC):
...
class BaseFeature(BaseElement, ABC): ...
T_Feature = TypeVar("T_Feature", bound=BaseFeature)
class BaseAppliance(Generic[T_Feature], BaseElement, ABC):
cpu_cnt: Annotated[StrictInt, DABField(1, gt=0)]
ram_size: Annotated[ByteSize, DABField(256, gt=128)]
@@ -192,6 +191,7 @@ class BaseAppliance(Generic[T_Feature], BaseElement, ABC):
dabinst_description: Annotated[StrictStr | None, DABField("")]
dabinst_creationdate: Annotated[AwareDatetime | None, DABField(datetime.now(tz=pytz.utc))]
def default_values_override(func: T_BaseElement_ConfigMethod) -> T_BaseElement_ConfigMethod:
func = ensure_classmethod_based_on_signature(func)
setattr(func, "default_values_override", lambda: True)

13
src/dabmodel/tools.py Normal file
View File

@@ -0,0 +1,13 @@
from uuid import UUID
from datetime import datetime
import json
class DABJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, UUID):
# if the obj is uuid, we simply return the value of uuid
return obj.hex
elif isinstance(obj, datetime):
return str(obj)
return json.JSONEncoder.default(self, obj)

View File

@@ -10,33 +10,22 @@ import unittest
from os import chdir
from pathlib import Path
from pydantic import StrictInt, model_validator
from pydantic.fields import Field
from pydantic import StrictInt
print(__name__)
print(__package__)
# print(__name__)
# print(__package__)
from src import dabmodel
from typing import Annotated, Any, Optional
from typing import Annotated, Optional
from uuid import uuid4
from pydantic import UUID4
import json
from uuid import UUID
from datetime import datetime
testdir_path = Path(__file__).parent.resolve()
chdir(testdir_path.parent.resolve())
class UUIDEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, UUID):
# if the obj is uuid, we simply return the value of uuid
return obj.hex
elif isinstance(obj, datetime):
return str(obj)
return json.JSONEncoder.default(self, obj)
class MyAppliance(dabmodel.BaseAppliance):
app_specifi_integer_arg: Annotated[StrictInt | None, dabmodel.DABField(42)]
@@ -49,7 +38,8 @@ class MyAppliance(dabmodel.BaseAppliance):
values["template_short_name"] = "my-feature-1"
values["template_long_name"] = "My feature template 1 !!"
values["template_description"] = """A very nice FEature 1"""
MyFeature : Annotated[Optional[_MyFeature],dabmodel.DABField(_MyFeature())]
MyFeature: Annotated[Optional[_MyFeature], dabmodel.DABField(_MyFeature())]
class _MyFeature2(dabmodel.BaseFeature):
@dabmodel.default_values_override
@@ -60,7 +50,8 @@ class MyAppliance(dabmodel.BaseAppliance):
values["template_short_name"] = "my-feature-2"
values["template_long_name"] = "My feature template 2 !!"
values["template_description"] = """A very nice FEature 2"""
MyFeature2 : Annotated[Optional[_MyFeature2],dabmodel.DABField(_MyFeature2())]
MyFeature2: Annotated[Optional[_MyFeature2], dabmodel.DABField(_MyFeature2())]
@dabmodel.default_values_override
@classmethod
@@ -72,8 +63,8 @@ class MyAppliance(dabmodel.BaseAppliance):
values["template_long_name"] = "My appliance template 1 !!"
values["template_description"] = """A very nice Appliance 1"""
values["ram_size"] = 1024
#cls.add_feature(cls.MyFeature())
#cls.add_feature(cls.MyFeature2())
# cls.add_feature(cls.MyFeature())
# cls.add_feature(cls.MyFeature2())
class MyAppliance2(MyAppliance):
@@ -87,20 +78,19 @@ class MyAppliance2(MyAppliance):
values["template_long_name"] = "My appliance template 2 !!"
values["template_description"] = """A very nice Appliance 2"""
values["MyFeature"] = None
#cls.del_feature(MyAppliance.MyFeature)
# cls.del_feature(MyAppliance.MyFeature)
# values["features"]["MyFeature2"].template_description = """Override feature desc"""
class MyAppliance3(dabmodel.BaseAppliance):
class _MyFeature6(MyAppliance._MyFeature):
# testtt: Annotated[MyAppliance.MyFeature, Field(MyAppliance.MyFeature())] # error case
test_integer: Annotated[int, dabmodel.DABField(200, ge=0)]
test_integer1234: Annotated[int, dabmodel.DABField(200, ge=0)]
#test_integer: int = dabmodel.DABField(200, ge=0)
# test_integer: int = dabmodel.DABField(200, ge=0)
@dabmodel.default_values_override
@classmethod
def __override_config__(cls, values):
@@ -108,9 +98,9 @@ class MyAppliance3(dabmodel.BaseAppliance):
values["template_id"] = "421d61cb-e364-46d8-9b77-ec439f1fa778"
values["template_short_name"] = "my-feature-1-bis"
values["test_integer"] = 666
MyFeature6 : Annotated[Optional[_MyFeature6],dabmodel.DABField(_MyFeature6())]
MyFeature6: Annotated[Optional[_MyFeature6], dabmodel.DABField(_MyFeature6())]
class _MyFeature7(dabmodel.BaseFeature):
# testtt: Annotated[MyAppliance.MyFeature, Field(MyAppliance.MyFeature())] # error case
test_integer_2: Annotated[int, dabmodel.DABField(759, ge=0)]
@@ -124,7 +114,8 @@ class MyAppliance3(dabmodel.BaseAppliance):
values["template_long_name"] = "My appliance template 7 !!"
values["template_description"] = """A very nice Appliance 7"""
values["test_integer_2"] = 3844
MyFeature7 : Annotated[Optional[_MyFeature7],dabmodel.DABField(_MyFeature7())]
MyFeature7: Annotated[Optional[_MyFeature7], dabmodel.DABField(_MyFeature7())]
# testtt: Annotated[MyAppliance.MyFeature, Field(MyAppliance.MyFeature())] # error case
@@ -138,17 +129,21 @@ class MyAppliance3(dabmodel.BaseAppliance):
values["template_description"] = """A very nice Appliance 3"""
values["ram_size"] = 3076
print("CREATE FEATURE")
#cls.add_feature(cls.MyFeature6())
#cls.add_feature(cls.MyFeature7())
# cls.add_feature(cls.MyFeature6())
# cls.add_feature(cls.MyFeature7())
print("!!! CONFIG Appliance 3 DONE")
class MyAppliance4(MyAppliance):
custom_uuid: Annotated[UUID4, dabmodel.DABField(uuid4(), repr=True)]
class _MyFeature8(dabmodel.BaseFeature):
# testtt: Annotated[MyAppliance.MyFeature, Field(MyAppliance.MyFeature())] # error case (nested feature)
# test_integer_10: Annotated[int, dabmodel.DABField(3189, ge=0, toto="tata")] # error case (extra field)
test_integer_10: Annotated[int, dabmodel.DABField(3189, ge=0, toto="tata")]
# testtt: Annotated[MyAppliance._MyFeature, Field(MyAppliance._MyFeature())] # error case (nested feature)
# toto: fix that
# test_integer_10_bad: Annotated[int, dabmodel.DABField(3189, ge=0, toto="tata")] # error case (extra field), /!\ this one is not working anymore :(
test_integer_10: Annotated[int, dabmodel.DABField(3189, ge=0)]
@dabmodel.default_values_override
@classmethod
@@ -160,9 +155,8 @@ class MyAppliance4(MyAppliance):
values["template_description"] = """A very nice Appliance 8"""
values["test_integer_10"] = 951753
# values["tete"] = 1 # error case (extra field in feature)
MyFeature8 : Annotated[Optional[_MyFeature8],dabmodel.DABField(_MyFeature8())]
# testtt: Annotated[MyAppliance.MyFeature, Field(MyAppliance.MyFeature())] # error case (feature not in features[] list)
MyFeature8: Annotated[Optional[_MyFeature8], dabmodel.DABField(_MyFeature8())]
@dabmodel.default_values_override
@classmethod
@@ -174,7 +168,7 @@ class MyAppliance4(MyAppliance):
values["template_description"] = """A very nice Appliance 4"""
values["ram_size"] = 954
print("CREATE FEATURE")
#cls.add_feature(cls.MyFeature8())
# cls.add_feature(cls.MyFeature8())
print("!!! CONFIG Appliance 4 DONE")
@@ -207,7 +201,7 @@ class TestModel(unittest.TestCase):
tmp_json = app3.dict()
tmp_json["MyFeature7"]["test_integer_2"] = 123
print(tmp_json)
recreated_obj = MyAppliance3.model_validate_json(json.dumps(tmp_json, cls=UUIDEncoder))
recreated_obj = MyAppliance3.model_validate_json(json.dumps(tmp_json, cls=dabmodel.DABJSONEncoder))
print(recreated_obj)
print(recreated_obj.model_dump_json(indent=1))
@@ -216,7 +210,7 @@ class TestModel(unittest.TestCase):
tmp_json["MyFeature"]["template_description"] = "blablabla"
tmp_json["MyFeature2"]["template_description"] = "blablabla2"
print(tmp_json)
recreated_obj = MyAppliance4.model_validate_json(json.dumps(tmp_json, cls=UUIDEncoder))
recreated_obj = MyAppliance4.model_validate_json(json.dumps(tmp_json, cls=dabmodel.DABJSONEncoder))
print(recreated_obj)
print(recreated_obj.model_dump_json(indent=1))
@@ -224,7 +218,7 @@ class TestModel(unittest.TestCase):
# tmp_json["non-existing"] = "test" # error case
# tmp_json["MyFeature"]["132"] = "test" # error case
recreated_obj = MyAppliance4.model_validate_json(json.dumps(tmp_json, cls=UUIDEncoder))
recreated_obj = MyAppliance4.model_validate_json(json.dumps(tmp_json, cls=dabmodel.DABJSONEncoder))
# app3.add_feature(MyAppliance.MyFeature()) # error case (add_feature not callable from instance)