I'm developing a Python library on Python 3.8.2 and I would like to run a module as main for testing purposes. When I try, I get a ModuleNotFound error.
Here's my library structure:
.
├── foo
│ ├── __init__.py
│ ├── bar.py
│ └── quux
│ ├── __init__.py
│ ├── corge.py
│ └── garply.py
├── main.py
bary.py:
def baz():
print("baz")
corge.py
from foo.quux.garply import *
def grault():
waldo()
print("grault")
if __name__ == '__main__':
grault()
garply.py
def waldo():
print("waldo")
main.py
from foo.bar import *
from foo.quux.corge import *
if __name__ == '__main__':
baz()
grault()
(All __init__.py
files are empty)
When I run main.py
, it works.
$ python main.py
baz
waldo
grault
If I try to run corge.py
, I get the following error:
$ python foo/quux/corge.py
Traceback (most recent call last):
File "foo/quux/corge.py", line 1, in <module>
from foo.quux.garply import *
ModuleNotFoundError: No module named 'foo'
It doesn't matter what my current working directory is, it always gives this error.
$ cd foo/quux/
$ python corge.py
Traceback (most recent call last):
File "corge.py", line 1, in <module>
from foo.quux.garply import *
ModuleNotFoundError: No module named 'foo'
While I was testing this, I created a new PyCharm project with PyCharm 2020.1 and implemented the structure I described. To my surprise, it works with with the default detected run configuration.
I tried using the venv that PyCharm automatically creates, but it still did not work. It does not work if I directly copy/paste the command and use their CWD. It does not work with the terminal built into PyCharm. It only works with the PyCharm Run button.
Am I doing something wrong with my module structure? If so, what could PyCharm be doing to make this work? If not, why does it not work outside of PyCharm?