From 1362092e86bf5753efb8dcb5c824607330e568fc Mon Sep 17 00:00:00 2001 From: Joseph Perez Date: Sat, 27 Nov 2021 08:01:05 +0100 Subject: [PATCH 1/2] Fix type converter handling when __init__ return is annotated --- apischema/conversions/utils.py | 18 +++++++++--------- apischema/serialization/serialized_methods.py | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apischema/conversions/utils.py b/apischema/conversions/utils.py index 505c8722..cd8d8e1d 100644 --- a/apischema/conversions/utils.py +++ b/apischema/conversions/utils.py @@ -1,4 +1,4 @@ -from inspect import Parameter, isclass, signature +from inspect import Parameter, signature from typing import Any, Callable, Dict, Generic, Optional, Tuple, Type, cast from apischema.types import AnyType @@ -32,7 +32,7 @@ def converter_types( else: parameters = list(signature(converter).parameters.values()) except ValueError: # builtin types - if target is None and isclass(converter): + if target is None and is_type(converter): target = cast(Type[Any], converter) if source is None: raise TypeError("Converter source is unknown") from None @@ -51,7 +51,7 @@ def converter_types( if source is not None and target is not None: return source, target types = get_type_hints(converter, None, namespace, include_extras=True) - if not types and isclass(converter): + if not types and is_type(converter): types = get_type_hints( converter.__new__, None, namespace, include_extras=True ) or get_type_hints( @@ -63,12 +63,12 @@ def converter_types( except KeyError: raise TypeError("converter source is unknown") from None if target is None: - try: - target = types.pop("return") - except KeyError: - if isclass(converter): - target = cast(Type, converter) - else: + if is_type(converter): + target = cast(Type, converter) + else: + try: + target = types.pop("return") + except KeyError: raise TypeError("converter target is unknown") from None return source, target diff --git a/apischema/serialization/serialized_methods.py b/apischema/serialization/serialized_methods.py index 0ba02d4d..80e5726a 100644 --- a/apischema/serialization/serialized_methods.py +++ b/apischema/serialization/serialized_methods.py @@ -1,7 +1,7 @@ from collections import defaultdict from dataclasses import dataclass from functools import wraps -from inspect import Parameter, isclass, signature +from inspect import Parameter, signature from typing import ( Any, Callable, @@ -24,7 +24,7 @@ from apischema.ordering import Ordering from apischema.schemas import Schema from apischema.types import AnyType, Undefined, UndefinedType -from apischema.typing import generic_mro, get_type_hints +from apischema.typing import generic_mro, get_type_hints, is_type from apischema.utils import ( deprecate_kwargs, get_args2, @@ -61,7 +61,7 @@ def return_type(self, return_type: AnyType) -> AnyType: def types(self, owner: AnyType = None) -> Mapping[str, AnyType]: types = get_type_hints(self.func, include_extras=True) if "return" not in types: - if isclass(self.func): + if is_type(self.func): types["return"] = self.func else: raise TypeError("Function must be typed") From 22448f29d3e443074866ccdd754a090b6859e560 Mon Sep 17 00:00:00 2001 From: Joseph Perez Date: Sat, 27 Nov 2021 14:30:40 +0100 Subject: [PATCH 2/2] Add test --- tests/integration/test_type_converter.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/integration/test_type_converter.py diff --git a/tests/integration/test_type_converter.py b/tests/integration/test_type_converter.py new file mode 100644 index 00000000..cbd1433c --- /dev/null +++ b/tests/integration/test_type_converter.py @@ -0,0 +1,12 @@ +from apischema import deserialize, deserializer + + +@deserializer +class Foo: + def __init__(self, bar: int) -> None: + self.bar = bar + + +def test_type_converter(): + foo = deserialize(Foo, 42) + assert isinstance(foo, Foo) and foo.bar == 42