def _register_converter(converter: Converter) -> Converter: converter.register_structure_hook( base_models.Snowflake, lambda d, _: base_models.Snowflake(int(d))) converter.register_structure_hook( permission_models.BitwisePermissionFlags, lambda d, _: permission_models.BitwisePermissionFlags(int(d)), ) def unstruct_permissions( d: permission_models.BitwisePermissionFlags) -> str: return str(d.value) converter.register_unstructure_hook( permission_models.BitwisePermissionFlags, unstruct_permissions) def struct_int_or_str(d: typing.Any, _: object) -> typing.Union[int, str]: try: return int(d) except ValueError: return str(d) converter.register_structure_hook(typing.Union[int, str], struct_int_or_str) UNKNOWN_TYPE = base_models.UNKNOWN_TYPE # TODO: use the new methods in `typing` def is_unknown(cls: type) -> bool: if getattr(cls, '__origin__') is typing.Union and UNKNOWN_TYPE in getattr( cls, '__args__'): return True return False def unknown_function(data: object, cls: typing.Type[typing.Any]) -> object: default: typing.Tuple[typing.Any] = ( ) # type: ignore[assignment] # mypy 0.930 regression args: typing.Tuple[typing.Type[typing.Any]] = getattr( cls, '__args__', default) if len(args) == 2: return converter.structure(data, [n for n in args if n != UNKNOWN_TYPE][0]) else: type: typing.Any = typing.Union[tuple(n for n in args if n != UNKNOWN_TYPE)] return converter.structure(data, type) converter.register_structure_hook_func(is_unknown, unknown_function) models.setup_cattrs(converter) return converter
def test_structure_hook_func(): """ testing the hook_func method """ converter = Converter() def can_handle(cls): return cls.__name__.startswith("F") def handle(obj, cls): return "hi" class Foo(object): pass class Bar(object): pass converter.register_structure_hook_func(can_handle, handle) assert converter.structure(10, Foo) == "hi" with raises(ValueError): converter.structure(10, Bar)