Skip to content

Commit 9378f79

Browse files
author
Lukasz Langa
committed
get_type_hints(): find the right globalns for classes
This makes the default behavior (without specifying `globalns` manually) more predictable for users. Implementation assumes the class has a `__module__` attribute and that module is present in `sys.modules`. This is backwards compatible, will just raise fewer exceptions in naive user code.
1 parent cc89ce8 commit 9378f79

2 files changed

Lines changed: 8 additions & 4 deletions

File tree

‎src/test_typing.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1660,7 +1660,7 @@ def test_get_type_hints_modules(self):
16601660

16611661
@skipUnless(PY36, 'Python 3.6 required')
16621662
def test_get_type_hints_classes(self):
1663-
self.assertEqual(gth(ann_module.C, ann_module.__dict__),
1663+
self.assertEqual(gth(ann_module.C), # gth will find the right globalns
16641664
{'y': Optional[ann_module.C]})
16651665
self.assertIsInstance(gth(ann_module.j_class), dict)
16661666
self.assertEqual(gth(ann_module.M), {'123': 123, 'o': type})

‎src/typing.py‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,8 +1481,9 @@ def get_type_hints(obj, globalns=None, localns=None):
14811481
search order is locals first, then globals.
14821482
14831483
- If no dict arguments are passed, an attempt is made to use the
1484-
globals from obj, and these are also used as the locals. If the
1485-
object does not appear to have globals, an exception is raised.
1484+
globals from obj (or the respective module's globals for classes),
1485+
and these are also used as the locals. If the object does not appear
1486+
to have globals, an empty dictionary is used.
14861487
14871488
- If one dict argument is passed, it is used for both globals and
14881489
locals.
@@ -1494,7 +1495,10 @@ def get_type_hints(obj, globalns=None, localns=None):
14941495
if getattr(obj, '__no_type_check__', None):
14951496
return {}
14961497
if globalns is None:
1497-
globalns = getattr(obj, '__globals__', {})
1498+
if isinstance(obj, type):
1499+
globalns = vars(sys.modules[obj.__module__])
1500+
else:
1501+
globalns = getattr(obj, '__globals__', {})
14981502
if localns is None:
14991503
localns = globalns
15001504
elif localns is None:

0 commit comments

Comments
 (0)