Leahcim Leahcim - 3 months ago 10
Python Question

How to use the root package in an import?

Taking the Ansible project as an example, there is, inside the lib/ansible root directory, many other packages, like this

ansible/cli
/errors
/...many omitted for brevity
/utils
/vars
__init__.py


As an example, from
ansible/utils/vars.py
, the imports start at the root ansible/lib directory, such as

from ansible.errors import AnsibleError


and

from ansible.errors import AnsibleError


rather than

from errors import AnsibleError etc.


I have a demo project with a directory structure like this

beatles/george/harrison.py
/george/__init__.py
/john/lennon.py
/john/__init__.py
/ringo/starr.py
/ringo/__init__.py
/paul/mccartney.py
/paul/__init__.py
__init__.py (this __init__.py file is in the beatles dir)
helpers.py


So, using the Ansible example, I tried (in file
john/lennon.py
) to do

from beatles.george.harrison import Guitar

but I get an error `No module named beatles.george.harrison

However, the code works fine if I omit the
beatles
package (the equivalent of ansible in the ansible project)

from george.harrison import Guitar

How come, with my directory structure, I am not able to code the import as

from beatles.george.harrison import Guitar


from the beatles/john/lennon.py file? If possible, please explain with reference to the ansible project so it's clear why it works in one situation but not the other.

>>> from beatles.john.lennon import Guitar Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named beatles.john.lennon
>>> from john.lennon import Guitar >>> Guitar <class 'john.lennon.Guitar'>

wim wim
Answer

The difference here is that when you install ansible, it puts files into a subdirectory which is accessible from your sys.path. For example, it might go here:

/home/leahcim/.local/lib/python2.7/site-packages'

That's just a guess at the location. import ansible and check on ansible.__file__ for the actual location it ended up in (the exact location is dependent on several things).

Now, if you write a setup.py file, you could also get your app visible locally with:

python setup.py develop

If you don't want to write a working setup.py for your app just yet, then you will need to find some other way to make it visible in sys.path.

Specifically, the parent directory of your "beatles" directory should be contained in sys.path. One easy way to do that is to export it in the environment variable PYTHONPATH.

Comments