I am making a package, and the modules within this package have code inside if __name__=='__main__':
blocks for testing purposes. But my attempts to use relative imports in these modules causes errors.
I have read this thread and the billion others: Relative imports for the billionth time
Before you mark this as a duplicate, if what I want to do is not possible in Python3 then my question is why did it work in Python2 and what motivated the decision to make this such a hassle in Python3?
This is my sample Python project:
mypackage
- module1.py
- module2.py
- __init__.py
__init__.py
and module2.py
are empty
module1.py
contains:
import module2
# module1 contents
if __name__=="__main__":
# Some test cases for the contents of this module
pass
This works fine in Python2. I am able to import module1 from other projects anywhere on my computer, and I'm also able to run module1 directly and have the code in the if
block run.
However, this structure doesn't work in Python3. If I try import the module somewhere else it fails:
>>> from mypackage import module1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\_MyFiles\Programming\Python Modules\mypackage\module1.py", line 1, in <module>
import module2
ModuleNotFoundError: No module named 'module2'
So I tried changing the first line to from . import module2
, and that fixed it so I could import the module from anywhere successfully. But then when I try running module1 directly as a script I get this error:
Traceback (most recent call last):
File "C:/_MyFiles/Programming/Python Modules/mypackage/module1.py", line 1, in <module>
from . import module2
ImportError: cannot import name 'module2' from '__main__' (C:/_MyFiles/Programming/Python Projects/pgui/mypackage/module1.py)
I don't want to have to open a console and type python -m myfile
every time I'm working on a module and want to run it directly as a script.
I want to be able to work on modules without adding their parent folder to PYTHONPATH by using relative imports like in Python2
Is there any better workaround or solution to these problems?
According to the Module documentation, for __main__
modules, you have to use absolute imports.
Note that relative imports are based on the name of the current module. Since the name of the main module is always "main", modules intended for use as the main module of a Python application must always use absolute imports.
So just change the import line in module1.py
to:
from mypackage import module2
Everything else remains the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With