3

When I try to run a python file with python3.6 src/main.py (the working directory is one above src) there's this error when importing another module from path src:

from src import another_module

ModuleNotFoundError: No module named 'src'

When I do

print(os.getcwd())
print(os.listdir(os.getcwd()))

I get what's expected:

path/to/working/directory

['src']

The import works when I run the script with PyCharm, but I need to run it outside PyCharm.

Raphael
  • 1,518
  • 2
  • 14
  • 27

4 Answers4

1

When you run a python script on the command line, the script's directory (which may not be the same as your shell current working directory) is added to the path.

So, since src/ is already in your path, you can just say import another_module.

John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • Interesting, but then it doesn't work in PyCharm anymore (since the working directory is properly set on PyCharm; the working directory is *not* 'src'). Is there a way to make it work in both? – Raphael Jan 06 '20 at 20:23
1

To make src a package, make an empty file named src/__init__.py

nicolas
  • 3,120
  • 2
  • 15
  • 17
  • 1
    `__init__.py` is not required in Python 3. – John Gordon Jan 06 '20 at 20:16
  • I still got the same error: `print(os.getcwd()) print(os.listdir(os.getcwd())) print(os.listdir('src')) from src import my_module path/to/working/directory` >['src'] >['__pycache__', 'my_module.py', '__init__.py'] > >Traceback (most recent call last): > File "src/main.py", line 12, in > from src import time_functions as time >ModuleNotFoundError: No module named 'src' – Raphael Jan 06 '20 at 20:21
  • The doc for [Packages](https://docs.python.org/3/tutorial/modules.html) shows how the directory structure should look like. And `__init__.py` is still required for python3. – nicolas Jan 06 '20 at 20:22
  • @Raphael: where are you executing those python statements from? A file in your top directory? – nicolas Jan 06 '20 at 20:25
  • My mistake; I overlooked that you were making `src` a _package_, and not just an _importable module_. – John Gordon Jan 06 '20 at 20:26
  • @JohnGordon: Regarding implicit `__init__.py` in python3, you are right according to [this question](https://stackoverflow.com/questions/37139786/is-init-py-not-required-for-packages-in-python-3-3). – nicolas Jan 06 '20 at 21:29
1

Solved by creating another file run.py in the working directory that calls src/main.py and running run.py from the command line instead of src/main.py.

Raphael
  • 1,518
  • 2
  • 14
  • 27
-1

In launch.json, add the following line to your deployment:

"env": {"PYTHONPATH": "${workspaceRoot}"}

This seems to force Python to evaluate imports relative to the ${workingSpaceRoot} folder; allowing you to use a fully qualified name: from src import ...

The default behavior is to evaluate namespaces relatively. So, your original statement: from src import ... is actually looking in src/src/....

(Credit to @g4th who posted this solution on another StackOverflow page.)

Eric McLachlan
  • 3,132
  • 2
  • 25
  • 37