From 4441980fe644b0334575e5a58cf294f2c3d76679 Mon Sep 17 00:00:00 2001 From: Oxan van Leeuwen Date: Thu, 19 Oct 2023 21:22:44 +0200 Subject: [PATCH] Add tests for type hint resolution --- rest_framework_dataclasses/typing_utils.py | 5 +++-- tests/test_typing_utils.py | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/rest_framework_dataclasses/typing_utils.py b/rest_framework_dataclasses/typing_utils.py index bb42526..f55bf51 100644 --- a/rest_framework_dataclasses/typing_utils.py +++ b/rest_framework_dataclasses/typing_utils.py @@ -56,8 +56,9 @@ def get_resolved_type_hints(tp: type) -> typing.Dict[str, type]: Resolving the type hints means converting any stringified type hint into an actual type object. These can come from either forward references (PEP 484), or postponed evaluation (PEP 563). """ - # typing.get_type_hints() does the heavy lifting for us, except when using PEP 585 generic types that contain a - # stringified type hint (see https://bugs.python.org/issue41370) + # typing.get_type_hints() does the heavy lifting for us, except: + # - when using PEP 585 generic types that contain a stringified type hint, on Python 3.9 and 3.10. See + # https://bugs.python.org/issue41370 def _resolve_type(context_type: type, resolve_type: typing.Union[str, type]) -> type: if isinstance(resolve_type, str): globalsns = sys.modules[context_type.__module__].__dict__ diff --git a/tests/test_typing_utils.py b/tests/test_typing_utils.py index e7669bf..7a83453 100644 --- a/tests/test_typing_utils.py +++ b/tests/test_typing_utils.py @@ -11,6 +11,25 @@ def assertAnyTypeEquivalent(self, tp: type): # 3.7 and 3.8). It's essentially the same, and we strip the typevar before usage anyway. self.assertTrue(tp is typing.Any or (isinstance(tp, typing.TypeVar) and len(tp.__constraints__) == 0)) + def test_resolve(self): + class Hinted: + a: str + b: 'str' + + hints = typing_utils.get_resolved_type_hints(Hinted) + self.assertEqual(hints['a'], str) + self.assertEqual(hints['b'], str) + + @unittest.skipIf(sys.version_info < (3, 9, 0), 'Python 3.9 required') + def test_resolve_pep585(self): + class Hinted: + a: list[str] + b: list['str'] + + hints = typing_utils.get_resolved_type_hints(Hinted) + self.assertEqual(hints['a'], types_module.GenericAlias(list, (str, ))) + self.assertEqual(hints['b'], types_module.GenericAlias(list, (str, ))) + def test_iterable(self): self.assertTrue(typing_utils.is_iterable_type(typing.Iterable[str])) self.assertTrue(typing_utils.is_iterable_type(typing.Collection[str]))