failed import in py2 succeeds in py3 (but actually not)

Issue #16 open
Alexandre Vincent
created an issue

In some situations, an import mypkg in python2 can trigger a ImportError, and in python3 no error...

I would think this case is quite common...

A package with the following structure (P being any path): - P/myrepopkg - P/myrepopkg/src - P/myrepopkg/src/myrepopkg

Note how the package and the repository clone have the same name. Having P/myrepopkg in sys path, and attempting to import myrepopkg would trigger an ImportError in python2, but a namespace package would be successfully created in python3, and python3 would likely fail later when attempting to use something inside the module, with an unhelpful error message...

Having P/myrepopkg/src/myrepopkg in sys path solves the import problem (for both py2 and py3)

I stumbled on that recently, and it took me some time to figure out why my except ImportError wasn't triggering with python3 when it should have...

Comments (4)

  1. Nick Coghlan repo owner

    Am I right in thinking this is a suggestion for an "Unexpected Namespace Package" trap in http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html?

    It seems like a reasonable addition to me, although the conditions for triggering it aren't quite as described (since having "P/myrepopkg/" as in entry in sys.path would give you an import error regardless of Python version).

    Instead, the problem arises when P (the parent directory of the version control directory) is one of the entries in sys.path, while the intended entry was "P/myrepopkg/src/".

    Regardless of the details, the outcome is as you describe: instead of getting an early ImportError when sys.path is misconfigured, you may instead get an unexpected namespace package, and that does indeed qualify as a potential import trap.

  2. Alexandre Vincent reporter

    Yes my intention was to suggest another import trap that I recently got caught in.

    I am currently writing a custom importer with pycharm, so it s very possible that I experiencd also some side effects from that...

    Testing again with a clean environment, I got that :

    alexv@alexv-pc:~/Projects/failingns$ tree
    .
    └── nspkg
        └── src
            └── nspkg
                └── pkg
                    ├── __init__.py
                    └── __pycache__
                        └── __init__.cpython-35.pyc
    
    5 directories, 2 files
    alexv@alexv-pc:~/Projects/failingns$ python2 -c "import nspkg.pkg; print(nspkg.pkg.a)"
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    ImportError: No module named nspkg.pkg
    alexv@alexv-pc:~/Projects/failingns$ python3 -c "import nspkg.pkg; print(nspkg.pkg.a)"
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    ImportError: No module named 'nspkg.pkg'
    alexv@alexv-pc:~/Projects/failingns$ python2 -c "import nspkg; print(nspkg.pkg)"
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    ImportError: No module named nspkg
    alexv@alexv-pc:~/Projects/failingns$ python3 -c "import nspkg; print(nspkg.pkg)"
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    AttributeError: module 'nspkg' has no attribute 'pkg'
    alexv@alexv-pc:~/Projects/failingns$ cd nspkg/src/
    alexv@alexv-pc:~/Projects/failingns/nspkg/src$ python2 -c "import nspkg.pkg; print(nspkg.pkg.a)"
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    ImportError: No module named nspkg.pkg
    alexv@alexv-pc:~/Projects/failingns/nspkg/src$ python3 -c "import nspkg.pkg; print(nspkg.pkg.a)"
    42
    

    The case that surprised me was python2 failing with import error and python3 with attribute error.

  3. Log in to comment