The same import statement from mypackage._aux import is_error
has two different meanings in similar files:
In _aux/foobar/_foobar.py
it imports the function is_error
from _aux/is_error/_is_error.py
.
But in _aux/abbrev_testing/_abbrev_testing.py
it imports the whole module _aux/is_error
instead.
The first is the expected behavior, because _aux/__init__.py
contains from .is_error._is_error import is_error
. (format from .folder.file import function
)
When I run pytest
, the two tests in _abbrev_testing_test.py
fail, because is_error
is not the expected function. (TypeError: 'module' object is not callable
)
It works when I use the line that I would like to abbreviate with the new function:
This includes the test in
_foobar_test.py
- so in _foobar.py
the function was imported.
But in _abbrev_testing.py
the module was imported:
Does someone understand the difference between the two files? Should I have done this in a different way?
I would love to know if there is some logical rule that would have avoided this. (To me this just looks absurd and erratic.)
Edit: In both files it works, when I use a long import statement not relying on _aux/__init__.py
:
short: from mypackage._aux import is_error
(format from _aux import function
)
long: from mypackage._aux.is_error._is_error import is_error
(format from _aux.folder.file import function
)
This question can be summarized as:
What in _abbrev_testing.py
is sabotaging the __init__.py
?
Edit 2: Steps to reproduce:
me@ubuntu:~$ git clone https://github.com/watchduck/module_object_is_not_callable.git
me@ubuntu:~$ cd module_object_is_not_callable/
me@ubuntu:~/module_object_is_not_callable$ virtualenv -p python3 env
Open project with IDE.
(env) me@ubuntu:~/module_object_is_not_callable$ pip install pytest
(env) me@ubuntu:~/module_object_is_not_callable$ pytest
What in _abbrev_testing.py is sabotaging the init.py?
Gotcha - if you change:
from .is_error._is_error import is_error
from .abbrev_testing._abbrev_testing import abbrev_testing
from .foobar._foobar import foobar
in your init problem goes away. You were:
from .abbrev_testing._abbrev_testing import abbrev_testing
from .is_error._is_error import is_error
setting the is_error to the function "is_error" only after you imported .abbrev_testing._abbrev_testing - where the is_error is (correctly) already been imported as a module.
Should I have done this in a different way?
Certainly. Do not name functions the same name as modules/packages. They are different things, so should have different names. Also - avoid similar repetitive names, and leading underscores. Makes code very difficult to read (so I opened many times the _abbrev_testing_errors.py cause it looked very similar to _abbrev_testing.py or _abbrev_testing_test.py) - reserve "test" for tests. I say this in all seriousness - python's import system is complex but the complexity is due, cause it's a complex problem. Correct naming makes this complexity manageable.