Stewori / pytypes

Typing-toolbox for Python 3 _and_ 2.7 w.r.t. PEP 484.
Apache License 2.0
200 stars 20 forks source link

pytypes breaks @autoreload in a somewhat dangerous way #113

Open sg-s opened 2 years ago

sg-s commented 2 years ago

If I decorate a class method with @typechecked, it works, but breaks autoreload, generating this error:

[autoreload of pytypes.typechecker failed: Traceback (most recent call last):
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/site-packages/IPython/extensions/autoreload.py", line 245, in check
    superreload(m, reload, self.old_objects)
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/site-packages/IPython/extensions/autoreload.py", line 394, in superreload
    module = reload(module)
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/imp.py", line 314, in reload
    return importlib.reload(module)
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/importlib/__init__.py", line 148, in reload
    raise ImportError(msg.format(name), name=name)
ImportError: module MYCLASS not in sys.modules
]

where MYCLASS is the name of the class i'm working on

sg-s commented 2 years ago

perhaps related error:

just adding @typechecked to any class method breaks autoreload:

[autoreload of MYCLASS failed: Traceback (most recent call last):
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/site-packages/IPython/extensions/autoreload.py", line 245, in check
    superreload(m, reload, self.old_objects)
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/site-packages/IPython/extensions/autoreload.py", line 410, in superreload
    update_generic(old_obj, new_obj)
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/site-packages/IPython/extensions/autoreload.py", line 347, in update_generic
    update(a, b)
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/site-packages/IPython/extensions/autoreload.py", line 302, in update_class
    if update_generic(old_obj, new_obj): continue
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/site-packages/IPython/extensions/autoreload.py", line 347, in update_generic
    update(a, b)
  File "/Users/srinivas/opt/anaconda3/lib/python3.8/site-packages/IPython/extensions/autoreload.py", line 266, in update_function
    setattr(old, name, getattr(new, name))
ValueError: foo() requires a code object with 0 free vars, not 14
]
sg-s commented 2 years ago

what's worse, it PERMANENTLY breaks autoreload. no new changes are ever seen. the only way to fix this is to restart the kernel

sg-s commented 2 years ago

did some further digging -- this also breaks autoreload with functions, but entirely silently! if you decorate a function with @typechecked, then autoreload will fail, but with no warning or error. it keeps using old versions of your function.

Stewori commented 2 years ago

Hey, I don't have time or energy to look into autoreload or IPython internals. However, if you can tell me the root cause of this issue I would fix it. At least if it is feasible with reasonable effort. Things you can try to narrow it down:

The mentioned functions check_argument_types, check_return_type are probably a good way to work around this issue. They are intended for all sorts of cases where the decorator interferes with some other module that does hackish things like monkeypatching. Also the profiler mode may be a possible workaround.

sg-s commented 2 years ago

hi @Stewori fair enough, i will do so and report back. thank you!

sg-s commented 2 years ago

hi @Stewori i looked at typeguard's @typechecked and it has the same behavior which breaks autoreload. sounds like this is an autoreload issue -- i'll see if I can take it up with them

Stewori commented 2 years ago

Another thing to try is to check whether the order of decorators makes a difference. Since typeguard is affected similarly, it is worth a try to ask @agronholm whether he happens to know the cause.

agronholm commented 2 years ago

I too don't have the capacity to research this, but once the root cause is understood and pytypes/typeguard found to do something wrong, I will of course fix typeguard if possible.