pytransitions / transitions

A lightweight, object-oriented finite state machine implementation in Python with many extensions
MIT License
5.49k stars 524 forks source link

unable to print state when __eq__ is overloaded. #536

Closed ppanteliadis closed 2 years ago

ppanteliadis commented 3 years ago

I made a temp object with the following attributes:

class ItemType(Enum):
    """
    Enum for item type abbreviations
    """

    NOT_ASSIGNED = auto()
    BAKERY = auto()
    BEVERAGE = auto()
    PRODUCE = auto()
    FLORAL = auto()
    DELI = auto()
    PREPARED_FOODS = auto()
    MEAT = auto()
    FISH = auto()
    DAIRY = auto()
    CANNED_FOOD = auto()

class Item:
    """
    Represents an Item
    """

    # Define FSM states
    states = ['new', 'out_of_stock', 'replaced', 'adjusted', 'cancelled', 'validated', 'validation_required', 'collected']

    def __init__(
        self,
        *,
        name: str,
        status: ItemStatus,
        quantity: int,
        # Optional args
        _id: Optional[ObjectId] = None,
        itype: Optional[ItemType] = ItemType.NOT_ASSIGNED,
    ):
        if quantity < 0:
            raise NegativeItemException("Can't have negative items")

        self.name = name
        self.status = status
        self.quantity = quantity
        self.prediction_time = datetime.now(tz=timezone(LOCALE))

self._initialize_fsm()

    def _initialize_fsm(self):
        """
        Given an FSM for the states of an Item, defines the triggers that will trigger transitions
        between states

        :return:
        """
        self.fsm = Machine(model=self, states=Item.states, initial='new')
        self.fsm.add_transition(trigger='validate', source='new', dest='validated')
        self.fsm.add_transition(trigger='todo', source='new', dest='validation_required')
        self.fsm.add_transition(trigger='todo', source='new', dest='adjusted')
        self.fsm.add_transition(trigger='todo', source='new', dest='out_of_stock')
        self.fsm.add_transition(trigger='cancel', source='new', dest='cancelled')
        self.fsm.add_transition(trigger='replace', source='out_of_stock', dest='replaced')
        self.fsm.add_transition(trigger='cancel', source='out_of_stock', dest='cancelled')
        self.fsm.add_transition(trigger='cancel', source='validation_required', dest='cancelled')
        self.fsm.add_transition(trigger='validate', source='validation_required', dest='validated')
        self.fsm.add_transition(trigger='cancel', source='validated', dest='cancelled')
        self.fsm.add_transition(trigger='collect', source='validated', dest='collected')

   def __eq__(self, other):
        """
        Returns true if the current item is equal to the other.

        :param other:
        :return:
        """
        return all(
            [
                isinstance(other, type(self)),
                self.name == other.name,
                self.type == other.type,
            ]
        )

Then, if I do:

myitem = Item(
        name="Cream Cheese 200gr",
        status=ItemStatus.NEW,
        quantity=2,
    )

I get an error originating from the equality.

ppanteliadis commented 3 years ago

However if I don't overload the equality operator, then everything works smoothly.

aleneum commented 3 years ago

Hello @ppanteliadis, I don't know if this is still relevant to you but if so, could you provide a minimal code example that reproduces your issue? Your code snippet right now lacks imports and used definitions such as ItemStatus. Cheers!

aleneum commented 2 years ago

Closing due to a lack of feedback. Feel free to comment if you still have this issue. I will reopen the issue if necessary.