In my little time tracking helper tool octodon I
ran into the problem that I wanted to import a global module of the same name as the
current module, and it was throwing an error. I had this in octodon/jira.py
:
from __future__ import absolute_import
from jira import JIRA
from jira import JIRAError
which got me the error
$ bin/python src/octodon/tests.py
[...]
ImportError: cannot import name 'JIRA' from 'jira' ([...]/src/octodon/jira.py)
It was obviously trying to import JIRA from octodon.jira, not from the global
jira package that I wanted to use. I was running Python 3, but even on Python 2
the absolute_import
should make sure this works. I straightened out the
namespace
declarations,
but still no luck.
Then I realized two things:
sys.path
hadsrc/octodon
as the first entry.- I only had the problem when running the tests, not the actual application.
When running bin/python src/octodon/tests.py
, my sys.path
looked like this:
(Pdb) sys.path
['[...]/src/octodon',
'/nix/store/z4y3q5nsm1hhk7g18ywpnsdgqcgsvc2i-python3-3.7.6/lib/python37.zip',
'/nix/store/z4y3q5nsm1hhk7g18ywpnsdgqcgsvc2i-python3-3.7.6/lib/python3.7',
'/nix/store/z4y3q5nsm1hhk7g18ywpnsdgqcgsvc2i-python3-3.7.6/lib/python3.7/lib-dynload',
'[...]/lib/python3.7/site-packages',
'[...]/src']
But when running bin/octodon
it looked like this instead:
(Pdb++) sys.path
['[...]/bin',
'/nix/store/z4y3q5nsm1hhk7g18ywpnsdgqcgsvc2i-python3-3.7.6/lib/python37.zip',
'/nix/store/z4y3q5nsm1hhk7g18ywpnsdgqcgsvc2i-python3-3.7.6/lib/python3.7',
'/nix/store/z4y3q5nsm1hhk7g18ywpnsdgqcgsvc2i-python3-3.7.6/lib/python3.7/lib-dynload',
'[...]/lib/python3.7/site-packages',
'[...]/src']
In the first case, the first entry was the directory that contained tests.py,
while in the second case it was the bin directory that I was calling the
application from. This reminded me of what I had read in a stackoverflow post
titled What does from __future__ import absolute_import
actually
do?:
When calling code by path (src/octodon/tests.py
) the directory containing the
file will be added to the path, but when running it as a module (-m
octodon.tests
) the current directory will be added instead. bin/octodon
was
generated from an entry-point and was doing it in the second way, which worked,
but my call to run the tests did it the first way, which always searched
src/octodon
for the jira module first, shadowing the global one.
So, when running bin/python -m octodon.tests
instead, it was suddenly working fine:
$ bin/python -m octodon.tests
[...]
OK (skipped=1)