Skip to content

Enum equality across modules: comparing objects instead of values #74730

Description

@MadhavDatt
mannequin
BPO 30545
Nosy @bitdancer, @ethanfurman
Files
  • enum_bug-flawless_example.zip: Structurally similar example program running flawlessly
  • enum_reload_example.zip
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/ethanfurman'
    closed_at = <Date 2017-06-08.18:01:08.648>
    created_at = <Date 2017-06-02.04:58:59.769>
    labels = ['3.7', 'invalid', 'type-bug', 'library']
    title = 'Enum equality across modules: comparing objects instead of values'
    updated_at = <Date 2018-11-16.13:05:55.653>
    user = 'https://bugs.python.org/MadhavDatt'

    bugs.python.org fields:

    activity = <Date 2018-11-16.13:05:55.653>
    actor = 'Sebastian H\xc3\xb6fer'
    assignee = 'ethan.furman'
    closed = True
    closed_date = <Date 2017-06-08.18:01:08.648>
    closer = 'ethan.furman'
    components = ['Library (Lib)']
    creation = <Date 2017-06-02.04:58:59.769>
    creator = 'Madhav Datt'
    dependencies = []
    files = ['47747', '47936']
    hgrepos = []
    issue_num = 30545
    keywords = []
    message_count = 11.0
    messages = ['294983', '295025', '295032', '295036', '295038', '295457', '323411', '323418', '323432', '323433', '329994']
    nosy_count = 6.0
    nosy_names = ['r.david.murray', 'ethan.furman', 'adrianwan2', 'Madhav Datt', 'Markus Wegmann', 'Sebastian H\xc3\xb6fer']
    pr_nums = []
    priority = 'normal'
    resolution = 'not a bug'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue30545'
    versions = ['Python 3.7']

    Activity

    1. MadhavDatt commented on Jun 2, 2017

      MadhavDattmannequin
      MannequinAuthor

      The problem is described with an example in this StackOverflow question (https://stackoverflow.com/questions/26589805/python-enums-across-modules). Like in C and other languages, I would expect Enum equality to work across modules and not compare enum states/values, instead of just checking for the same object.

      A possible simple fix for this problem would be to override the __eq__() function by default in the enum.Enum class with the following:

      def __eq__(self, other):
          if isinstance(other, self.__class__):
              return self.value == other.value
          return False

      I would be happy to create a GitHub pull request to fix this, however, I do not have the experience or knowledge to know if

      • the current behavior is by design;
      • whether this is worth fixing; and
      • whether fixing this will break anything else.
    2. added
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on Jun 2, 2017
    3. ethanfurman commented on Jun 2, 2017

      @ethanfurman
      Member

      Two points:

      • Python 2.7 was the version marked, but 2.7 does not come with Enum
        (wasn't introduced until 3.4 -- the third-party backport does work
        on 2.7)

      • the problem in the SO question is not caused by Enum, but by
        re-importing a module under a different name which results in two
        different Enum classes that happen to look identical, but are not --
        so the change you propose would not help; also, since Enum members
        with the same value are mapped to the same member your change does not
        provide any new behavior.

      So, in summary, the bug here is in the user's code.

    4. MadhavDatt commented on Jun 2, 2017

      MadhavDattmannequin
      MannequinAuthor

      Thanks a lot for those points Ethan. I feel I haven't done a very good job of explaining the bug, but let me use an example. Let's say we have an Enum called MyEnum, which is in a Python module called ModuleA. ModuleB imports ModuleA, and ModuleC imports both, ModuleA and ModuleB. Now, in ModuleC, I have ModuleB.some_function() return a MyEnum state, which I pass as a parameter to ModuleA.other_function() where it is compared to MyEnum states. Here the comparison fails even though it should not have. Obviously, this problem would not arise without such imports, and so is pretty specific, but I hope this makes explains it a little better.

    5. bitdancer commented on Jun 2, 2017

      @bitdancer
      Member

      Can you provide actual code that demonstrates the issue you are talking about?

    6. ethanfurman commented on Jun 2, 2017

      @ethanfurman
      Member

      If your example code is the same as the code in the SO problem, then my previous points stand.

      According to the plain-English description you provided the comparison would succeed, so if you have example code which:

      • doesn't involve ModuleA being the __main__ script module, and
      • has the comparison fail, then

      please share it. ;) (As a comment/message here is fine.)

    7. ethanfurman commented on Jun 8, 2017

      @ethanfurman
      Member

      No test code has been provided, so lacking any evidence of this problem I am closing this issue.

      Do not reopen without testable code to show the failure.

    8. 11 remaining items

    9. added
      docsDocumentation in the Doc dir
      and removed
      stdlibStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or error
      on May 4, 2022
    10. added a commit that references this issue on Apr 3, 2023
    11. added 2 commits that reference this issue on Apr 3, 2023
    12. moved this from Docs to Done in enum issueson Apr 3, 2023
    13. added a commit that references this issue on Apr 8, 2023
    14. added a commit that references this issue on Apr 11, 2023
    15. ffissore commented on Nov 10, 2023

      @ffissore

      Hi. I stumbled on this issue once more so coded an example that triggers the weird behaviour whilst NOT using any reloading mechanism

      Pls find the code at this gist: https://gist.github.com/ffissore/e882955f8046d6c35821ba53d2134bdb#file-readme-md

      Also, I was checking the docs and I see no mentions of the different way enums equality work

    16. dybi commented on Sep 2, 2024

      @dybi

      @ffissore I had similar problem. The underlying root cause was... due to imports.
      In your example, MyEnum is imported twice (you can add below snippet to __main__.py to verify it)

      import sys
      print([mod for mod in sys.modules.keys() if "myenum" in mod])

      If you want to fix your issue, make sure that MyEnum is imported uniformly across your project.

      Cheers!

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

    Metadata

    Metadata

    Assignees

    Labels

    docsDocumentation in the Doc dir

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions