From 5257ade0bc9b53471227d0e67999df7c8ad633a7 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Thu, 12 Oct 2023 05:20:20 +0300 Subject: [PATCH] gh-110682: Ignore `__match_args__` from `__instancecheck__` in protocols (#110683) Co-authored-by: Alex Waygood --- Lib/test/test_typing.py | 33 +++++++++++++++++++ Lib/typing.py | 3 +- ...-10-11-11-00-11.gh-issue-110682.bXRFaX.rst | 4 +++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2023-10-11-11-00-11.gh-issue-110682.bXRFaX.rst diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index c24cf3bc776..66812f317c7 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -3801,6 +3801,39 @@ class ProtocolTests(BaseTestCase): 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 d1f371377b8..14845b36028 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1669,7 +1669,8 @@ _TYPING_INTERNALS = frozenset({ _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 00000000000..b935d9a769c --- /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.