Infinite recursion when autoreloading a generic class
- 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
Assessment
This issue has not been assessed yet.