scientific-python/lazy-loader

Unbound Local Variable: parent deleted without ensuring it got created first

scnerd opened this issue · 2 comments

Problem

I get the following stacktrace from librosa's usage of lazy_loader:

  File "C:\...\lib\site-packages\datasets\features\audio.py", line 194, in decode_example
    array = librosa.to_mono(array)
  File "C:\...\lib\site-packages\lazy_loader\__init__.py", line 78, in __getattr__
    attr = getattr(submod, name)
  File "C:\...\lib\site-packages\lazy_loader\__init__.py", line 77, in __getattr__
    submod = importlib.import_module(submod_path)
  File "C:\...\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "C:\.\lib\site-packages\librosa\core\audio.py", line 31, in <module>
    samplerate = lazy.load("samplerate")
  File "C:\...\lib\site-packages\lazy_loader\__init__.py", line 203, in load
    del parent
UnboundLocalError: local variable 'parent' referenced before assignment

Here's the offending code block:

            try:
                parent = inspect.stack()[1]
                frame_data = {
                    "spec": fullname,
                    "filename": parent.filename,
                    "lineno": parent.lineno,
                    "function": parent.function,
                    "code_context": parent.code_context,
                }
                return DelayedImportErrorModule(frame_data, "DelayedImportErrorModule")
            finally:
                del parent

Environment

Python version: 3.10
lazy_loader version: 0.3

Solution

The assignment to parent should occur before the try block. Errors with the inspect.stack()[1] chunk should be handled in a separate try/except clause.

@scnerd Thanks for the report; could you verify whether this was addressed by #83

We have resolved two race conditions, and these fixes will be available in the next release of lazy_loader & Python.