eclipse-cyclonedds / cyclonedds-python

Other
54 stars 44 forks source link

Idl Enum fields with auto are identical between each other #196

Closed morkovka1337 closed 1 year ago

morkovka1337 commented 1 year ago

I've noticed that when I use idl.IdlEnum, fields of such class are identical. The issue does not reproduce with C++ code AFAIK. I'm using cyclonedds version 0.11 built from sources.

Steps to reproduce:

from enum import auto
from dataclasses import dataclass
import cyclonedds.idl as idl

@dataclass
class ModuleStateEnum(idl.IdlEnum, typename="ModuleStateEnum", default="STATE_UNKNOWN"):
    STATE_UNKNOWN = auto()
    STATE_DISABLE = auto()
    STATE_ENABLE = auto()

print(ModuleStateEnum.STATE_DISABLE == ModuleStateEnum.STATE_ENABLE)
print(ModuleStateEnum.STATE_DISABLE == ModuleStateEnum.STATE_UNKNOWN)
print(ModuleStateEnum.STATE_UNKNOWN == ModuleStateEnum.STATE_ENABLE)
class StandartEnum:
    first = auto()
    second = auto()
    third = auto()
print(StandartEnum.first == StandartEnum.second)
print(StandartEnum.first == StandartEnum.third)
print(StandartEnum.third == StandartEnum.second)

produces:

True
True
True
False
False
False
morkovka1337 commented 1 year ago

It turns out that manually setting numbers to data fields does not work as a workaround:

from enum import auto
from dataclasses import dataclass
import cyclonedds.idl as idl

@dataclass
class ModuleStateEnum(idl.IdlEnum, typename="ModuleStateEnum"):
    STATE_UNKNOWN = 0
    STATE_DISABLE = 1
    STATE_ENABLE = 2

print(ModuleStateEnum.STATE_DISABLE == ModuleStateEnum.STATE_ENABLE)
print(ModuleStateEnum.STATE_DISABLE == ModuleStateEnum.STATE_UNKNOWN)
print(ModuleStateEnum.STATE_UNKNOWN == ModuleStateEnum.STATE_ENABLE)

class StandartEnum:
    first = auto()
    second = auto()
    third = auto()

print(StandartEnum.first == StandartEnum.second)
print(StandartEnum.first == StandartEnum.third)
print(StandartEnum.third == StandartEnum.second)
True
True
True
False
False
False
eboasson commented 1 year ago

Following a bit of experimentation ...

If I do:

class E(idl.IdlEnum, typename="E", default="A"):
    A = auto()
    B = auto()
    C = auto()

print(E.A == E.B)
print(E.B == E.C)
print(E.C == E.A)

I get False three times, as expected. This is also what idlc -lpy outputs.

If instead I do

@dataclass
class E(idl.IdlEnum, typename="E", default="A"):
    A = auto()
    B = auto()
    C = auto()

(note the addition of @dataclass) I get True three times. This reproduces your observation.

What I suspect is that for enums you should simply not use @dataclass. This is also in line with, e.g., https://github.com/eclipse-cyclonedds/cyclonedds-python/blob/master/tests/test_enum_as_discriminator.py.

My python knowledge is insufficient to give a proper root cause analysis ...

morkovka1337 commented 1 year ago

Ok, thanks for the workaround, I will try it and close the issue if it works for me. :)

morkovka1337 commented 1 year ago

Confirm , removing @dataclass solves the problem.