From c3690ad25cceb71c89817c920385007eaa0a4b79 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Fri, 7 Apr 2023 14:39:58 +0100 Subject: [PATCH] gh-74690: Add more tests for runtime-checkable protocols --- Lib/test/test_typing.py | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 7d2e6a6a9f6287..b8eee9a570a301 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2577,6 +2577,22 @@ def meth(x): ... 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): ... @@ -2586,8 +2602,15 @@ def meth(x): ... 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): @@ -2829,6 +2852,20 @@ def __init__(self, x): 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