Search code examples
pythonpython-venvc9.io

python importing file on virtual environment


I am writing a web app using python3, venv and c9.io PAAS. I have the following structure of my code:

batch_runner.py
logic/
    __init__.py
    parsers/
        __init__.py
        time_parser.py
        abstract_parser.py

here batch_runner imports abstract_parser, which, in it turn, import from time_parser. everything was installed and runs with venv activated.

To be specific, batch_runner.py contains:

from logic.parsers import abstract
from sys import argv

url = argv[1]
a = abstract(url)

logic/__init__.py is empty. logic/parsers/__init__.py contains:

from abstract_parser import abstract
from time_parser import _timeInfo

If I go to logic and run python abstract_parser.py directly, everything works as expected. However, if I go one level up, and run python batch_runner.py, it is able to import abstract_parser, but it can't find time_parser which is called from abstract_parser, throwing ImportError: No module named 'abstract'


Solution

  • Do read about importing from the python documentation on modules.

    In this case, one possible solution is to use relative imports inside your package:

    That is, in logic/parsers/__init__.py, use:

    from .abstract_parser import abstract
    from .time_parser import _timeInfo
    

    and in abstract_parser.py:

    from .time_parser import _timeInfo
    

    This should let parsers/__init__.py find the abstract_parser module and the time_parser module.

    The python import system has a surprising number of traps that you can fall into. This blog post by Nick Coghlan describes many of them, and I personally consider it a must-read if you're planning to develop a package.