diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index c24cf3bc776fc1..66812f317c7656 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3801,6 +3801,39 @@ class E: self.assertIsInstance(E(), D) + def test_runtime_checkable_with_match_args(self): + @runtime_checkable + class P_regular(Protocol): + x: int + y: int + + @runtime_checkable + class P_match(Protocol): + __match_args__ = ('x', 'y') + x: int + y: int + + class Regular: + def __init__(self, x: int, y: int): + self.x = x + self.y = y + + class WithMatch: + __match_args__ = ('x', 'y', 'z') + def __init__(self, x: int, y: int, z: int): + self.x = x + self.y = y + self.z = z + + class Nope: ... + + self.assertIsInstance(Regular(1, 2), P_regular) + self.assertIsInstance(Regular(1, 2), P_match) + self.assertIsInstance(WithMatch(1, 2, 3), P_regular) + self.assertIsInstance(WithMatch(1, 2, 3), P_match) + self.assertNotIsInstance(Nope(), P_regular) + self.assertNotIsInstance(Nope(), P_match) + def test_supports_int(self): self.assertIsSubclass(int, typing.SupportsInt) self.assertNotIsSubclass(str, typing.SupportsInt) diff --git a/Lib/typing.py b/Lib/typing.py index d1f371377b88f8..14845b36028ca1 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1669,7 +1669,8 @@ class _TypingEllipsis: _SPECIAL_NAMES = frozenset({ '__abstractmethods__', '__annotations__', '__dict__', '__doc__', '__init__', '__module__', '__new__', '__slots__', - '__subclasshook__', '__weakref__', '__class_getitem__' + '__subclasshook__', '__weakref__', '__class_getitem__', + '__match_args__', }) # These special attributes will be not collected as protocol members. diff --git a/Misc/NEWS.d/next/Library/2023-10-11-11-00-11.gh-issue-110682.bXRFaX.rst b/Misc/NEWS.d/next/Library/2023-10-11-11-00-11.gh-issue-110682.bXRFaX.rst new file mode 100644 index 00000000000000..b935d9a769c3c6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-11-11-00-11.gh-issue-110682.bXRFaX.rst @@ -0,0 +1,4 @@ +:func:`runtime-checkable protocols ` used +to consider ``__match_args__`` a protocol member in +``__instancecheck__`` if it was present on the protocol. Now, this attribute is +ignored if it is present.