I have a Python 2 Pyramid App that is setup using buildout
and a project folder activated using Mr.Developer
; I am trying to futurize
this project as part of Python 3 migration which changes:
import test
to:
from __future__ import absolute_import
from . import test
However for some reason ./bin/pserve development.ini
doesn't come up, it says:
...
File "/apps/src/project/engine/config.py", line 3, in <module>
import utilities
File "/apps/src/project/engine/utilities.py", line 9, in <module>
from project.engine import spreadsheets
File "/apps/src/project/engine/spreadsheets.py", line 16, in <module>
from project.engine import utilities
ImportError: cannot import name utilities
It is a proper package as far as I am aware because it does have a setup.py
and I ran develop activate project
+ buildout
again.
If I type print(__package__)
in that code it prints fine, but if I add a line from __future__ import absolute_import
it prints None
. Is it possible that future
's absolute_import
can simply clears out the __package__
variable and that is why it is not detecting this as a package?
This is the MWE of the real issue: Why does this circular import fail in Python 2 but not in Python 3?, it seems to be a bug in Python 2 when there is circular import. If anyone has a clean solution please let me know.
When __package__
is set to None
, that's just a flag value for not yet set. It is not a problem.
From PEP 366 – Main module explicit relative imports, on the subject of __package__
:
When the import system encounters an explicit relative import in a module without
__package__
set (or with it set toNone
), it will calculate and store the correct value (__name__.rpartition('.')[0]
for normal modules and__name__
for package initialisation modules). If__package__
has already been set then the import system will use it in preference to recalculating the package name from the__name__
and__path__
attributes.
If you see this set to None
in the main module and it was meant to be part of a package, then set it yourself:
if __name__ == "__main__" and __package__ is None:
__package__ = "foo.bar.baz"