Skip to content

gh-149828: make Protocol compatible with Enum instantiation#149830

Open
randolf-scholz wants to merge 2 commits into
python:mainfrom
randolf-scholz:protocol_enum
Open

gh-149828: make Protocol compatible with Enum instantiation#149830
randolf-scholz wants to merge 2 commits into
python:mainfrom
randolf-scholz:protocol_enum

Conversation

@randolf-scholz
Copy link
Copy Markdown
Contributor

@randolf-scholz randolf-scholz commented May 14, 2026

Fixes #149828

This was surprisingly easy, the issue is that with enums, __init_subclass__ is only called after EnumType.__new__ is finished.

However, when subclassing from typing.Protocol, _is_protocol is only set during __init_subclass__. The fix is to replace the lookup of _is_protocol inside _no_init_or_replace_init with the actual check.

A more robust solution would probably be for _is_protocol to be a lazy class property, but that would be a larger change and class-properties are not natively supported...

cc @sobolevn

Copy link
Copy Markdown
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

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

Looks fine to me! Let's wait for @ethanfurman :)

@AlexWaygood AlexWaygood added the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label May 14, 2026
@bedevere-bot
Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @AlexWaygood for commit 5ab82ba 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F149830%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-refleak-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-refleak-buildbots Test PR w/ refleak buildbots; report in status section label May 14, 2026
Comment thread Lib/test/test_enum.py
@randolf-scholz randolf-scholz changed the title gh-119946: make Protocol compatible with Enum instantiation gh-149828: make Protocol compatible with Enum instantiation May 15, 2026
@randolf-scholz
Copy link
Copy Markdown
Contributor Author

Had to update the PR title since I copy-pasted the wrong issue number. The Misc/NEWS.d already used the correct number though, so no code changes are needed.

Comment thread Lib/typing.py
# Note: not using cls._is_protocol here,
# since this may be called before __init_subclass__ is resolved.
# for example when subclassing enum.Enum.
if any(b is Protocol for b in cls.__bases__):
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.

Could this break when inheriting from typing_extensions.Protocol?

Comment thread Lib/test/test_enum.py
globals()['T'] = T
test_pickle_dump_load(self.assertIs, SomeEnum.first)

def test_protocol_mixin_as_enum_member_value(self):
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.

The change you made was to typing.py. Can you add a test case to test_typing that demonstrates the issue without relying on enum itself?

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jun 3, 2026

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

And if you don't make the requested changes, you will be poked with soft cushions!

Comment thread Lib/test/test_enum.py
Comment on lines +2495 to +2497
globals()['Example'] = Example
globals()['Impl'] = Impl
globals()['ProtoEnum'] = ProtoEnum
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.

I also feel like we shouldn't be mutating the global environment in a test like this. If these classes need to be global, can't we just define them in the global scope? I was honestly surprised the refleak buildbots didn't complain about this

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.

They don't because we run a warmup round first; refleak buildbots only complain if you keep leaking on every test.

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.

ah makes sense

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot subclass from Protocol and Enum at the same time.

6 participants