ipython icon indicating copy to clipboard operation
ipython copied to clipboard

deepreload fails to reload importlib on Python 3.13

Open cbarrick opened this issue 1 year ago • 1 comments

deepreload.reload fails to reload importlib and leaves the environment in an unstable state. In some circumstances, this crashes the process.

Here is a minimal reproduction and stack trace.
$ ipython -c 'import importlib; from IPython.lib.deepreload import reload; reload(importlib)'
Reloading _frozen_importlib
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File <frozen importlib._bootstrap>:866, in _exec(spec, module)

File <frozen importlib._bootstrap_external>:1022, in exec_module(self, module)

File <frozen importlib._bootstrap>:488, in _call_with_frames_removed(f, *args, **kwds)

File /opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/importlib/__init__.py:16
     15 try:
---> 16     import _frozen_importlib as _bootstrap
     17 except ImportError:

File ~/Desktop/optix/.venv/lib/python3.13/site-packages/IPython/lib/deepreload.py:230, in deep_import_hook(name, globals, locals, fromlist, level)
    228 parent, buf = get_parent(globals, level)
--> 230 head, name, buf = load_next(parent, None if level < 0 else parent, name, buf)
    232 tail = head

File ~/Desktop/optix/.venv/lib/python3.13/site-packages/IPython/lib/deepreload.py:149, in load_next(mod, altmod, name, buf)
    147 buf += subname
--> 149 result = import_submodule(mod, subname, buf)
    150 if result is None and mod != altmod:

File ~/Desktop/optix/.venv/lib/python3.13/site-packages/IPython/lib/deepreload.py:179, in import_submodule(mod, subname, fullname)
    178 if oldm is not None:
--> 179     m = importlib.reload(oldm)
    180 else:

File /opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/importlib/__init__.py:129, in reload(module)
    128     raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name)
--> 129 _bootstrap._exec(spec, module)
    130 # The module may have replaced itself in sys.modules!

File <frozen importlib._bootstrap>:848, in _exec(spec, module)

File <frozen importlib._bootstrap>:421, in __exit__(self, *args, **kwargs)

File <frozen importlib._bootstrap>:373, in release(self)

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

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
Cell In[1], line 1
----> 1 import importlib; from IPython.lib.deepreload import reload; reload(importlib)

File ~/Desktop/optix/.venv/lib/python3.13/site-packages/IPython/lib/deepreload.py:308, in reload(module, exclude)
    306 try:
    307     with replace_import_hook(deep_import_hook):
--> 308         return deep_reload_hook(module)
    309 finally:
    310     found_now = {}

File ~/Desktop/optix/.venv/lib/python3.13/site-packages/IPython/lib/deepreload.py:273, in deep_reload_hook(m)
    270     modules_reloading[name] = m
    272 try:
--> 273     newm = importlib.reload(m)
    274 except:
    275     sys.modules[name] = m

File /opt/homebrew/Cellar/[email protected]/3.13.0_1/Frameworks/Python.framework/Versions/3.13/lib/python3.13/importlib/__init__.py:129, in reload(module)
    127 if spec is None:
    128     raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name)
--> 129 _bootstrap._exec(spec, module)
    130 # The module may have replaced itself in sys.modules!
    131 return sys.modules[name]

File <frozen importlib._bootstrap>:848, in _exec(spec, module)

File <frozen importlib._bootstrap>:421, in __exit__(self, *args, **kwargs)

File <frozen importlib._bootstrap>:373, in release(self)

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

This seems to be choking while trying to reload a package called _frozen_importlib.

The error points to this line in importlib.

Notably, the deepreload.original_reload function can reload importlib just fine.

After trying to deep reload `importlib`, attempting to import new packages fails.
$ touch ./empty.py
$ ipython
Python 3.13.0 (main, Oct  7 2024, 05:02:14) [Clang 16.0.0 (clang-1600.0.26.3)]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.29.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from IPython.lib import deepreload

In [2]: import importlib

In [3]: deepreload.reload(importlib)
# Fails. Output elided for brevity. Same error as before.

