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

Exception when used with %autoreload #257

Closed
xiao-fred opened this issue Feb 17, 2020 · 4 comments
Closed

Exception when used with %autoreload #257

xiao-fred opened this issue Feb 17, 2020 · 4 comments

Comments

@xiao-fred
Copy link

  • Python State Machine version: 0.8.0
  • Python version: 3.7.6
  • Operating System: macOS 10.15.2

Description

I am using statemachine in a project, with Jupyter notebook and the IPython %autoreload extension.

I have been using Jupyter and autoreload for years, and I haven't met any serious problem until now. But it leads to a systematic exception in statemachine. And unless it can be solved, I will have to give up statemachine, since there is no way I give up Jupyter and autoreload...

What I Did

Create two files:

File 1: my_state_machine.py

from statemachine import StateMachine, State


class MyStateMachine(StateMachine):
    state1 = State('State1', initial=True)
    state2 = State('State2')
    state3 = State('State3')

    transition12 = state1.to(state2)
    transition23 = state2.to(state3)

    def do_something(self):
        print('something')

File 2: Jupyter notebook
Create 2 cells:
Cell #1

%load_ext autoreload
%autoreload 2

from my_state_machine import MyStateMachine

Cell #2

state_machine = MyStateMachine()
state_machine.transition12()

Execute both cells (cell #1 then cell #2). It's working. Fine.
Execute cell #2 once again. It's working too. Fine.

Now modify my_state_machine.py. No need to modify the states or transitions. Just modify the do_something() method:

def do_something(self):
    print('something else')

Now run cell #2 once again. Autoreload automatically reloads the statemachine module. But obviously something goes wrong, and systematically leads to an exception:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-12-50d5b3013664> in <module>
      1 state_machine = MyStateMachine()
----> 2 state_machine.transition12()

~/opt/anaconda3/envs/tf20/lib/python3.7/site-packages/statemachine/statemachine.py in __call__(self, *args, **kwargs)
     61 
     62     def __call__(self, *args, **kwargs):
---> 63         return self.func(*args, **kwargs)
     64 
     65 

~/opt/anaconda3/envs/tf20/lib/python3.7/site-packages/statemachine/statemachine.py in transition_callback(*args, **kwargs)
     89         def transition_callback(*args, **kwargs):
     90             print('!@#$ Transition.__get__.transition_callback', 'machine', machine, 'self', id(self))
---> 91             return self._run(machine, *args, **kwargs)
     92 
     93         return CallableInstance(self, func=transition_callback)

~/opt/anaconda3/envs/tf20/lib/python3.7/site-packages/statemachine/statemachine.py in _run(self, machine, *args, **kwargs)
    116 
    117     def _run(self, machine, *args, **kwargs):
--> 118         self._verify_can_run(machine)
    119         self._validate(*args, **kwargs)
    120         return machine._activate(self, *args, **kwargs)

~/opt/anaconda3/envs/tf20/lib/python3.7/site-packages/statemachine/statemachine.py in _verify_can_run(self, machine)
    110 
    111     def _verify_can_run(self, machine):
--> 112         transition = self._can_run(machine)
    113         if not transition:
    114             raise TransitionNotAllowed(self, machine.current_state)

~/opt/anaconda3/envs/tf20/lib/python3.7/site-packages/statemachine/statemachine.py in _can_run(self, machine)
    106 
    107     def _can_run(self, machine):
--> 108         if machine.current_state == self.source:
    109             return self
    110 

AttributeError: 'NoneType' object has no attribute 'current_state'

Here's a (partial) callstack showing when autoreload is invoking Transition._ _ get _ _() with a None machine parameter, eventually leading to an exception, next time the transition is invoked. Unfortunately I am not familiar enough with autoreload or your own code to understand what is the expected workflow...

347, in update_generic
    update(a, b)
  File "/Users/fred/opt/anaconda3/envs/tf20/lib/python3.7/site-packages/IPython/extensions/autoreload.py", line 287, in update_class
    old_obj = getattr(old, key)
  File "/Users/fred/opt/anaconda3/envs/tf20/lib/python3.7/site-packages/statemachine/statemachine.py", line 88, in __get__
    traceback.print_stack()
@fgmacedo
Copy link
Owner

Hi @xiao-fred, thanks for reporting this. Can you please provide a notebook and your requirements with exact versions, so I can try for myself?

I'm not familiar with autoreload but can try to find a fix.

@brunolnetto
Copy link

May I join the issue? I installed the library with !pip install statemachine and shift-entered from statemachine import StateMachine, State. However, the following log appeared:

NameError: name 'StateMachine' is not defined

Weird.

@brunolnetto
Copy link

brunolnetto commented Dec 28, 2022

@xiao-fred I run the following steps (OS Linux distribution Ubuntu 20.04):

  1. Create and Activate virtual environment: virtualenv .venv && source .venv/bin/activate;
  2. Install ipykernel to allow jupyter notebook usage of above virtual environment: pip install ipykernel;
  3. Make virtual kernel available: python -m ipykernel install --user --name .venv --display-name
  4. Checkout available kernelspec routes: jupyter kernelspec list;
  5. Open jupyter notebook session: jupyter notebook;
  6. Click on file sm_notebook.ipynb;
  7. Activate .venv kernel by:
    a. Click option Kernel on header-menu;
    b. Select option Change kernel > .venv.
  8. Perform the described workflow on this issue first post.

@fgmacedo
Copy link
Owner

fgmacedo commented Jan 4, 2023

Closing as stale. If you still need help please open a new issue.

@fgmacedo fgmacedo closed this as completed Jan 4, 2023
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

3 participants