def test_optional_keys(): class Q(SimpleBase): y: int class P(SimpleBase): s: Optional[Q] assert instruct.show_all_fields(P) == {"s": {"y": None}} assert instruct.keys(P, "s") == {"y"} assert instruct.keys(P) == {"s"}
def test_skip_keys_coerce(): def parse_supervisors(values): assert not isinstance(values, Person) return tuple(Person(**value) for value in values) def parse_person(value): assert not isinstance(value, Person) return Person(**value) class Person(Base): id: int name: str created_date: str class Position(Base): id: int supervisor: Tuple[Person, ...] worker: Person task_name: str __coerce__ = { "supervisor": (List[Dict[str, Union[int, str]]], parse_supervisors), "worker": (Dict[str, Union[int, str]], parse_person), } p = Position.from_json({"id": 1, "task_name": "Business Partnerships"}) p.supervisor = [{"created_date": "0", "id": 2, "name": "John"}] p.worker = {"created_date": "0", "id": 456, "name": "Sam"} FacelessPosition = Position & {"id": None, "supervisor": {"id"}, "worker": {"id"}} assert instruct.keys(FacelessPosition) == {"id", "supervisor", "worker"} OnlyPositionId = Position & "id" assert instruct.keys(OnlyPositionId) == {"id"} fp = FacelessPosition.from_json({"id": 1, "task_name": "Business Partnerships"}) fp.supervisor = [{"created_date": "0", "id": 2, "name": "John"}] assert fp.supervisor[0].name is None assert fp.supervisor[0].id == 2 fp.worker = {"created_date": "0", "id": 456, "name": "Sam"} assert fp.to_json() == {"id": 1, "supervisor": [{"id": 2}], "worker": {"id": 456}} fp.worker = Person(789, "abxdef", "0") assert fp.to_json() == {"id": 1, "supervisor": [{"id": 2}], "worker": {"id": 789}} assert isinstance(fp.worker, Person) assert isinstance(fp.worker, Person & "id") # Allow us to check the exact type of the subtraction is the same: assert instruct.public_class(fp.worker, preserve_subtraction=True) is (Person & "id") assert instruct.public_class(fp.worker, preserve_subtraction=True) is not Person
def test_subtracted_pickle(): cls = LinkedFields - {"id"} assert instruct.keys(cls) == {"name"} c = cls("Autumn") assert cls._skipped_fields == {"id": None} assert instruct._dump_skipped_fields(cls) == {"id": None} data = pickle.dumps(c) c2 = pickle.loads(data) assert c == c2 assert instruct.public_class(c2, preserve_subtraction=True) is cls
def test_skip_keys_keys(): class Person(Base): id: int name: str created_date: str NamelessPerson = Person - "name" class Position(Base): id: int supervisor: Tuple[Person, ...] worker: Person task_name: str hierarchy: Tuple[Person, NamelessPerson] __coerce__ = { "supervisor": (List[Dict[str, Union[int, str]]], Person.from_many_json), "worker": (Dict[str, Union[int, str]], Person.from_json), } FacelessPosition = Position & {"id": None, "supervisor": {"id"}, "worker": {"id"}} assert tuple(instruct.keys(FacelessPosition)) == ("id", "supervisor", "worker") assert tuple(instruct.keys(FacelessPosition, "supervisor")) == ("id",) assert tuple(instruct.keys(FacelessPosition, "worker")) == ("id",) assert instruct.keys(FacelessPosition, "hierarchy") == { Person - "name": instruct.keys(Person - "name"), Person: instruct.keys(Person), }
def test_without_keys(): class Foo(SimpleBase, json=True): bar: str f = Foo("abc") with pytest.raises(TypeError): {**f} assert f.to_json() == {"bar": "abc"} class ClobberedKeys(SimpleBase): bar: str keys: List[str] c = ClobberedKeys("a", ["foo"]) with pytest.raises(TypeError): {**c} # Show that accessing the metaclass ALWAYS # allows for getting the keys, values, etc functions instruct.keys(ClobberedKeys) & {"bar", "keys"} == {"bar", "keys"} instruct.keys(c) & {"bar", "keys"} == {"bar", "keys"}
def __repr__(self): value = {} for key in keys(type(self)): value[key] = getattr(self, key) return f"{type(self).__name__}({value!r})"