Skip to content

Commit 51cf7e8

Browse files
committed
pythongh-102433: Add tests for how properties interact with typing.runtime_checkable protocols
1 parent 3222054 commit 51cf7e8

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

Lib/test/test_typing.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2535,6 +2535,112 @@ def meth(x): ...
25352535
with self.assertRaises(TypeError):
25362536
isinstance(C(), BadPG)
25372537

2538+
def test_protocols_isinstance_simple_properties(self):
2539+
T = TypeVar('T')
2540+
2541+
@runtime_checkable
2542+
class P(Protocol):
2543+
@property
2544+
def attr(self): ...
2545+
2546+
@runtime_checkable
2547+
class P1(Protocol):
2548+
attr: int
2549+
2550+
@runtime_checkable
2551+
class PG(Protocol[T]):
2552+
@property
2553+
def attr(self): ...
2554+
2555+
@runtime_checkable
2556+
class PG1(Protocol[T]):
2557+
attr: T
2558+
2559+
class BadP(Protocol):
2560+
@property
2561+
def attr(self): ...
2562+
2563+
class BadP1(Protocol):
2564+
attr: int
2565+
2566+
class BadPG(Protocol[T]):
2567+
@property
2568+
def attr(self): ...
2569+
2570+
class BadPG1(Protocol[T]):
2571+
attr: T
2572+
2573+
class C:
2574+
@property
2575+
def attr(self):
2576+
return 42
2577+
2578+
self.assertEqual(C().attr, 42)
2579+
self.assertIsInstance(C(), P)
2580+
self.assertIsInstance(C(), P1)
2581+
self.assertIsInstance(C(), PG)
2582+
self.assertIsInstance(C(), PG1)
2583+
with self.assertRaises(TypeError):
2584+
isinstance(C(), PG[T])
2585+
with self.assertRaises(TypeError):
2586+
isinstance(C(), PG[C])
2587+
with self.assertRaises(TypeError):
2588+
isinstance(C(), PG1[T])
2589+
with self.assertRaises(TypeError):
2590+
isinstance(C(), PG1[C])
2591+
with self.assertRaises(TypeError):
2592+
isinstance(C(), BadP)
2593+
with self.assertRaises(TypeError):
2594+
isinstance(C(), BadP1)
2595+
with self.assertRaises(TypeError):
2596+
isinstance(C(), BadPG)
2597+
with self.assertRaises(TypeError):
2598+
isinstance(C(), BadPG1)
2599+
2600+
def test_protocols_isinstance_dynamic_properties(self):
2601+
T = TypeVar('T')
2602+
2603+
@runtime_checkable
2604+
class P(Protocol):
2605+
@property
2606+
def attr(self): ...
2607+
2608+
@runtime_checkable
2609+
class P1(Protocol):
2610+
attr: int
2611+
2612+
@runtime_checkable
2613+
class PG(Protocol[T]):
2614+
@property
2615+
def attr(self): ...
2616+
2617+
@runtime_checkable
2618+
class PG1(Protocol[T]):
2619+
attr: T
2620+
2621+
class C:
2622+
X = False
2623+
@property
2624+
def attr(self):
2625+
if self.X:
2626+
return 42
2627+
raise AttributeError
2628+
2629+
inst = C()
2630+
with self.assertRaises(AttributeError):
2631+
inst.attr
2632+
self.assertNotIsInstance(inst, P)
2633+
self.assertNotIsInstance(inst, P1)
2634+
self.assertNotIsInstance(inst, PG)
2635+
self.assertNotIsInstance(inst, PG1)
2636+
2637+
C.X = True
2638+
self.assertEqual(inst.attr, 42)
2639+
self.assertIsInstance(inst, P)
2640+
self.assertIsInstance(inst, P1)
2641+
self.assertIsInstance(inst, PG)
2642+
self.assertIsInstance(inst, PG1)
2643+
25382644
def test_protocols_isinstance_py36(self):
25392645
class APoint:
25402646
def __init__(self, x, y, label):

0 commit comments

Comments
 (0)