I have seen a lot of questions on this topic, but None seem to explain why this is happening or provide a solution I can use.
The following script gives 8 different outputs depending on where it's run from and I really don't understand why. I've managed to pin down a pattern but still don't understand why this occurs and it hasn't helped me solve the problem.
I have a file called
__init__.py
In the same directory as this file, I have a folder called "source_code". In that folder I have another file called
__init__.py
The
source_code/__init__.py
file contains one line of code which is:
print("source_code imported")
The first
__init__.py
file has the following script:
import sys
print(sys.executable)
print(sys.path[0])
try:
from . import source_code
except ImportError as ie:
print(ie)
try:
import source_code
except ImportError as ie:
print(ie)
I am using Spyder 4.1.5 as part of the Anaconda package, as well as Powershell on Windows 10. I have a virtual environment, created with conda, with only Jupyter notebook and spider installed.
The pattern I have found (as far as I can tell) is as follows:
- If I run the script through powershell, from outside the virtual environment, the output is as follows:
C:\Users\user\Desktop\Anaconda\python.exe
C:\Users\user\path\to\file
cannot import name 'source_code' from '__main__' (.\path\to\file\__init__.py)
source_code imported
- if I run through Powershell from inside the virtual environment, the output is:
C:\Users\user\Desktop\Anaconda\envs\venv\python.exe
C:\Users\user\path\to\file
attempted relative import with no known parent package
source_code imported
- if I open spyder, outside the virtual environment, and run the script by clicking into the editor and pressing "Control+Enter", the output is:
C:\Users\user\Desktop\Anaconda\python.exe
C:\Users\user\Desktop\Anaconda\python37.zip
cannot import name 'source_code' from '__main__' (C:\Users\user\path\to\file\__init__.py)
No module named 'source_code'
- If (still in spyder, outside the virtual environment) I click on the run button in the bar at the top, the output is:
C:\Users\user\Desktop\Anaconda\python.exe
C:\Users\user\Desktop\Anaconda\python37.zip
cannot import name 'source_code' from '__main__' (C:\Users\user\path\to\file\__init__.py)
source_code imported
- If I then click back into the editor and press "Control+Enter" again, the output is now:
C:\Users\user\Desktop\Anaconda\python.exe
C:\Users\user\Desktop\Anaconda\python37.zip
- If I run spyder from inside the virtual environment. Click into the editor and press "Control+Enter", the output is:
C:\Users\user\Desktop\Anaconda\envs\venv\python.exe
C:\Users\user\Desktop\Anaconda\envs\venv\python38.zip
attempted relative import with no known parent package
No module named 'source_code'
- Then click on the run button at the top, the output is:
C:\Users\user\Desktop\Anaconda\envs\venv\python.exe
C:\Users\user\Desktop\Anaconda\envs\venv\python38.zip
attempted relative import with no known parent package
source_code imported
- Then clicking back into the editor and pressing "Control+Enter" again gives:
C:\Users\user\Desktop\Anaconda\envs\venv\python.exe
C:\Users\user\Desktop\Anaconda\envs\venv\python38.zip
attempted relative import with no known parent package
I have tried including "a=8" in the "source_code/init.py" file and using "from .source_code import a" instead of "from . import source_code".
I have also tried including the lines:
from pathlib import Path as path
sys.path.insert(0, path(__file__).parent)
This changed the output from print(sys.path[0]), but made no difference to the output of the import statements.
I would like to understand the following:
1: Why does
Cannot import name "source_code" from "__main__."
change to
"attempted relative import with no known parent package."
when I move from outside to inside the virtual environment?
2: Why does running the script from Powershell, add the location of the file to the beginning of sys.path, but running it from spyder does not? (see the difference in line 2 between outputs 1 and 2 vs outputs 3 onwards.)
3: In Spyder, what is the difference between clicking into the editor and pressing "Control + Enter" and clicking the Run button.
4: Why can't spyder find the "source_code" module (located in the same directory as the script) when I press "Control + Enter" but it can once I have run it by clicking the run button? (see the difference between output 3 vs output 5, and output 6 vs output 8).
5a: Why (once I have run the script by clicking the run button) does pressing "Control + Enter" stop generating an ImportError but also does not run the script (i.e. it doesn't print "source_code imported" in output 5 and 8).
5b: Why does this behaviour change depending on whether I'm inside or outside the virtual environment. i.e. Why is line 3 different in outputs 4 and 5, but the same in outputs 7 and 8?
6: How do I get my script to consistently, successfully import the "source_code" module, regardless of where I run it from?