ipython / ipython/ipython

Infinite recursion when autoreloading a generic class

Open
#11,619 4 comments 2 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
16.8k
Forks
4.5k
Avg merge
1d 2h
Merged PRs (30d)
6

Description

When using autoreload (`autoreload 2`) while a generic class is imported, it gives an error saying that autoreload failed due to exceeding maximum recursion depth. However, the class in question is still reloaded correctly.

The minimum working example is as follows. The code containing the generic class is stored in file `foo.py`:
```python
from typing import Generic, TypeVar

T = TypeVar('T')

class Foo(Generic[T]):
def __init__(self, x: T) -> None:
self.x = x
```

This is the IPython output. I have `%load_ext autoreload` and `%autoreload 2` stored in the startup script.
```
$ ipython
Python 3.6.3 (default, Mar 29 2018, 12:00:21)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.3.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from foo import Foo

In [2]: f = Foo[int](1)

In [3]: print(f.x)
1

In [4]: # at this point, change the __init__ code from 'self.x = x' to 'self.x = x * 2'
[autoreload of foo failed: Traceback (most recent call last):
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 244, in check
superreload(m, reload, self.old_objects)
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 394, in superreload
update_generic(old_obj, new_obj)
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 331, in update_generic
update(a, b)
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 289, in update_class
if update_generic(old_obj, new_obj): continue
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 331, in update_generic
update(a, b)
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 289, in update_class
if update_generic(old_obj, new_obj): continue
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 331, in update_generic
update(a, b)
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 289, in update_class
if update_generic(old_obj, new_obj): continue
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 331, in update_generic
update(a, b)
File "/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/extensions/autoreload.py", line 289, in update_class
if update_generic(old_obj, new_obj): continue
RecursionError: maximum recursion depth exceeded
]

In [5]: f = Foo[int](1)

In [6]: print(f.x)
2
```

My system information is as follows:
```
$ python -c "import IPython; print(IPython.sys_info())"
{'commit_hash': '2e1cca5bc',
'commit_source': 'installation',
'default_encoding': 'UTF-8',
'ipython_path': '/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython',
'ipython_version': '7.3.0',
'os_name': 'posix',
'platform': 'Darwin-18.2.0-x86_64-i386-64bit',
'sys_executable': '/Users/[redacted_user]/.pyenv/versions/3.6.3/Python.framework/Versions/3.6/bin/python',
'sys_platform': 'darwin',
'sys_version': '3.6.3 (default, Mar 29 2018, 12:00:21) \n'
'[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)]'}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.