# dabmodel (c) by chacha # # dabmodel is licensed under a # Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Unported License. # # You should have received a copy of the license along with this # work. If not, see . import unittest from typing import Annotated, Union import sys import subprocess from os import chdir, environ from pathlib import Path print(__name__) print(__package__) from src import dabmodel as dm testdir_path = Path(__file__).parent.resolve() chdir(testdir_path.parent.resolve()) class ElementTest(unittest.TestCase): def setUp(self): print("\n->", unittest.TestCase.id(self)) def test_element_simple(self): class E(dm.Element): ivalue: int = 43 strvalue: str = "test" fvalue: float = 1.4322 ar_int: list[int] = [1, 54, 65] ar_int2: list[int] = [1, 54, 65] class A(dm.Appliance): elem: E = E(ivalue=45, strvalue="coucou", ar_int=[5, 7]) a = A() self.assertIsInstance(a.elem, E) self.assertIsInstance(a.elem.ivalue, int) self.assertEqual(a.elem.ivalue, 45) self.assertIsInstance(a.elem.strvalue, str) self.assertEqual(a.elem.strvalue, "coucou") self.assertIsInstance(a.elem.fvalue, float) self.assertEqual(a.elem.fvalue, 1.4322) self.assertIsInstance(a.elem.ar_int, tuple) self.assertEqual(a.elem.ar_int, (5, 7)) self.assertIsInstance(a.elem.ar_int2, tuple) self.assertEqual(a.elem.ar_int2, (1, 54, 65)) def test_element_in_container(self): class E(dm.Element): ivalue: int = 43 strvalue: str = "test" fvalue: float = 1.4322 ar_int: list[int] = [1, 54, 65] ar_int2: list[int] = [1, 54, 65] class A(dm.Appliance): elems: list[E] = [ E(ivalue=45, strvalue="coucou", ar_int=[5, 7]), E(ivalue=46, strvalue="coucou2", ar_int=[50, 7]), ] a = A() self.assertIsInstance(a.elems, tuple) self.assertEqual(len(a.elems), 2) self.assertIsInstance(a.elems[0], E) self.assertIsInstance(a.elems[0].ivalue, int) self.assertEqual(a.elems[0].ivalue, 45) self.assertIsInstance(a.elems[0].strvalue, str) self.assertEqual(a.elems[0].strvalue, "coucou") self.assertIsInstance(a.elems[0].fvalue, float) self.assertEqual(a.elems[0].fvalue, 1.4322) self.assertIsInstance(a.elems[0].ar_int, tuple) self.assertEqual(a.elems[0].ar_int, (5, 7)) self.assertIsInstance(a.elems[0].ar_int2, tuple) self.assertEqual(a.elems[0].ar_int2, (1, 54, 65)) self.assertIsInstance(a.elems[1], E) self.assertIsInstance(a.elems[1].ivalue, int) self.assertEqual(a.elems[1].ivalue, 46) self.assertIsInstance(a.elems[1].strvalue, str) self.assertEqual(a.elems[1].strvalue, "coucou2") self.assertIsInstance(a.elems[1].fvalue, float) self.assertEqual(a.elems[1].fvalue, 1.4322) self.assertIsInstance(a.elems[1].ar_int, tuple) self.assertEqual(a.elems[1].ar_int, (50, 7)) self.assertIsInstance(a.elems[1].ar_int2, tuple) self.assertEqual(a.elems[1].ar_int2, (1, 54, 65)) def test_class_frozen(self): class E(dm.Element): ivalue: int = 43 strvalue: str = "test" fvalue: float = 1.4322 ar_int: list[int] = [1, 54, 65] with self.assertRaises(dm.ReadOnlyField): E.ivalue = 3 with self.assertRaises(dm.ReadOnlyField): E.strvalue = "toto" with self.assertRaises(dm.ReadOnlyField): E.fvalue = 3.14 with self.assertRaises(AttributeError): E.ar_int.append(5) def test_instance_frozen(self): class E(dm.Element): ivalue: int = 43 strvalue: str = "test" fvalue: float = 1.4322 ar_int: list[int] = [1, 54, 65] e = E() with self.assertRaises(dm.ReadOnlyField): e.ivalue = 3 with self.assertRaises(dm.ReadOnlyField): e.strvalue = "toto" with self.assertRaises(dm.ReadOnlyField): e.fvalue = 3.14 with self.assertRaises(AttributeError): e.ar_int.append(5) def test_composition_frozen(self): class E(dm.Element): ivalue: int = 43 strvalue: str = "test" fvalue: float = 1.4322 ar_int: list[int] = [1, 54, 65] ar_int2: list[int] = [1, 54, 65] class A(dm.Appliance): elems: list[E] = [ E(ivalue=45, strvalue="coucou", ar_int=[5, 7]), E(ivalue=46, strvalue="coucou2", ar_int=[50, 7]), ] elem: E = E() a = A() with self.assertRaises(AttributeError): a.elems.add(E()) with self.assertRaises(dm.ReadOnlyField): a.elem.ivalue = 1 with self.assertRaises(dm.ReadOnlyField): a.elems[0].ivalue = 1 def test_element_inheritance(self): class E(dm.Element): ivalue: int = 43 strvalue: str = "test" fvalue: float = 1.4322 ar_int: list[int] = [1, 54, 65] ar_int2: list[int] = [1, 54, 65] class E2(E): ivalue2: int = 43 class A(dm.Appliance): elems: list[E] = [ E(ivalue=45, strvalue="coucou", ar_int=[5, 7]), E2(ivalue=46, strvalue="coucou2", ar_int=[50, 7], ivalue2=32), ] elem: E = E() elem2: E2 = E2(ivalue=7, ivalue2=33) a = A() self.assertIsInstance(a.elems, tuple) self.assertEqual(len(a.elems), 2) self.assertIsInstance(a.elems[0], E) self.assertIsInstance(a.elems[0].ivalue, int) self.assertEqual(a.elems[0].ivalue, 45) self.assertIsInstance(a.elems[0].strvalue, str) self.assertEqual(a.elems[0].strvalue, "coucou") self.assertIsInstance(a.elems[0].fvalue, float) self.assertEqual(a.elems[0].fvalue, 1.4322) self.assertIsInstance(a.elems[0].ar_int, tuple) self.assertEqual(a.elems[0].ar_int, (5, 7)) self.assertIsInstance(a.elems[0].ar_int2, tuple) self.assertEqual(a.elems[0].ar_int2, (1, 54, 65)) self.assertIsInstance(a.elems[1], E2) self.assertIsInstance(a.elems[1].ivalue, int) self.assertEqual(a.elems[1].ivalue, 46) self.assertIsInstance(a.elems[1].ivalue2, int) self.assertEqual(a.elems[1].ivalue2, 32) self.assertIsInstance(a.elems[1].strvalue, str) self.assertEqual(a.elems[1].strvalue, "coucou2") self.assertIsInstance(a.elems[1].fvalue, float) self.assertEqual(a.elems[1].fvalue, 1.4322) self.assertIsInstance(a.elems[1].ar_int, tuple) self.assertEqual(a.elems[1].ar_int, (50, 7)) self.assertIsInstance(a.elems[1].ar_int2, tuple) self.assertEqual(a.elems[1].ar_int2, (1, 54, 65)) self.assertIsInstance(a.elem, E) self.assertIsInstance(a.elem.ivalue, int) self.assertEqual(a.elem.ivalue, 43) self.assertIsInstance(a.elem.strvalue, str) self.assertEqual(a.elem.strvalue, "test") self.assertIsInstance(a.elem.fvalue, float) self.assertEqual(a.elem.fvalue, 1.4322) self.assertIsInstance(a.elem.ar_int, tuple) self.assertEqual(a.elem.ar_int, (1, 54, 65)) self.assertIsInstance(a.elem.ar_int2, tuple) self.assertEqual(a.elem.ar_int2, (1, 54, 65)) self.assertIsInstance(a.elem2, E2) self.assertIsInstance(a.elem2.ivalue, int) self.assertEqual(a.elem2.ivalue, 7) self.assertIsInstance(a.elem2.ivalue2, int) self.assertEqual(a.elem2.ivalue2, 33) self.assertIsInstance(a.elem2.strvalue, str) self.assertEqual(a.elem2.strvalue, "test") self.assertIsInstance(a.elem2.fvalue, float) self.assertEqual(a.elem2.fvalue, 1.4322) self.assertIsInstance(a.elem2.ar_int, tuple) self.assertEqual(a.elem2.ar_int, (1, 54, 65)) self.assertIsInstance(a.elem2.ar_int2, tuple) self.assertEqual(a.elem2.ar_int2, (1, 54, 65)) def test_element_initializer(self): class E(dm.Element): ivalue: int = 43 strvalue: str = "test" fvalue: float = 1.4322 ar_int: list[int] = [1, 54, 65] ar_int2: list[int] = [1, 54, 65] class A(dm.Appliance): elem: E = E(ivalue=45, strvalue="coucou", ar_int=[5, 7]) @classmethod def __initializer(self): self.elem = E(ivalue=12, strvalue="coucou", ar_int=[5, 7]) a = A() self.assertIsInstance(a.elem, E) self.assertIsInstance(a.elem.ivalue, int) self.assertEqual(a.elem.ivalue, 12) self.assertIsInstance(a.elem.strvalue, str) self.assertEqual(a.elem.strvalue, "coucou") self.assertIsInstance(a.elem.fvalue, float) self.assertEqual(a.elem.fvalue, 1.4322) self.assertIsInstance(a.elem.ar_int, tuple) self.assertEqual(a.elem.ar_int, (5, 7)) self.assertIsInstance(a.elem.ar_int2, tuple) self.assertEqual(a.elem.ar_int2, (1, 54, 65)) def test_element_in_container_initializer(self): class E(dm.Element): ivalue: int = 43 strvalue: str = "test" fvalue: float = 1.4322 ar_int: list[int] = [1, 54, 65] ar_int2: list[int] = [1, 54, 65] class A(dm.Appliance): elems: list[E] = [E(ivalue=45, strvalue="coucou", ar_int=[5, 7])] class B(A): @classmethod def __initializer(cls): cls.elems.append(E(ivalue=46, strvalue="coucou2", ar_int=[50, 7])) a = A() b = B() self.assertIsInstance(a.elems, tuple) self.assertEqual(len(a.elems), 1) self.assertIsInstance(a.elems[0], E) self.assertIsInstance(a.elems[0].ivalue, int) self.assertEqual(a.elems[0].ivalue, 45) self.assertIsInstance(a.elems[0].strvalue, str) self.assertEqual(a.elems[0].strvalue, "coucou") self.assertIsInstance(a.elems[0].fvalue, float) self.assertEqual(a.elems[0].fvalue, 1.4322) self.assertIsInstance(a.elems[0].ar_int, tuple) self.assertEqual(a.elems[0].ar_int, (5, 7)) self.assertIsInstance(a.elems[0].ar_int2, tuple) self.assertEqual(a.elems[0].ar_int2, (1, 54, 65)) self.assertIsInstance(b.elems, tuple) self.assertEqual(len(b.elems), 2) self.assertIsInstance(b.elems[0], E) self.assertIsInstance(b.elems[0].ivalue, int) self.assertEqual(b.elems[0].ivalue, 45) self.assertIsInstance(b.elems[0].strvalue, str) self.assertEqual(b.elems[0].strvalue, "coucou") self.assertIsInstance(b.elems[0].fvalue, float) self.assertEqual(b.elems[0].fvalue, 1.4322) self.assertIsInstance(b.elems[0].ar_int, tuple) self.assertEqual(b.elems[0].ar_int, (5, 7)) self.assertIsInstance(b.elems[0].ar_int2, tuple) self.assertEqual(b.elems[0].ar_int2, (1, 54, 65)) self.assertIsInstance(b.elems[1], E) self.assertIsInstance(b.elems[1].ivalue, int) self.assertEqual(b.elems[1].ivalue, 46) self.assertIsInstance(b.elems[1].strvalue, str) self.assertEqual(b.elems[1].strvalue, "coucou2") self.assertIsInstance(b.elems[1].fvalue, float) self.assertEqual(b.elems[1].fvalue, 1.4322) self.assertIsInstance(b.elems[1].ar_int, tuple) self.assertEqual(b.elems[1].ar_int, (50, 7)) self.assertIsInstance(b.elems[1].ar_int2, tuple) self.assertEqual(b.elems[1].ar_int2, (1, 54, 65)) def test_method(self): class E(dm.Element): ivalue: int = 43 def get_increment(self) -> int: return self.ivalue + 1 def increment(self) -> int: return type(self)(ivalue=self.ivalue + 1) class A(dm.Appliance): elem: E = E(ivalue=45) a = A() self.assertIsInstance(a.elem, E) self.assertEqual(a.elem.ivalue, 45) self.assertEqual(a.elem.get_increment(), 46) class B(A): @classmethod def __initializer(cls): cls.elem = cls.elem.increment() b = B() self.assertEqual(b.elem.ivalue, 46) self.assertEqual(b.elem.get_increment(), 47) def test_initializer_appliance_function_forbidden(self): def test_fun() -> int: return 12 class E(dm.Element): ivalue: int = 43 with self.assertRaises(dm.FunctionForbidden): class B(dm.Element): elem: E = E() @classmethod def __initializer(cls): cls.elem.ivalue = test_fun() with self.assertRaises(dm.FunctionForbidden): class C(dm.Element): elem: E = E() @classmethod def __initializer(cls): cls.elem = E(ivalue=test_fun()) def test_mutable_class2_newelement_fails(self): class E(dm.Element, options=(dm.ClassMutable)): ivalue: int = 43 with self.assertRaises(dm.NonExistingField): E.test = 123 e = E() with self.assertRaises(dm.NonExistingField): e.test = 123 def test_mutable_class_freeze(self): class E(dm.Element, options=(dm.ClassMutable)): ivalue: int = 43 E.ivalue = 12 self.assertEqual(E.ivalue, 12) E.freeze_class() self.assertEqual(E.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): E.ivalue = 13 self.assertEqual(E.ivalue, 12) e = E() self.assertEqual(e.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): e.ivalue = 14 self.assertEqual(e.ivalue, 12) def test_mutable_object_freeze(self): class E(dm.Element, options=(dm.ObjectMutable)): ivalue: int = 43 self.assertEqual(E.ivalue, 43) with self.assertRaises(dm.ReadOnlyField): E.ivalue = 13 self.assertEqual(E.ivalue, 43) e = E() self.assertEqual(e.ivalue, 43) e.ivalue = 14 self.assertEqual(e.ivalue, 14) e.freeze() self.assertEqual(e.ivalue, 14) with self.assertRaises(dm.ReadOnlyField): e.ivalue = 15 self.assertEqual(e.ivalue, 14) def test_mutable_object_and_class_freeze(self): class E(dm.Element, options=(dm.ObjectMutable, dm.ClassMutable)): ivalue: int = 43 self.assertEqual(E.ivalue, 43) E.ivalue = 13 self.assertEqual(E.ivalue, 13) e = E() self.assertEqual(e.ivalue, 13) e.ivalue = 14 self.assertEqual(e.ivalue, 14) e.freeze() self.assertEqual(e.ivalue, 14) with self.assertRaises(dm.ReadOnlyField): e.ivalue = 15 self.assertEqual(e.ivalue, 14) def test_mutable_object_and_class_freeze_2(self): class E(dm.Element, options=(dm.ObjectMutable, dm.ClassMutable)): ivalue: int = 43 self.assertFalse(E.__lam_schema__["ivalue"].is_frozen()) E.freeze_class() self.assertTrue(E.__lam_schema__["ivalue"].is_frozen()) e = E() self.assertFalse(e.__lam_schema__["ivalue"].is_frozen()) e.freeze() self.assertTrue(e.__lam_schema__["ivalue"].is_frozen()) def test_mutable_class_freeze_container(self): class E(dm.Element, options=(dm.ClassMutable)): ar_ivalue: list[int] = [43] E.ar_ivalue.append(12) self.assertEqual(E.ar_ivalue, [43, 12]) E.freeze_class() self.assertEqual(E.ar_ivalue, (43, 12)) with self.assertRaises(AttributeError): E.ar_ivalue.append(52) self.assertEqual(E.ar_ivalue, (43, 12)) e = E() self.assertEqual(e.ar_ivalue, (43, 12)) with self.assertRaises(AttributeError): e.ar_ivalue.append(52) self.assertEqual(e.ar_ivalue, (43, 12)) def test_mutable_object_freeze_container(self): class E(dm.Element, options=(dm.ObjectMutable)): ar_ivalue: list[int] = [43, 54] self.assertEqual(E.ar_ivalue, (43, 54)) with self.assertRaises(AttributeError): E.ar_ivalue.append(13) self.assertEqual(E.ar_ivalue, (43, 54)) e = E() self.assertEqual(e.ar_ivalue, [43, 54]) e.ar_ivalue.append(32) self.assertEqual(e.ar_ivalue, [43, 54, 32]) e.freeze() self.assertEqual(e.ar_ivalue, (43, 54, 32)) with self.assertRaises(AttributeError): e.ar_ivalue.append(12) self.assertEqual(e.ar_ivalue, (43, 54, 32)) def test_mutable_object_and_class_freeze_container(self): class E(dm.Element, options=(dm.ObjectMutable, dm.ClassMutable)): ar_ivalue: list[int] = [43, 54] self.assertEqual(E.ar_ivalue, [43, 54]) E.ar_ivalue.append(13) self.assertEqual(E.ar_ivalue, [43, 54, 13]) e = E() self.assertEqual(e.ar_ivalue, [43, 54, 13]) e.ar_ivalue.append(14) self.assertEqual(e.ar_ivalue, [43, 54, 13, 14]) e.freeze() self.assertEqual(e.ar_ivalue, (43, 54, 13, 14)) with self.assertRaises(AttributeError): e.ar_ivalue.append(15) self.assertEqual(e.ar_ivalue, (43, 54, 13, 14)) def test_mutable_class_freeze_inheritance(self): class E(dm.Element, options=(dm.ClassMutable)): ivalue: int = 12 class E2(E): pass self.assertEqual(E2.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): E2.ivalue = 13 self.assertEqual(E2.ivalue, 12) e = E2() self.assertEqual(e.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): e.ivalue = 14 self.assertEqual(e.ivalue, 12) def test_mutable_object_freeze_inheritance(self): class E(dm.Element, options=(dm.ObjectMutable)): ivalue: int = 12 class E2(E): pass self.assertEqual(E2.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): E2.ivalue = 13 self.assertEqual(E2.ivalue, 12) e = E2() self.assertEqual(e.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): e.ivalue = 14 self.assertEqual(e.ivalue, 12) def test_mutable_object_and_class_freeze_inheritance(self): class E(dm.Element, options=(dm.ObjectMutable, dm.ClassMutable)): ivalue: int = 12 class E2(E): pass self.assertEqual(E2.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): E2.ivalue = 13 self.assertEqual(E2.ivalue, 12) e = E2() self.assertEqual(e.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): e.ivalue = 14 self.assertEqual(e.ivalue, 12) def test_mutable_object_and_class_freeze_inheritance_noleak(self): class E(dm.Element, options=(dm.ObjectMutable, dm.ClassMutable)): ivalue: int = 12 class E2(E): pass self.assertEqual(E2.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): E2.ivalue = 13 self.assertEqual(E2.ivalue, 12) e2 = E2() self.assertEqual(e2.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): e2.ivalue = 14 self.assertEqual(e2.ivalue, 12) # no Leak self.assertEqual(E.ivalue, 12) E.ivalue = 13 self.assertEqual(E.ivalue, 13) e = E() self.assertEqual(e.ivalue, 13) e.ivalue = 14 self.assertEqual(e.ivalue, 14) e.freeze() self.assertEqual(e.ivalue, 14) with self.assertRaises(dm.ReadOnlyField): e.ivalue = 15 self.assertEqual(e.ivalue, 14) # no Leak 2 self.assertEqual(E2.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): E2.ivalue = 13 self.assertEqual(E2.ivalue, 12) e2 = E2() self.assertEqual(e2.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): e2.ivalue = 14 self.assertEqual(e2.ivalue, 12) def test_mutable_class_freeze_nested_element(self): class NElem(dm.Element): ivalue: int = 43 class E(dm.Element, options=(dm.ClassMutable)): e: NElem = NElem() E.e.ivalue = 12 self.assertEqual(E.e.ivalue, 12) E.freeze_class() self.assertEqual(E.e.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): E.e.ivalue = 13 self.assertEqual(E.e.ivalue, 12) e = E() self.assertEqual(e.e.ivalue, 12) with self.assertRaises(dm.ReadOnlyField): e.e.ivalue = 14 self.assertEqual(e.e.ivalue, 12) def test_mutable_object_freeze_nested_element(self): class NElem(dm.Element): ivalue: int = 43 class E(dm.Element, options=(dm.ObjectMutable)): e: NElem = NElem() self.assertEqual(E.e.ivalue, 43) with self.assertRaises(dm.ReadOnlyField): E.e.ivalue = 13 self.assertEqual(E.e.ivalue, 43) e = E() self.assertEqual(e.e.ivalue, 43) e.e.ivalue = 14 self.assertEqual(e.e.ivalue, 14) e.freeze() self.assertEqual(e.e.ivalue, 14) with self.assertRaises(dm.ReadOnlyField): e.e.ivalue = 15 self.assertEqual(e.e.ivalue, 14) def test_mutable_object_and_class_freeze_nested_element(self): class NElem(dm.Element): ivalue: int = 43 class E(dm.Element, options=(dm.ObjectMutable, dm.ClassMutable)): e: NElem = NElem() self.assertEqual(E.e.ivalue, 43) E.e.ivalue = 13 self.assertEqual(E.e.ivalue, 13) e = E() self.assertEqual(e.e.ivalue, 13) e.e.ivalue = 14 self.assertEqual(e.e.ivalue, 14) e.e.freeze() self.assertEqual(e.e.ivalue, 14) with self.assertRaises(dm.ReadOnlyField): e.e.ivalue = 15 self.assertEqual(e.e.ivalue, 14) def test_element_clone(self): class Elem(dm.Element): ivalue: int = 43 self.assertTrue(Elem.frozen_cls) self.assertFalse(Elem.mutable_obj) e = Elem() print(e) new_obj1 = e.clone_as_mutable_variant() self.assertFalse(new_obj1.frozen_cls) self.assertTrue(new_obj1.mutable_obj) self.assertIsInstance(new_obj1, Elem) self.assertEqual(new_obj1.ivalue, 43) new_obj1.ivalue = 55 self.assertEqual(new_obj1.ivalue, 55) new_obj2 = e.clone_as_mutable_variant() self.assertFalse(new_obj2.frozen_cls) self.assertTrue(new_obj2.mutable_obj) self.assertNotEqual(new_obj1, new_obj2) self.assertEqual(type(new_obj1), type(new_obj2)) self.assertEqual(new_obj2.ivalue, 43) new_obj2.ivalue = 56 self.assertEqual(new_obj2.ivalue, 56) new_obj3 = e.clone_as_mutable_variant() self.assertFalse(new_obj3.frozen_cls) self.assertTrue(new_obj3.mutable_obj) self.assertNotEqual(new_obj1, new_obj3) self.assertNotEqual(new_obj2, new_obj3) self.assertEqual(type(new_obj1), type(new_obj3)) self.assertEqual(type(new_obj2), type(new_obj3)) self.assertEqual(new_obj3.ivalue, 43) new_obj3.ivalue = 57 self.assertEqual(new_obj3.ivalue, 57) self.assertEqual(e.ivalue, 43) with self.assertRaises(dm.ReadOnlyField): e.ivalue = 15 self.assertEqual(e.ivalue, 43) self.assertEqual(new_obj1.ivalue, 55) new_obj1.freeze() self.assertEqual(new_obj1.ivalue, 55) with self.assertRaises(dm.ReadOnlyField): new_obj1.ivalue = 15 self.assertEqual(new_obj1.ivalue, 55) self.assertEqual(new_obj2.ivalue, 56) self.assertEqual(new_obj3.ivalue, 57) new_obj2.ivalue = 76 self.assertEqual(new_obj2.ivalue, 76) self.assertEqual(new_obj3.ivalue, 57) self.assertEqual(new_obj1.ivalue, 55) new_obj2.freeze() self.assertEqual(new_obj2.ivalue, 76) with self.assertRaises(dm.ReadOnlyField): new_obj2.ivalue = 15 self.assertEqual(new_obj2.ivalue, 76) self.assertTrue(e.frozen) self.assertTrue(new_obj1.frozen) self.assertTrue(new_obj2.frozen) self.assertFalse(new_obj3.frozen) def test_element_clone_inheritance(self): class ElemA(dm.Element): ivalue: int = 43 class ElemB(ElemA): ivalue = 18 elemA = ElemA() elemB = ElemB() _elemA = elemA.clone_as_mutable_variant() _elemB = elemB.clone_as_mutable_variant() self.assertIsInstance(elemB, type(elemA)) self.assertIsInstance(_elemA, type(elemA)) self.assertIsInstance(_elemB, type(elemB)) self.assertIsInstance(_elemB, type(_elemA)) def test_element_clone_inheritance_nested(self): class ElemAInner(dm.Element): fvalue: float = 0.123 class ElemA(dm.Element): ivalue: int = 43 el1: ElemAInner = ElemAInner() class ElemBInner(ElemAInner): fvalue = 0.9 class ElemB(ElemA): ivalue = 18 el1 = ElemAInner(fvalue=6.54) el2: ElemBInner = ElemBInner() self.assertIsInstance(ElemA.el1, ElemAInner) self.assertIsInstance(ElemB.el1, ElemAInner) self.assertIsInstance(ElemB.el2, ElemAInner) self.assertIsInstance(ElemB.el2, ElemBInner) self.assertNotIsInstance(ElemB.el1, ElemBInner) elemA = ElemA() elemB = ElemB() _elemA = elemA.clone_as_mutable_variant() _elemB = elemB.clone_as_mutable_variant() self.assertIsInstance(elemB, type(elemA)) self.assertIsInstance(_elemA, type(elemA)) self.assertIsInstance(_elemB, type(elemB)) self.assertIsInstance(_elemB, type(_elemA)) self.assertIsInstance(_elemB.el1, type(_elemA.el1)) self.assertIsInstance(_elemA.el1, type(elemA.el1)) self.assertIsInstance(_elemB.el1, type(elemB.el1)) self.assertIsInstance(_elemB.el1, type(_elemA.el1)) self.assertIsInstance(_elemB.el2, type(_elemA.el1)) self.assertIsInstance(_elemB.el2, type(elemB.el1)) self.assertIsInstance(_elemB.el2, type(_elemA.el1)) def test_element_mutable_invalid_instance_override_container(self): class Elem(dm.Element, options=(dm.ClassMutable, dm.ObjectMutable)): val: list[int] = [] with self.assertRaises(dm.InvalidFieldValue): Elem(val=["test"]) def test_element_mutable_invalid_instance_override_container_nested(self): class ElemInner(dm.Element, options=(dm.ClassMutable, dm.ObjectMutable)): val: list[int] = [] class ElemOuter(dm.Element, options=(dm.ClassMutable, dm.ObjectMutable)): inner: ElemInner = ElemInner() # with self.assertRaises(dm.InvalidFieldValue): elem = ElemOuter(inner={"val": [1, 2, 3]}) self.assertEqual(elem.inner.val, [1, 2, 3]) def test_class_protocol(self): self.assertIsInstance(dm.base_element.BaseElement, dm.interfaces.FreezableElement) def test_wrong_annotated(self): with self.assertRaises(dm.UnsupportedFieldType): class Elem(dm.Appliance): StrVar: list[Annotated[str, dm.LAMFieldInfo(doc="foo1")]] = ["default value"] def test_wrong_annotation_union(self): with self.assertRaises(dm.UnsupportedFieldType): class Elem(dm.Appliance): StrVar: str | int = "test" with self.assertRaises(dm.UnsupportedFieldType): class Elem(dm.Appliance): StrVar: list[str | int] = "test" with self.assertRaises(dm.UnsupportedFieldType): class Elem(dm.Appliance): StrVar: list[None | int] = "test" def test_annotation_union(self): class Elem(dm.Appliance): strvar1: str | None = "test" strvar1: str | None = None ivar1: Union[int, None] = 12 ivar2: Union[int, None] = None # ---------- main ---------- if __name__ == "__main__": unittest.main()