Skip to content

Commit

Permalink
Fix isinstance check for Generic classes on Python 3.7 (#188)
Browse files Browse the repository at this point in the history
  • Loading branch information
dolfinus committed May 24, 2023
1 parent f62fa3f commit 57aae62
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# Unreleased

- Fix regression in version 4.6.1 where comparing a generic class against a
runtime-checkable protocol using `isinstance()` would cause `AttributeError`
to be raised if using Python 3.7

# Release 4.6.1 (May 23, 2023)

- Change deprecated `@runtime` to formal API `@runtime_checkable` in the error
Expand Down
23 changes: 23 additions & 0 deletions src/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2246,6 +2246,28 @@ class Foo: ...
del f.x
self.assertNotIsInstance(f, HasX)

def test_protocols_isinstance_generic_classes(self):
T = TypeVar("T")

class Foo(Generic[T]):
x: T

def __init__(self, x):
self.x = x

class Bar(Foo[int]):
...

@runtime_checkable
class HasX(Protocol):
x: int

foo = Foo(1)
self.assertIsInstance(foo, HasX)

bar = Bar(2)
self.assertIsInstance(bar, HasX)

def test_protocols_support_register(self):
@runtime_checkable
class P(Protocol):
Expand Down Expand Up @@ -4330,6 +4352,7 @@ class Y(Generic[T], NamedTuple):

a = A(3)
self.assertIs(type(a), G)
self.assertIsInstance(a, G)
self.assertEqual(a.x, 3)

things = "arguments" if sys.version_info >= (3, 11) else "parameters"
Expand Down
5 changes: 3 additions & 2 deletions src/typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import typing
import warnings


__all__ = [
# Super-special typing primitives.
'Any',
Expand Down Expand Up @@ -659,7 +658,9 @@ def _proto_hook(cls, other):
isinstance(annotations, collections.abc.Mapping)
and attr in annotations
and issubclass(other, (typing.Generic, _ProtocolMeta))
and other._is_protocol
# All subclasses of Generic have an _is_proto attribute on 3.8+
# But not on 3.7
and getattr(other, "_is_protocol", False)
):
break
else:
Expand Down

0 comments on commit 57aae62

Please sign in to comment.