From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Fri, 7 Apr 2023 17:47:49 +0000 (-0700) Subject: gh-74690: Add more tests for runtime-checkable protocols (GH-103347) X-Git-Tag: v3.11.4~219 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1b1f0164cb210abc0af5803bee071d67e8272bb8;p=thirdparty%2FPython%2Fcpython.git gh-74690: Add more tests for runtime-checkable protocols (GH-103347) (cherry picked from commit 800382a2b0980c21dfb2a8ac02aaf1e881f987b9) Co-authored-by: Alex Waygood --- diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 4de24472c2c0..46cff6ad5085 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2572,6 +2572,22 @@ class ProtocolTests(BaseTestCase): class PG(Protocol[T]): def meth(x): ... + @runtime_checkable + class WeirdProto(Protocol): + meth = str.maketrans + + @runtime_checkable + class WeirdProto2(Protocol): + meth = lambda *args, **kwargs: None + + class CustomCallable: + def __call__(self, *args, **kwargs): + pass + + @runtime_checkable + class WeirderProto(Protocol): + meth = CustomCallable() + class BadP(Protocol): def meth(x): ... @@ -2581,8 +2597,15 @@ class ProtocolTests(BaseTestCase): class C: def meth(x): ... - self.assertIsInstance(C(), P) - self.assertIsInstance(C(), PG) + class C2: + def __init__(self): + self.meth = lambda: None + + for klass in C, C2: + for proto in P, PG, WeirdProto, WeirdProto2, WeirderProto: + with self.subTest(klass=klass.__name__, proto=proto.__name__): + self.assertIsInstance(klass(), proto) + with self.assertRaises(TypeError): isinstance(C(), PG[T]) with self.assertRaises(TypeError): @@ -2735,6 +2758,20 @@ class ProtocolTests(BaseTestCase): self.assertIsInstance(C(1), P) self.assertIsInstance(C(1), PG) + def test_protocols_isinstance_monkeypatching(self): + @runtime_checkable + class HasX(Protocol): + x: int + + class Foo: ... + + f = Foo() + self.assertNotIsInstance(f, HasX) + f.x = 42 + self.assertIsInstance(f, HasX) + del f.x + self.assertNotIsInstance(f, HasX) + def test_protocol_checks_after_subscript(self): class P(Protocol[T]): pass class C(P[T]): pass