cleaning a little bit...
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
13
src/dabmodel/tools.py
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user