diff options
| author | Ćukasz Langa <lukasz@langa.pl> | 2017-09-14 18:33:00 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-09-14 18:33:00 (GMT) |
| commit | f350a268a7071ce7d7a5bb86a9b1229782d4963b (patch) | |
| tree | 04b38394dea9be76bea00f41b488c3e3a223dd34 /Lib/test/test_typing.py | |
| parent | d393c1b227f22fb9af66040b2b367c99a4d1fa9a (diff) | |
| download | cpython-f350a268a7071ce7d7a5bb86a9b1229782d4963b.zip cpython-f350a268a7071ce7d7a5bb86a9b1229782d4963b.tar.gz cpython-f350a268a7071ce7d7a5bb86a9b1229782d4963b.tar.bz2 | |
bpo-28556: typing.get_type_hints: better globalns for classes and modules (#3582)
This makes the default behavior (without specifying `globalns` manually) more
predictable for users, finds the right globalns automatically.
Implementation for classes assumes has a `__module__` attribute and that module
is present in `sys.modules`. It does this recursively for all bases in the
MRO. For modules, the implementation just uses their `__dict__` directly.
This is backwards compatible, will just raise fewer exceptions in naive user
code.
Originally implemented and reviewed at https://github.com/python/typing/pull/470.
Diffstat (limited to 'Lib/test/test_typing.py')
| -rw-r--r-- | Lib/test/test_typing.py | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index a351be1..87d707c 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3,7 +3,7 @@ import collections import pickle import re import sys -from unittest import TestCase, main, skipUnless, SkipTest +from unittest import TestCase, main, skipUnless, SkipTest, expectedFailure from copy import copy, deepcopy from typing import Any, NoReturn @@ -30,6 +30,13 @@ except ImportError: import collections as collections_abc # Fallback for PY3.2. +try: + import mod_generics_cache +except ImportError: + # try to use the builtin one, Python 3.5+ + from test import mod_generics_cache + + class BaseTestCase(TestCase): def assertIsSubclass(self, cls, class_or_tuple, msg=None): @@ -836,10 +843,6 @@ class GenericTests(BaseTestCase): self.assertEqual(Callable[..., GenericMeta].__args__, (Ellipsis, GenericMeta)) def test_generic_hashes(self): - try: - from test import mod_generics_cache - except ImportError: # for Python 3.4 and previous versions - import mod_generics_cache class A(Generic[T]): ... @@ -1619,6 +1622,10 @@ class XRepr(NamedTuple): def __add__(self, other): return 0 +class HasForeignBaseClass(mod_generics_cache.A): + some_xrepr: 'XRepr' + other_a: 'mod_generics_cache.A' + async def g_with(am: AsyncContextManager[int]): x: int async with am as x: @@ -1659,8 +1666,18 @@ class GetTypeHintTests(BaseTestCase): self.assertEqual(gth(ann_module3), {}) @skipUnless(PY36, 'Python 3.6 required') + @expectedFailure + def test_get_type_hints_modules_forwardref(self): + # FIXME: This currently exposes a bug in typing. Cached forward references + # don't account for the case where there are multiple types of the same + # name coming from different modules in the same program. + mgc_hints = {'default_a': Optional[mod_generics_cache.A], + 'default_b': Optional[mod_generics_cache.B]} + self.assertEqual(gth(mod_generics_cache), mgc_hints) + + @skipUnless(PY36, 'Python 3.6 required') def test_get_type_hints_classes(self): - self.assertEqual(gth(ann_module.C, ann_module.__dict__), + self.assertEqual(gth(ann_module.C), # gth will find the right globalns {'y': Optional[ann_module.C]}) self.assertIsInstance(gth(ann_module.j_class), dict) self.assertEqual(gth(ann_module.M), {'123': 123, 'o': type}) @@ -1671,8 +1688,15 @@ class GetTypeHintTests(BaseTestCase): {'y': Optional[ann_module.C]}) self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) self.assertEqual(gth(ann_module.foo), {'x': int}) - self.assertEqual(gth(NoneAndForward, globals()), + self.assertEqual(gth(NoneAndForward), {'parent': NoneAndForward, 'meaning': type(None)}) + self.assertEqual(gth(HasForeignBaseClass), + {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, + 'some_b': mod_generics_cache.B}) + self.assertEqual(gth(mod_generics_cache.B), + {'my_inner_a1': mod_generics_cache.B.A, + 'my_inner_a2': mod_generics_cache.B.A, + 'my_outer_a': mod_generics_cache.A}) @skipUnless(PY36, 'Python 3.6 required') def test_respect_no_type_check(self): |
