Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Cover a property member in the regression test
A property is not callable when looked up on the class, so it lands in
__non_callable_proto_members__ alongside a plain class attribute. Both
subtests fail without the change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016TM2nkuPFj6FFmZyUJZYUQ
  • Loading branch information
adamtheturtle and claude committed Aug 27, 2026
commit 7f7bc3fd95b33aeb00da13ab71e58ac2ea66363b
30 changes: 20 additions & 10 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3894,22 +3894,32 @@ def test_none_on_non_callable_doesnt_defeat_the_abc_cache(self):
# class out of ABCMeta's cache and made every isinstance() call walk
# all of the protocol members again.
@runtime_checkable
class P(Protocol):
class PAttr(Protocol):
x = 1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check with a protocol defining a property as well? it's not really a callable strictly speaking.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Deleted comment that the bot wrote).

Yes - added in a new commit.


@runtime_checkable
class PProperty(Protocol):
@property
def x(self) -> int: ...

class B:
x = None

self.assertIsInstance(B(), P)

# The first check must have cached B as a subclass of P, so the second
# one may not touch the members at all.
typing._lazy_load_getattr_static.cache_clear()
try:
with patch.object(inspect, "getattr_static", side_effect=AssertionError):
for P in (PAttr, PProperty):
with self.subTest(protocol=P.__name__):
self.assertIn("x", P.__non_callable_proto_members__)
self.assertIsInstance(B(), P)
finally:
typing._lazy_load_getattr_static.cache_clear()

# The first check must have cached B as a subclass of P, so
# the second one may not touch the members at all.
typing._lazy_load_getattr_static.cache_clear()
try:
with patch.object(
inspect, "getattr_static", side_effect=AssertionError
):
self.assertIsInstance(B(), P)
finally:
typing._lazy_load_getattr_static.cache_clear()

def test_none_on_callable_blocks_implementation(self):
@runtime_checkable
Expand Down
Loading