mirror of https://github.com/python/cpython
bpo-44468: Never skip base classes in `typing.get_type_hints()`, even with invalid `.__module__`. (GH-26862)
This commit is contained in:
parent
521ba8892e
commit
7569c0fe91
|
@ -2277,13 +2277,6 @@ class ClassVarTests(BaseTestCase):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
issubclass(int, ClassVar)
|
issubclass(int, ClassVar)
|
||||||
|
|
||||||
def test_bad_module(self):
|
|
||||||
# bpo-41515
|
|
||||||
class BadModule:
|
|
||||||
pass
|
|
||||||
BadModule.__module__ = 'bad' # Something not in sys.modules
|
|
||||||
self.assertEqual(get_type_hints(BadModule), {})
|
|
||||||
|
|
||||||
class FinalTests(BaseTestCase):
|
class FinalTests(BaseTestCase):
|
||||||
|
|
||||||
def test_basics(self):
|
def test_basics(self):
|
||||||
|
@ -3033,6 +3026,24 @@ class GetTypeHintTests(BaseTestCase):
|
||||||
# This previously raised an error under PEP 563.
|
# This previously raised an error under PEP 563.
|
||||||
self.assertEqual(get_type_hints(Foo), {'x': str})
|
self.assertEqual(get_type_hints(Foo), {'x': str})
|
||||||
|
|
||||||
|
def test_get_type_hints_bad_module(self):
|
||||||
|
# bpo-41515
|
||||||
|
class BadModule:
|
||||||
|
pass
|
||||||
|
BadModule.__module__ = 'bad' # Something not in sys.modules
|
||||||
|
self.assertNotIn('bad', sys.modules)
|
||||||
|
self.assertEqual(get_type_hints(BadModule), {})
|
||||||
|
|
||||||
|
def test_get_type_hints_annotated_bad_module(self):
|
||||||
|
# See https://bugs.python.org/issue44468
|
||||||
|
class BadBase:
|
||||||
|
foo: tuple
|
||||||
|
class BadType(BadBase):
|
||||||
|
bar: list
|
||||||
|
BadType.__module__ = BadBase.__module__ = 'bad'
|
||||||
|
self.assertNotIn('bad', sys.modules)
|
||||||
|
self.assertEqual(get_type_hints(BadType), {'foo': tuple, 'bar': list})
|
||||||
|
|
||||||
|
|
||||||
class GetUtilitiesTestCase(TestCase):
|
class GetUtilitiesTestCase(TestCase):
|
||||||
def test_get_origin(self):
|
def test_get_origin(self):
|
||||||
|
|
|
@ -1701,10 +1701,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False):
|
||||||
hints = {}
|
hints = {}
|
||||||
for base in reversed(obj.__mro__):
|
for base in reversed(obj.__mro__):
|
||||||
if globalns is None:
|
if globalns is None:
|
||||||
try:
|
base_globals = getattr(sys.modules.get(base.__module__, None), '__dict__', {})
|
||||||
base_globals = sys.modules[base.__module__].__dict__
|
|
||||||
except KeyError:
|
|
||||||
continue
|
|
||||||
else:
|
else:
|
||||||
base_globals = globalns
|
base_globals = globalns
|
||||||
ann = base.__dict__.get('__annotations__', {})
|
ann = base.__dict__.get('__annotations__', {})
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
:func:`typing.get_type_hints` now finds annotations in classes and base classes
|
||||||
|
with unexpected ``__module__``. Previously, it skipped those MRO elements.
|
Loading…
Reference in New Issue