8000 bpo-45283: Run `_type_check` on `get_type_hints()` by sobolevn · Pull Request #28563 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-45283: Run _type_check on get_type_hints() #28563

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement requested changes
  • Loading branch information
sobolevn committed Oct 21, 2021
commit c3752e224162c8f509ccd5c5b93b34a90f23c02a
38 changes: 19 additions & 19 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3341,25 +3341,6 @@ def final_var_return_type2() -> Final[int]: pass
with self.assertRaises(TypeError):
get_type_hints(func)

def test_forward_ref_and_final(self):
# https://bugs.python.org/issue45166
hints = get_type_hints(ann_module5)
self.assertEqual(hints, {'name': Final[str]})

hints = get_type_hints(ann_module5.MyClass)
self.assertEqual(hints, {'value': Final})

def test_top_level_class_var(self):
# https://bugs.python.org/issue45166
# https://bugs.python.org/issue45283
for obj in [ann_module6, ann_module7]:
with self.subTest(obj=obj):
with self.assertRaisesRegex(
TypeError,
r'typing.ClassVar\[int\] is not valid as type argument',
):
get_type_hints(obj)


class GetUtilitiesTestCase(TestCase):
def test_get_origin(self):
Expand Down Expand Up @@ -3423,6 +3404,25 @@ class C(Generic[T]): pass
(Concatenate[int, P], int))
self.assertEqual(get_args(list | str), (list, str))

def test_forward_ref_and_final(self):
# https://bugs.python.org/issue45166
hints = get_type_hints(ann_module5)
self.assertEqual(hints, {'name': Final[str]})

hints = get_type_hints(ann_module5.MyClass)
self.assertEqual(hints, {'value': Final})

def test_top_level_class_var(self):
# https://bugs.python.org/issue45166
# https://bugs.python.org/issue45283
for obj in [ann_module6, ann_module7]:
with self.subTest(obj=obj):
with self.assertRaisesRegex(
TypeError,
r'typing.ClassVar\[int\] is not valid as type argument',
):
get_type_hints(obj)


class CollectionsAbcTests(BaseTestCase):

Expand Down
13 changes: 7 additions & 6 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,12 @@ def _type_check(arg, msg, is_argument=True, module=None, *, is_class=False):
invalid_generic_forms += (Final,)

arg = _type_convert(arg, module=module)
if (
(isinstance(arg, _GenericAlias) and
arg.__origin__ in invalid_generic_forms) or
(is_argument and arg == Final) # Raw `Final` is not `_GenericAlias`
):
is_invalid_generic = (
isinstance(arg, _GenericAlias)
and arg.__origin__ in invalid_generic_forms
)
is_invalid_bare_final = is_argument and arg is Final
if is_invalid_generic or is_invalid_bare_final:
raise TypeError(f"{arg} is not valid as type argument")
if arg in (Any, NoReturn, Final):
return arg
Expand Down Expand Up @@ -1784,7 +1785,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
if getattr(obj, '__no_type_check__', None):
return {}

error_msg = "get_type_hint() got invalid type annotation."
error_msg = "get_type_hints() got invalid type annotation."

# Classes require a special treatment.
if isi 8009 nstance(obj, type):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Runs ``_type_check()`` on all ``get_type_hints()`` calls. This catches cases
Run ``_type_check()`` on all ``get_type_hints()`` calls. This catches cases
when any invalid annotations are used.
0