In [4]: import empty
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[4], line 1
----> 1 import empty

File <frozen importlib._bootstrap>:1357, in _find_and_load(name, import_)

File <frozen importlib._bootstrap>:417, in __enter__(self)

File <frozen importlib._bootstrap>:456, in _get_module_lock(name)

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

This second error points to this line in importlib.

In my case, my package is not doing anything with importlib directly. I assume one of my dependencies is using it. In fact, when I try to deep reload my package, IPython crashes. I am not able to create a minimal reproduction of the crash though.

cbarrick avatar Nov 04 '24 02:11 cbarrick

I'm facing the same issue with Python 3.10. Is there any workaround?

When I run ipython -c 'import importlib; from IPython.lib.deepreload import reload; reload(importlib)', I get:

Output
Reloading _frozen_importlib
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File <frozen importlib._bootstrap>:619, in _exec(spec, module)

File <frozen importlib._bootstrap_external>:883, in exec_module(self, module)

File <frozen importlib._bootstrap>:241, in _call_with_frames_removed(f, *args, **kwds)

File /anaconda/envs/azureml_py310_sdkv2/lib/python3.10/importlib/__init__.py:16
     15 try:
---> 16     import _frozen_importlib as _bootstrap
     17 except ImportError:

File /anaconda/envs/azureml_py310_sdkv2/lib/python3.10/site-packages/IPython/lib/deepreload.py:230, in deep_import_hook(name, globals, locals, fromlist, level)
    228 parent, buf = get_parent(globals, level)
--> 230 head, name, buf = load_next(parent, None if level < 0 else parent, name, buf)
    232 tail = head

File /anaconda/envs/azureml_py310_sdkv2/lib/python3.10/site-packages/IPython/lib/deepreload.py:149, in load_next(mod, altmod, name, buf)
    147 buf += subname
--> 149 result = import_submodule(mod, subname, buf)
    150 if result is None and mod != altmod:

File /anaconda/envs/azureml_py310_sdkv2/lib/python3.10/site-packages/IPython/lib/deepreload.py:179, in import_submodule(mod, subname, fullname)
    178 if oldm is not None:
--> 179     m = importlib.reload(oldm)
    180 else:

File /anaconda/envs/azureml_py310_sdkv2/lib/python3.10/importlib/__init__.py:169, in reload(module)
    168     raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name)
--> 169 _bootstrap._exec(spec, module)
    170 # The module may have replaced itself in sys.modules!

File <frozen importlib._bootstrap>:601, in _exec(spec, module)

File <frozen importlib._bootstrap>:174, in __exit__(self, *args, **kwargs)

File <frozen importlib._bootstrap>:126, in release(self)

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

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
Cell In[1], line 1
----> 1 import importlib; from IPython.lib.deepreload import reload; reload(importlib)

File /anaconda/envs/azureml_py310_sdkv2/lib/python3.10/site-packages/IPython/lib/deepreload.py:308, in reload(module, exclude)
    306 try:
    307     with replace_import_hook(deep_import_hook):
--> 308         return deep_reload_hook(module)
    309 finally:
    310     found_now = {}

File /anaconda/envs/azureml_py310_sdkv2/lib/python3.10/site-packages/IPython/lib/deepreload.py:273, in deep_reload_hook(m)
    270     modules_reloading[name] = m
    272 try:
--> 273     newm = importlib.reload(m)
    274 except:
    275     sys.modules[name] = m

File /anaconda/envs/azureml_py310_sdkv2/lib/python3.10/importlib/__init__.py:169, in reload(module)
    167 if spec is None:
    168     raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name)
--> 169 _bootstrap._exec(spec, module)
    170 # The module may have replaced itself in sys.modules!
    171 return sys.modules[name]

File <frozen importlib._bootstrap>:601, in _exec(spec, module)

File <frozen importlib._bootstrap>:174, in __exit__(self, *args, **kwargs)

File <frozen importlib._bootstrap>:126, in release(self)

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

AwesomeLemon avatar Dec 23 '24 10:12 AwesomeLemon