This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author KevKeating
Recipients KevKeating
Date 2020-11-05.22:14:23
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1604614463.81.0.853919807892.issue42273@roundup.psfhosted.org>
In-reply-to
Content
Steps to reproduce:

Create the following three files (or download the attached zip file, which contains these files):

main.py

    import foo
    from foo import a
    from foo import b

    print(foo.b.my_function())


foo/a.py

    import importlib.util
    import sys

    # implementation copied from https://github.com/python/cpython/blob/master/Doc/library/importlib.rst#implementing-lazy-imports
    def lazy_import(name):
        spec = importlib.util.find_spec(name)
        loader = importlib.util.LazyLoader(spec.loader)
        spec.loader = loader
        module = importlib.util.module_from_spec(spec)
        sys.modules[name] = module
        loader.exec_module(module)
        return module

    b = lazy_import("foo.b")


foo/b.py

    def my_function():
        return "my_function"

and then run main.py



Expected results

my_function should be printed to the terminal


Actual results

The following traceback is printed to the terminal

    Traceback (most recent call last):
      File "F:\Documents\lazy_import\main.py", line 6, in <module>
        print(foo.b.my_function())
    AttributeError: module 'foo' has no attribute 'b'

If you comment out "from foo import a" from main.py, then the traceback doesn't occur and my_function gets printed.  Alternatively, if you move "from foo import a" after "from foo import b", then the traceback doesn't occur and my_function gets printed.  Adding "foo.b = b" before "print(foo.b.my_function())" will also fix the traceback.


A colleague of mine originally ran into this bug when writing unit tests for lazily imported code, since mock.patch("foo.b.my_function") triggers the same AttributeError.  I've reproduced this on Windows using both Python 3.8.3 and Python 3.9.0, and my colleague was using Python 3.8.3 on Mac.
History
Date User Action Args
2020-11-05 22:14:23KevKeatingsetrecipients: + KevKeating
2020-11-05 22:14:23KevKeatingsetmessageid: <1604614463.81.0.853919807892.issue42273@roundup.psfhosted.org>
2020-11-05 22:14:23KevKeatinglinkissue42273 messages
2020-11-05 22:14:23KevKeatingcreate