Functionally created Enums misbehaviours

How severe does this issue affect your experience of using Ray?

  • Low: It annoys or frustrates me for a moment.

Hi, I am using ray 1.9.0 and I have an issue with functionally created enums.
More specifically when the first parameter of Enum doesn’t match the assigned variable name.

Here is a minimal example:

a.py

from enum import Enum

A = Enum('B', ['a'])

class Actor:
    def __init__(self, arg_a) -> None:
        self.a = A.a
        self.arg_a = arg_a

    def compare(self, arg_a):
        print(self.a == A.a)
        print(self.arg_a == A.a)
        print(arg_a == A.a)
        print(arg_a == self.arg_a)

b.py:

from file import A, Actor
actor = ray.remote(Actor).remote(A.a)
ray.get(actor.compare.remote(A.a))

Then running b.py results in True, False, False, True

When replacing “A = Enum(‘B’, [‘a’])” into “A = Enum(‘A’, [‘a’])” it works fine.
It also doesn’t happen when all the code belong to the same file.

But I would like my code to be robust to this (which can happen anytime I rename a variable for instace …)

Is it something that doesn’t happen in later ray versions ?
Could you please explain why this is happening ?

Many thanks

The same issue seems to happen in Ray 2.8. I think it is due to how enum comparison works doesn’t work well with python serialization & deserialization (I think Python enum is a singleton, and the eq is decided by the address of the class, not the value).

        from pprint import pprint
        pprint(hex(id(self.a)))
        pprint(hex(id(self.arg_a)))

If you add this to your compare method, you can see this more clearly

You can alternaitvely fix the issue by creating your own enum implementation that overwrites eq

class ComparableEnum(Enum):
    def __eq__(self, other):
        return self.name == other.name and self.value == other.value
A = ComparableEnum('B', ['a'])

Thank you for your answer !

Unfortunately ComparableEnum doesn’t really solve my issue as it loses the whole point of enum:
I don’t want ComparableEnum(‘B’, [‘a’]).a to be equal to neither ComparableEnum(‘C’, [‘a’]).a nor another ComparableEnum(‘B’, [‘a’]).a where ComparableEnum(‘B’, [‘a’]) was defined in another module.
So I guess we would need to check in the module in which each enum has been defined in the equality as well but I don’t know yet how to do that and it doesn’t feel right to reimplement such a low level behaviour

So I guess we would need to check in the module in which each enum has been defined in the equality as well but I don’t know yet how to do that and it doesn’t feel right to reimplement such a low level behaviour

Yeah to me adding module check in the comparable enum sounds like the best option here.