pytypes icon indicating copy to clipboard operation
pytypes copied to clipboard

pytypes breaks @autoreload in a somewhat dangerous way

Open sg-s opened this issue 2 years ago • 8 comments

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 avatar Dec 22 '21 20:12 sg-s

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 avatar Dec 22 '21 20:12 sg-s

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 avatar Dec 22 '21 20:12 sg-s

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.

sg-s avatar Dec 22 '21 21:12 sg-s

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:

  • Is this specific to pytypes' decorator or are other decorators affected as well? E.g. try typeguard's typechecked decorator please
  • instead of using the decorator, call check_argument_types and check_return_type inside a method/function body. Does this work around the issue?
  • ask the autoreload devs whether they know the cause; there are a number of caveats already listed. Maybe interference with certain decorators is just another caveat not yet on the list...?

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.

Stewori avatar Dec 23 '21 18:12 Stewori

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

sg-s avatar Dec 24 '21 16:12 sg-s

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

sg-s avatar Jan 05 '22 18:01 sg-s

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.

Stewori avatar Jan 05 '22 18:01 Stewori

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.

agronholm avatar Jan 05 '22 18:01 agronholm