def test_can_override_field_with_annotated_classvar_but_not_with_plain_attribute( ): class A(strictus): x: int = 5 class B(A): x: ClassVar[int] = 55 assert A.x.default == 5 assert B.x == 55 assert B().x == 55 assert "x" not in get_schema(B) with pytest.raises(RuntimeError): # This is illegal, user probably doing it by mistake. # If it's a class var, then should be annotated as such. class C(A): x = 55 class D(A): x: int = 55 assert D.x.default == 55 assert D().x == 55 assert D(x=1).x == 1 class E(D): # ClassVar argument is not required x: ClassVar = 33 assert E.x == 33 assert E().x == 33 assert "x" not in get_schema(E)
def test_can_set_additional_attributes_if_allowed_in_meta(): class A(strictus): class Meta: additional_attributes = True a = A(x=11, y=22) assert a.x == 11 assert a.y == 22 assert a.to_dict() == {"x": 11, "y": 22} assert "x" not in get_schema(A) assert "x" not in get_schema(a) class B(A): pass b = B() b.x = 11 assert b.x == 11 b.y = 22 assert b.y == 22 assert b.to_dict() == {"x": 11, "y": 22} assert "x" not in get_schema(B) assert "x" not in get_schema(b)
def test_type_hints_from_base_class_act_as_field_definitions(): class Base(abc.ABC): x: int y: int = 5 class A(Base, strictus): pass assert "x" in get_schema(A) assert "y" in get_schema(A) assert get_schema(A)["y"].default == 5
def test_field_with_getter_included_in_derived_class_dict(): class A(strictus): id: int = 0 @strictus_field def path(self): return f"/items/{self.id}" class B(A): pass assert get_schema(A)["path"].dict assert A().to_dict() == {"id": 0, "path": "/items/0"} assert get_schema(B)["path"].dict assert B().to_dict() == {"id": 0, "path": "/items/0"}
def test_field_is_strictus_container(): assert not get_schema(ExampleEvent)["id"].is_strictus_container assert not get_schema(ExampleProcess)["events"].is_strictus_container assert not get_schema(ExampleEvents)["started"].is_strictus_container class Item(strictus): pass class Component(strictus): items: List[Item] items_by_name: Dict[str, Item] assert not Component.items.is_strictus assert Component.items.is_strictus_container assert not Component.items_by_name.is_strictus assert Component.items_by_name.is_strictus_container
def test_explicit_strictus_field_in_schema(): class A(strictus): x: int = strictus_field(default=55) x_schema = get_schema(A)["x"] assert x_schema.type is int assert x_schema.default == 55 assert A().x == 55 assert A(x=44).x == 44
def test_underscore_prefixed_type_hints_are_ignored(): class A(strictus): _x: int = 0 _y: str z: bool = None schema = get_schema(A) assert "_x" not in schema assert "_y" not in schema assert schema["z"].type is bool
def test_simple_schema(): ee_schema = get_schema(ExampleEvent) assert ee_schema["id"].name == "id" assert ee_schema["type"].default is None assert ee_schema["type"].has_default assert ee_schema["time"].type is str assert "path" not in ee_schema
def test_inherited_schema(): cee = get_schema(CustomExampleEvent) assert cee["id"] assert cee["type"] assert cee["type"].has_default assert cee["type"].default == "custom" assert cee["time"] assert not cee["comment"].has_default
def test_schema_meta(): class A(strictus): pass assert get_schema(A).meta == {} assert get_schema(A).additional_attributes is False class B(strictus): class Meta: custom_setting = 123 additional_attributes = True assert get_schema(B).meta == { "custom_setting": 123, "additional_attributes": True } assert get_schema(B).additional_attributes is True assert get_schema(B).custom_setting == 123 assert not hasattr(B, "Meta") assert not hasattr(B(), "Meta") class C(B): class Meta: another_setting = "ccc" assert get_schema(C).meta == { "custom_setting": 123, "additional_attributes": True, "another_setting": "ccc" } assert not hasattr(C, "Meta") assert not hasattr(C(), "Meta")
def test_parent_class_property_with_type_hint_higher_up_remains_property(): class Base: x: int class A(Base, strictus): @property def x(self): return 55 class B(A): pass class C(B): pass assert "x" not in get_schema(A) assert "x" not in get_schema(B) assert "x" not in get_schema(C) assert A().x == 55 assert B().x == 55 assert C().x == 55
def test_init_all_initialises_attributes_without_default(): class A(strictus): pass class B(strictus): class Meta: init_all = True x: int @strictus_field def y(self): return "yyy" class CBase(abc.ABC): p: int class C(CBase, strictus): class Meta: init_all = True q: B r: int = 5 s: List[int] = strictus_field(default_factory=list) assert get_schema(A).init_all is False assert get_schema(B).init_all is True assert get_schema(C).init_all is True assert B().x is None assert B().y == "yyy" assert "p" in get_schema(C) assert C().p is None assert C().q is None assert C().r == 5 assert C().s == []
def test_property_is_not_a_field(): class A(strictus): @property def x(self) -> str: return "xxx" y: str assert "x" not in get_schema(A) assert get_schema(A)["y"] assert hasattr(A, "x") assert A().x == "xxx" assert A().to_dict() == {} assert A(y=555).to_dict() == {"y": "555"} class B(A): pass assert "x" not in get_schema(B) assert get_schema(B)["y"] assert B().to_dict() == {} assert B(y=555).to_dict() == {"y": "555"}
def test_strictus_field_decorated_getters_registered_as_fields(): class A(strictus): @strictus_field def x(self) -> str: return "xxx" @strictus_field(dict=False) def y(self) -> int: return "yyy" x = get_schema(A)["x"] assert x.type is str assert x.dict is True y = get_schema(A)["y"] assert y.type is int assert y.dict is False a = A() assert a.x == "xxx" assert a.y == "yyy" assert a.to_dict() == { "x": "xxx", }
def test_dict_repr_setting_is_respected(): class A(strictus): x1: int = strictus_field(dict=False) x2: int = strictus_field(dict=False, default=22) y1: str = strictus_field(dict=True) y2: str = strictus_field(dict=True, default="yy") z: float schema = get_schema(A) assert schema["x1"].dict is False assert schema["x2"].dict is False assert schema["y1"].dict is True assert schema["y2"].dict is True assert schema["z"].dict is True assert A().to_dict() == {"y2": "yy"} assert A(x1=1).to_dict() == {"y2": "yy"} assert A(x2=222222).to_dict() == {"y2": "yy"} assert A(x1=1, x2=222222, y1="y", y2="yyyy", z=3).to_dict() == { "y1": "y", "y2": "yyyy", "z": 3.0, }
def test_nested_schema(): ep_schema = get_schema(ExampleProcess) assert ep_schema["events"].type is ExampleEvents assert ep_schema["events"].default_factory is ExampleEvents
def test_classvar_not_registered_as_field(): assert CustomExampleEvent.PREFIX == "CUSTOM" assert "PREFIX" not in get_schema(CustomExampleEvent)
def test_field_is_strictus(): assert not get_schema(ExampleEvent)["id"].is_strictus assert get_schema(ExampleProcess)["events"].is_strictus assert get_schema(ExampleEvents)["started"].is_strictus