When I developed the package exclusively for Python 2, I could use the simple import b syntax to import the relative path without worrying about whether the importing file was in the package or not. This had the advantage that I could run the if __name__ == "__main__": block if __name__ == "__main__": any file, just by executing the file, and all the imported files would work fine.
After adding Python 3 support, I had to move on to the new relative import syntax, which also supports 2.7: from . import b from . import b . However, this syntax only works inside packages. Direct file execution does not directly work:
Traceback (most recent call last): File "./a.py", line 2, in <module> from . import b ValueError: Attempted relative import in non-package
The workaround is to invoke the file by importing it as a module from the top directory:
python -m foo.a
However, this places the requirement in the working directory, which prevents you from transferring the output to another program that also takes care of the working directory.
Is there any way to get a cake and eat it? That is, they support both running as a script and importing as part of the package, working both in Python 2 and 3?
Example package structure:
foo/ foo/__init__.py foo/a.py (imports b) foo/b.py (imports c) foo/c.py
I would like both of them to work for x in (a, b, c):
import foo.x (in some file when foo/ is in path) python[23] path/to/foo/x.py
The comment below mentions setting __package__ according to PEP 366 , but "if the script moves to another package or subpackage, the template panel must be manually updated."
Update . I tried to execute the PEP 366 solution, but could not understand. It says:
The additional code that sys.path manages will be required for direct execution to work without the top-level package already being imported.
This is the case when executing a file from an unimported package. What does this additional code look like?