Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pylint complains that transition methods don't exist #426

Closed
Bob-May opened this issue Apr 9, 2020 · 6 comments
Closed

pylint complains that transition methods don't exist #426

Bob-May opened this issue Apr 9, 2020 · 6 comments

Comments

@Bob-May
Copy link

Bob-May commented Apr 9, 2020

From readme.md

Notice the shiny new methods attached to the Matter instance (evaporate(), ionize(), etc.). Each method triggers the corresponding transition. You don't have to explicitly define these methods anywhere; the name of each transition is bound to the model passed to the Machine initializer (in this case, lump). Additionally, there is a method called trigger now attached to your model. This method lets you execute transitions by name in case dynamic triggering is required.

example to reproduce:

import transitions
class myStateMachine(object):

    # Define states
    states = ['State_A', 'State_B']

    def __init__(self):

        # Initialize the state machine
        self.state = None #prevents the linter from complaining that there is no state member
        self.machine = transitions.Machine(model=self, states=self.states, initial='State_A')

        #Define Transitions
        self.machine.add_transition('to_B','State_A', 'State_B')
        self.machine.add_transition('to_A', 'State_B', 'State_A')
        
        
if __name__ == "__main__":
    
    example = myStateMachine()
    example.to_B()
    print(example.state)

output>>
State_B
State_A

pylint complains

Instance of 'myStateMachine' has no 'to_B' member
Instance of 'myStateMachine' has no 'to_A' member

How to prevent these errors?

@Bob-May
Copy link
Author

Bob-May commented Apr 10, 2020

Looking through closed issues I see that fundamentally this is related to Issue #383

@Panos26
Copy link

Panos26 commented Apr 14, 2020

So did you came up with the solution for your example without using docstrings?

@Bob-May
Copy link
Author

Bob-May commented Apr 14, 2020

I have not made any attempt yet to prevent the issue.

So far my "solution" is to say to myself "It's not really a problem" when pylint highlights one of these items.

@shuttle1987
Copy link

Perhaps we can just tell Pylint that these are generated members if we want the false positive warning will go away? More about why this happens here: https://www.lesinskis.com/pylint-false-positives.html

@aleneum
Copy link
Member

aleneum commented May 17, 2020

If silencing E1101 is all that is needed, generated-members in .pylintrc could do the trick. This will apease pylint when generated-members=run:

"""a test"""

import transitions


class MyStateMachine:
    """A machine"""

    # Define states
    states = ['State_A', 'State_B']

    def __init__(self):

        # Initialize the state machine
        self.state = None  # prevents the linter from complaining that there is no state member
        self.machine = transitions.Machine(model=self, states=self.states, initial='State_A',
                                           auto_transitions=False)

        # Define Transitions
        self.machine.add_transition('run', 'State_A', 'State_B')
        self.machine.add_transition('go', 'State_B', 'State_A')

    def processing(self):
        """processes things"""

    def rapid_processing(self):
        """processes things... but faster!"""


def main():
    """where the action is"""
    example = MyStateMachine()
    example.run()


if __name__ == "__main__":
    main()

However, I am not sure how this should be automatized though. Adding all potential triggers manually is quite cumbersome. For Machine a list of transitions can be retrieved with:

    print(", ". join(example.machine.events.keys()))

This will not include OTHER convenience functions such as is_State_A and trigger. They could be derived from transition and state names though. So extending on the one liner above might be all that is needed to generate a method whitelist:

    whitelist = ['trigger', 'state']
    whitelist.extend(example.machine.events.keys())
    for s in example.machine.states:
        whitelist.append(f'is_{s}')
    print(",".join(whitelist))  # >>> trigger,state,run,go,is_State_A,is_State_B

@aleneum
Copy link
Member

aleneum commented Jun 12, 2020

Closing this due to the lack of feedback. If you have more to add to that issue, feel free to comment. I will reopen the issue if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants