I am having a problem running my script in a cmd prompt despite it working in PyCharm. I have a folder structure as such:
MyCode # PyCharm project folder
/UsefulFunctions
/Messaging
/Texter.py
/DiscordBot
/DiscordBot.py
Within DiscordBot.py I have an import
from UsefulFunctions.Messaging import Texter
This works when I run it from PyCharm without a problem. However when I try to run from a command prompt located at the DiscordBot
level it errors with:
ImportError: No module named 'UsefulFunctions'
So naturally I thought it meant that the UsefulFunctions
folder was not on my path. Therefore, I went into my environment variables and added it to my PATH
variable (as well as the MyCode
folder for good measure). Still it encountered this error. I browsed some posts on here regarding imports (mainly Importing files from different folder) and they recommend doing something like:
import sys
sys.path.insert(0, '/path/to/application/app/folder')
import file
Or adding __init__.py
files to each folder in order to get them to register as packages. I went ahead and added __init__
files to each folder and subfolder I was trying to import from, but still could not run from the command prompt...I ommitted the sys.path.insert()
solution because I see no benefit from this after already explicitly adding it to my PATH
variable. Another solution was to add "." before the import because supposedly otherwise it is only searching python's PATH. I attempted this as:
from .UsefulFunctions.Messaging import Texter
ImportError: attempted relative import with no known parent package
And this error shows on PyCharm now as well... I don't get why my initial script would work without a hitch on PyCharm, but the same program cannot seem to find my import when run from a prompt. Can somebody please explain the difference between PyCharm running the program and my prompt? Why will this not work despite having __init__.py
files and having added MyCode
and UsefulFunctions
to my PATH variable on Windows?
From [Python 3.Docs]: Command line and environment - PYTHONPATH:
Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored.
You can also find more details on [SO]: Strange error while using Pycharm to debug PyQt gui (@CristiFati's answer).
So, in order for Python to be able to load a module (package) without specifying its path, the path must be present in %PYTHONPATH% environment variable.
You mentioned %PATH% several times in the question but it's %PYTHONPATH% (MyCode must be added to it).
PyCharm does that because of (any of) the 2 checkboxes in the image below:
If you want to get things working from cmdline, yo have to do the same thing there as well:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q054955891\DiscordBot]> sopr.bat *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [prompt]> set py Environment variable py not defined [prompt]> "e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" DiscordBot.py Traceback (most recent call last): File "DiscordBot.py", line 1, in <module> from UsefulFunctions.Messaging import Texter ModuleNotFoundError: No module named 'UsefulFunctions' [prompt]> set PYTHONPATH=e:\Work\Dev\StackOverflow\q054955891 [prompt]> set py PYTHONPATH=e:\Work\Dev\StackOverflow\q054955891 [prompt]> "e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" DiscordBot.py e:\Work\Dev\StackOverflow\q054955891\UsefulFunctions\Messaging\Texter.py imported
As a side note, I personally hate names that start with My (e.g. MyCode). Try finding a more useful name (e.g. TestBotProject, or smth similar) :).
Python uses the system variable PYTHONPATH
, among other things, to decide what to import.
From the docs:
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:
- The directory containing the input script (or the current directory when no file is specified).
- PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
- The installation-dependent default.
The reason PyCharm magically imports the module when you run the script is because of the Project Structure -> Content Root
value. It points to your project directory, by default.
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