mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-132493: Avoid eager import of annotationlib in typing (again) (#132596)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
e42bda9441
commit
5707837049
2 changed files with 34 additions and 12 deletions
|
@ -3149,6 +3149,21 @@ class ProtocolTests(BaseTestCase):
|
|||
with self.assertRaisesRegex(TypeError, only_classes_allowed):
|
||||
issubclass(1, BadPG)
|
||||
|
||||
def test_isinstance_against_superproto_doesnt_affect_subproto_instance(self):
|
||||
@runtime_checkable
|
||||
class Base(Protocol):
|
||||
x: int
|
||||
|
||||
@runtime_checkable
|
||||
class Child(Base, Protocol):
|
||||
y: str
|
||||
|
||||
class Capybara:
|
||||
x = 43
|
||||
|
||||
self.assertIsInstance(Capybara(), Base)
|
||||
self.assertNotIsInstance(Capybara(), Child)
|
||||
|
||||
def test_implicit_issubclass_between_two_protocols(self):
|
||||
@runtime_checkable
|
||||
class CallableMembersProto(Protocol):
|
||||
|
@ -6323,7 +6338,7 @@ class InternalsTests(BaseTestCase):
|
|||
"inspect",
|
||||
"re",
|
||||
"contextlib",
|
||||
# "annotationlib", # TODO
|
||||
"annotationlib",
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -1801,9 +1801,13 @@ def _get_protocol_attrs(cls):
|
|||
for base in cls.__mro__[:-1]: # without object
|
||||
if base.__name__ in {'Protocol', 'Generic'}:
|
||||
continue
|
||||
annotations = _lazy_annotationlib.get_annotations(
|
||||
base, format=_lazy_annotationlib.Format.FORWARDREF
|
||||
)
|
||||
try:
|
||||
annotations = base.__annotations__
|
||||
except Exception:
|
||||
# Only go through annotationlib to handle deferred annotations if we need to
|
||||
annotations = _lazy_annotationlib.get_annotations(
|
||||
base, format=_lazy_annotationlib.Format.FORWARDREF
|
||||
)
|
||||
for attr in (*base.__dict__, *annotations):
|
||||
if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES:
|
||||
attrs.add(attr)
|
||||
|
@ -2020,14 +2024,17 @@ def _proto_hook(cls, other):
|
|||
break
|
||||
|
||||
# ...or in annotations, if it is a sub-protocol.
|
||||
if (
|
||||
issubclass(other, Generic)
|
||||
and getattr(other, "_is_protocol", False)
|
||||
and attr in _lazy_annotationlib.get_annotations(
|
||||
base, format=_lazy_annotationlib.Format.FORWARDREF
|
||||
)
|
||||
):
|
||||
break
|
||||
if issubclass(other, Generic) and getattr(other, "_is_protocol", False):
|
||||
# We avoid the slower path through annotationlib here because in most
|
||||
# cases it should be unnecessary.
|
||||
try:
|
||||
annos = base.__annotations__
|
||||
except Exception:
|
||||
annos = _lazy_annotationlib.get_annotations(
|
||||
base, format=_lazy_annotationlib.Format.FORWARDREF
|
||||
)
|
||||
if attr in annos:
|
||||
break
|
||||
else:
|
||||
return NotImplemented
|
||||
return True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue