2

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'

Praveen
  • 6,872
  • 3
  • 43
  • 62
Philipp_Kats
  • 3,872
  • 3
  • 27
  • 44
  • 1
    Please add what file imports what, and the exact import statements you're using. Are you using `from logic import abstract_parser`? How are you trying to import `time_parser`? What does the `__init__.py` file contain? – Praveen Sep 02 '16 at 00:40
  • thanks. Added all the information on importing – Philipp_Kats Sep 02 '16 at 01:41

2 Answers2

3

Change this:

from abstract_parser import abstract

To

from logic.parsers.abstract_parser import abstract
Windsooon
  • 6,864
  • 4
  • 31
  • 50
  • If you're using this solution, you can leave `parsers/__init__.py` empty, and use `from logic.parsers import abstract_parser as ap` followed by `ap.abstract( ... )` when you call, for instance. This is particularly useful when there are plenty of names under abstract_parser that you need to import. – Praveen Sep 02 '16 at 02:24
2

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.

Praveen
  • 6,872
  • 3
  • 43
  • 62