Skip to content

Enum _missing_ function changes __contains__ behaviour #132684

Closed

Description

@artur-sl

Bug report

Bug description:

I observed different behavior for Enum __contains__ in 3.13.2 and 3.13.3 if there is _missing_ method implemented:

from enum import Enum

class Color(Enum):
    RED = 1
    
    @classmethod
    def _missing_(cls, value):
        return cls.RED

# 3.13.2
>>> "blue" in Color
False

# 3.13.3
>>> "blue" in Color
True

IMO _missing_ should only influence the __call__ method:

# both 3.13.2 and 3.13.3
>>> Color("blue")
<Color.RED: 1>

CPython versions tested on:

3.13

Operating systems tested on:

macOS

Linked PRs

Activity

  1. noamcohen97 commented on Apr 18, 2025

    @noamcohen97
    Contributor

    I am fairly certain this is a side effect of #131053, but I'm not sure what the correct behavior should be.
    @picnixz @ethanfurman, what are your thoughts?

  2. picnixz commented on Apr 18, 2025

    @picnixz
    Member

    Arf... this is something I didn't think of. This can be pretty annoying and we could also need to revert it in 3.12 :< I'll mark it as a release-blocker for now to draw attention.

  3. added
    3.12only security fixes
    3.13only security fixes
    3.14bugs and security fixes
    on Apr 18, 2025
  4. picnixz commented on Apr 18, 2025

    @picnixz
    Member

    Actually, Ethan said on the previous issue:

    In other words, if Weekday(x) would return a valid member, then x in Weekday should return True.

    Now, here Color("blue") returns Color.RED. So... if we were to follow the same logic, "blue" in Color would still be correct. I'm not entirely sure whether we need to fix this or not but I know for sure that sometimes we do checks of the form x in ENUM and depending on how the ENUM is being done, we may or may not have broken some code out there.

  5. s3rius commented on Apr 18, 2025

    @s3rius

    I guess it makes total sense, because usually you only check that the value is present in the enum to create its member.

    But if you really want to mimic the behavior of 3.12 then you can use this workaround:

    >>> 'blue' in {color.name for color in Color}
    False
  6. noamcohen97 commented on Apr 18, 2025

    @noamcohen97
    Contributor

    Perhaps we should simply document the change in behavior?

  7. picnixz commented on Apr 18, 2025

    @picnixz
    Member

    If possible, yes, but it's also sad that the behavior of some constructions have been broken in a stable release.

  8. 1 remaining item

  9. ethanfurman commented on Apr 22, 2025

    @ethanfurman
    Member

    we could also need to revert it in 3.12

    3.12 is in security-only mode, unfortunately.

  10. picnixz commented on Apr 24, 2025

    @picnixz
    Member

    We can still ask @Yhg1s if he would consider the bugfix as an incomplete bugfix then (considering we broke something =/) and backport your recent bugfix.

  11. added a commit that references this issue on Apr 25, 2025
  12. added a commit that references this issue on Apr 25, 2025
  13. added a commit that references this issue on Apr 25, 2025
  14. hugovk commented on May 5, 2025

    @hugovk
    Member

    (Noting this is release-blocker for 3.12, not 3.14 or 3.13)

  15. removed
    3.14bugs and security fixes
    on May 5, 2025
  16. Yhg1s commented on Jun 2, 2025

    @Yhg1s
    Member

    Yeah, fine, get this backport in the next release if you want.

    However, something to keep in mind is that as a security fix release, we won't be distributing installers for Windows / macOS.

  17. picnixz commented on Jun 2, 2025

    @picnixz
    Member

    However, something to keep in mind is that as a security fix release, we won't be distributing installers for Windows / macOS.

    Hum. Then I don't know then. This could be quite annoying if it's an OS-dependant stuff. I think it's better to tell people to upgrade to Python 3.13 in this case.

  18. ambv commented on Jun 3, 2025

    @ambv
    Contributor

    This could be quite annoying if it's an OS-dependant stuff.

    It's not "OS-dependent", we simply don't provide installers for the fix, but you can still get them through ActiveState or Anaconda or winpython or...

  19. ambv commented on Jun 3, 2025

    @ambv
    Contributor

    That being said, I attempted a backport and it broke 21 old tests, so I decided it's not worth fiddling with it and breaking it even more. After speaking with Thomas, we are aborting the 3.12 backport.

  20. ethanfurman commented on Jun 3, 2025

    @ethanfurman
    Member

    Thanks for trying.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.12only security fixes3.13only security fixesrelease-blockerstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions