ModuleNotFoundError error with PyCharm project folder recs - python

I am working on a project in PyCharm. The project has the following structure:
/projectRoot/
folder1/
somecode.py
utils/
__init__.py
myutils1.py
I'd want to know how I can do an import such that the import works when running the code in the pyCharm console in an interactive manner, as well as when running the code using the
python somecode.py
command in the terminal.
Currently I do:
from utils.myutils1.py import myClass
But command line I get the error:
File "somecode.py", line 10, in
from utils.myutils1 import myClass ModuleNotFoundError: No module named 'utils'
and on PyCharm:
Traceback (most recent call last): File
"/home/ubuntu/anaconda3/lib/python3.6/site-packages/IPython/core/interactiveshell.py",
line 2881, in run_code
exec(code_obj, self.user_global_ns, self.user_ns) File "", line 1, in
from utils.myutils1 import myClass ModuleNotFoundError: No module named 'utils'
Any recommendations on the proper folder structure for modules within a project, and how to import them properly?
Thanks!

To explain the answer I recreated that project structure you had
/projectRoot/
folder1/
somecode.py
utils/
__init__.py
myutils1.py
somecode.py
from utils.myutils1 import myclass
if __name__ == "__main__":
print(myclass)
myutils1.py
myclass="tarun"
Running them from pycharm works without any issues, but running them from terminal will produce below error
File "somecode.py", line XX, in <module>
from utils.myutils1 import myclass
ModuleNotFoundError: No module named 'utils'
The issue is that Pycharm does few things for you because which you don't realize why it is not working in the terminal. So before telling you what you need to, I will tell you two things that PyCharm does on its own.
Python Console
When you launch a Python Console from Pycharm, there is some code that gets executed, using preferences.
As you can see there are two options
[X] Add content roots to PYTHONPATH
[ ] Add source roots to PYTHONPATH
And then a starting script as well. So what this does is that it adds the root of your project to python's path. Which is controlled by two main ways sys.path and PYTHONPATH environment variable
If I run the below code in Python Console
>>> import sys
>>> sys.path
['/Applications/PyCharm.app/Contents/helpers/pydev',
'/Applications/PyCharm.app/Contents/helpers/pydev',
'/Users/tarun.lalwani/.virtualenvs/folderstructure27/lib/python27.zip',
'/Users/tarun.lalwani/.virtualenvs/folderstructure27/lib/python2.7', ....
'/Users/tarun.lalwani/.virtualenvs/folderstructure27/lib/python2.7/site-packages',
'/Users/tarun.lalwani/Desktop/payu/projects/folderstructure27']
As you can see '/Users/tarun.lalwani/Desktop/payu/projects/folderstructure27' is added to the Python terminal.
Python Configurations
When you configure to RUN in code using Pycharm, you have similar two options.
We can change the code of our somecode.py to below
import os
print (os.environ['PYTHONPATH'])
import sys
print (sys.path)
/Users/tarun.lalwani/Desktop/payu/projects/folderstructure27
['/Users/tarun.lalwani/Desktop/payu/projects/folderstructure27/folder1',
'/Users/tarun.lalwani/Desktop/payu/projects/folderstructure27', ....,
'/Users/tarun.lalwani/.virtualenvs/folderstructure27/lib/python2.7/site-packages']
From the output we can see that PYTHONPATH is set to current project folder.
Running from terminal
Now let's run the somecode.py from terminal with the modifications we made.
$ python somecode.py
Traceback (most recent call last):
File "somecode.py", line 2, in <module>
print (os.environ['PYTHONPATH'])
File "/Users/tarun.lalwani/.virtualenvs/folderstructure27/bin/../lib/python2.7/UserDict.py", line 40, in __getitem__
raise KeyError(key)
KeyError: 'PYTHONPATH'
So that indicates there is no PYTHONPATH when we ran it in terminal. Let us run it again by removing the print(os.environ['PYTHONPATH']) code. You will get the below output
['/Users/tarun.lalwani/Desktop/payu/projects/folderstructure27/folder1', ...
'/Users/tarun.lalwani/.virtualenvs/folderstructure27/lib/python2.7/site-packages']
Traceback (most recent call last):
File "somecode.py", line 7, in <module>
from utils.myutils1 import myclass
ImportError: No module named utils.myutils1
As you can see folder1 is added to sys.path because it is the folder containing somecode.py, but the root folder has not been added. The fix in terminal is simple, which is to set the root directory path in PYTHONPATH.
PYTHONPATH=`pwd`/.. python somcode.py
And now the code will work from terminal also.
But the way they work are different from Python Console.
IMPORTANT NOTE:
Python Console using PyCharm on remote interpreter.
If running the python console using the remote interpreter option pycharm will fail. This is because it will append the path of the local PC and not the path of the remote server.
In order to fix this problem one has to add a mapping between the local PC directory and the remote server path.

You can use utils package inside folder1 folder:
Then the code will work either way:
from utils.myutils1 import myClass

Similar error here and this appears to be working for me:
Make sure Project Interpreter is set to, for example: C:\Python36\python.exe (in my case) and not a copy somewhere or another.
'File > Settings > Project ____ > Project Interpreter'
Or, long story short, if that route isn't cooperating, can also try finding workspace.xml and manually change SDK_HOME before starting PyCharm:
<option name="SDK_HOME" value="C:\Python36\python.exe" />

Related

Imported module cannot be found when Python script is run via a bat file

I know there has been similar problems, but unfortunately most of them are related to errors with pyperclip itself instead of the batch file, which i suspect is where the problem stems from.
Below is an MRE of my Python script:
#! python3 -> Do I have to use my version(3.8)?
# pw.py - An insecure password locker program.
import sys, pyperclip
#do something with the module
And my batch file pw.bat:
#py.exe C:\Users\KEVIN\PycharmProjects\atbs_exercise\pw.py %*
#pause
I am running python 3.8 on windows 10. I imported the pyperclip module in my python script pw.py and ran the file via pw.bat, and this in turn gives me this error:
Traceback (most recent call last):
File "C:\Users\KEVIN\PycharmProjects\atbs_exercise\pw.py", line 7, in <module>
import sys, pyperclip
ModuleNotFoundError: No module named 'pyperclip'
Press any key to continue . . .
Which shouldn't happen as I have installed pyperclip on the project using pip, and the script itself runs just fine in pycharm. What am I missing?
EDIT: I forgot to mention that I am using pycharm. So the thing is that pycharm had also installed python.exe in the project folder. And as the module pyperclip is only installed to that folder, the python.exe used in the bat must point to the one in the project folder.
i don't know why are you using py.exe. when running commands from a batch file or cmd .you should use python.exe.obviously you would need to add python to add for doing so.instead of adding py.exe to path,add python in system variable Path which is somewhere present in C:\Users\[username]\AppData\Local\Programs\Python\(your path might be diffrernt).you can add python in Path by following this post
after adding python to path just use the following batch-file:
#echo off
python path-to-your-py-file\filename.py

Why does python only correctly import if I'm using -m flag?

I'm currently very confused on how imports in python work exactly. Basically, I'm confused why starting a script as a module (with -m) changes the behaviour:
I have a two scripts in a folder Called Testing. One named Programm.py, the other named Test_Programm.py.
The first line in Test_Programm.py is: from Testing.Programm import my_function
Running Test_Programm.py from the parent folder of Testing with the command line python -m Testing. Test_Programm works as expected, it imports everything as expected. Running it from within the Testing folder with python -m Test_Programm doesn't get the import. Running it from the parent folder as python Testing\Test_Programm.py doesn't work. It also dosen't work when running inside the Testing folder with python Test_Programm.py.
So why is this, how does python look for modules?
All testing was done using Python 3.8.0
Stack Traces:
python Testing\Test_Programm.py in the parent folder:
Traceback (most recent call last):
File "Testing\Test_Programm.py", line 8, in <module>
from Testing.Test_Programm import my_function
ModuleNotFoundError: No module named 'Testing'
python Test_Programm.py in the Testing folder:
Traceback (most recent call last):
File "Test_Programm.py", line 8, in <module>
from Test_Programm import my_function
ModuleNotFoundError: No module named 'Testing'
python -m Test_Programm.py in the Testing folder:
Traceback (most recent call last):
File "C:\Python38\lib\runpy.py", line 192, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Python38\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\<username>\PycharmProjects\TestingTesting\src\Testing\Test_Programm.py", line 8, in <module>
from Testing.Test_Programm import my_function
ModuleNotFoundError: No module named 'Testing'
Per the sys.path documentation:
As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first.
And per the Python command-line documentation:
When called with -m module-name, the given module is located on the Python module path and executed as a script.
An implication of that second quote is that the -m invocation method is not "running a script" in the sense sys.path describes it, because it has to set up sys.path first, then look for the module to execute, so it can't be making path[0] match the script directory (sys.path is generally not programmatically modified by Python itself after initial setup by the interpreter, followed by the site module).
Between the two of them, this answers your question. Since your directories are not part of the "always on" sys.path, you're relying on the implicit behavior for the first entry in sys.path.
The cases are:
Running python3 Testing/Test_Programm.py: sys.path[0] is Testing/, so when you import from Testing.Programm, it can't find any entry in sys.path with a Testing subdirectory and it gives up (same goes for python3 Test_Programm.py; no Testing within the script's folder)
Running python3 -mTest_Programm from the same directory also doesn't work; sys.path[0] is searching the current directory first, and again, there is no Testing subdirectory
python3 -mTesting.Test_Programm works because it's looking up the module to run, not directly executing the script, so path[0] remains the working directory, which does have a Testing subdirectory. It finds it, finds Test_Programm.py inside it, and when it runs, it still roots searches below Testing so imports from Testing.Programm work.

Custom modules not read by Python, generating ImportError

I am trying to run a python pipeline through Mac OS Terminal. I am using Python 2.7.15 because newer versions of Python gave me error messages with this file. I keep getting the following error message:
$ python ../../../scripts/gemmaPipeline.py ../../../data/all.fixGL.Q10.ap.bi.MAF5.vcf.gz outfile Results
Traceback (most recent call last): File
"../../../scripts/gemmaPipeline.py", line 5, in
import utils, vcf, genomes100, gemma ImportError: No module named genomes100
The modules listed in the import command are present under the "scripts" folder in a subfolder "modules". For each of the four modules, I have a .py and .pyc file in this subfolder. I cannot get Python to find this path.
I have tried running the same script within a virtualenv but to no avail. I even tried moving the "modules" subfolder to the Python "site-packages" folder in hopes that it would work but failed.
Finally, I tried including an init.py file (blank) in the "script" folder, but that didn't work either.
I am an utter novice and am pretty much learning as I go.Please help.

Getting error "ImportError: No module named" on Heroku but not locally

I'm getting ImportError: No module named when I try to deploy my app to heroku but the app builds fine locally. Here are the logs from Heroku
Traceback (most recent call last):
File "mr_meeseeks.py", line 4, in <module>
import Helpers.Plugin_Handler as Plugin_Handler
File "/app/Helpers/Plugin_Handler.py", line 5, in <module>
from Utils.constants import Plugin_Type
ImportError: No module named 'Utils.constants'
Here is my file structure:
As far as I can tell, Utils/constants.py exists. In case it's relevant, this is a SlackBot. The rest of the code can be found here.
The Python Interpreter looks for modules under the $PYTHONPATH environment variable. It looks like you or your editor (my editor does this when I mark a directory as sources) root has added SlackBot/ to $PYTHONPATH.
I myself encountered this error when I marked a directory as sources root.
You have a few options:
Make the bot launch script append SlackBot/ to the $PYTHONPATH
Use relative imports - from ..Utils import constants
Dynamically add SlackBot/ to the sys.path variable
Also, a note on style: python classes should be CamelCase and python modules should be lowercase_with_underscores. If you have an editor like PyCharm, your editor can fix these issues automatically, and more.
PEP 8 is the official python style guide, although I recommend using a linter so these issues can be automatically detected and fixed.
In your Procfile, append Slackbot to PYTHONPATH, try adding
--pythonpath SlackBot
as a argument. This link address the exact same issue as well.

Import statement works on PyCharm but not from terminal

PyCharm 2016.2.3, Mac OS X 10.11.1, Python 3.5 (Homebrew);
I have this folder structure
project
/somepackage
/subpackage
__init__.py
bar.py
__init__.py
foo.py
foo.py:
import somepackage.subpackage.bar
print("foo")
bar.py:
print("bar")
So my expected output is
bar
foo
This works fine when run from PyCharm. However, when I run it from my terminal I get an ImportError:
$ pwd
$ /home/project (not the actual path; just omitting some personal stuff)
$ python3.5 somepackage/foo.py
File "foo.py", line 1, in <module>
import somepackage.subpackage.bar
ImportError: No module named 'somepackage'
I have found this question, which is about the same problem. However, none of the suggested solutions work for me, as I am indeed using the same Python interpreter as PyCharm does and I am currently in the folder that contains the /somepackage folder.
Does anyone have any other suggestions about how to solve this issue?
You are running foo.py like a script, but you are really using it like a module. So the proper solution is to run it as a module:
python3 -m somepackage.foo
For the record, another alternative is to edit your path like:
export PYTHONPATH=.
(Or you could put the absolute directory in there, and of course you should append any other directories that are already in your PYTHONPATH.) This is closer to what PyCharm does, but is less philosophically correct.
Setting PYTHONPATH is what makes it work, as noted above. I use the following VSCODE .env content so that it works for any project:
PYTHONPATH=${PROJ_DIR}:${PYTHONPATH}
This is essentially what PyCharm does when you check "Add Content Roots to PYTHONPATH" in your run/debug configuration. It's a helpful setting, but it spoils you because your code fails outside PyCharm.
Or, if you run in terminal, first export:
export PYTHONPATH=...
Took me days to work all this out.
i solved my problem by two steps on Linux:
first step
go to the root directory of your project and set:
export PYTHONPATH=$PATHONPATH:`pwd`
second step
run python3 -m somepackage.foo
remember Without '.py' suffix
I just had the same problem using scapy.layers.http Module,
this problem occurred on my Kali (linux-Debian) but run fine on Win-10 (after few modifications.)
packet was installed (scapy-http) correctly and the program was running in PyCharm but not as script (from terminal)
I tried solving it with reinstalling in main root, and messing with the sys.path but None have worked.
Troubleshoot & Solution
I found that it looks for the http module in:
/usr/local/lib/python3.7/dist-packages/scapy/layers/init.py
and got the ImportError:
from scapy.layers import http --->
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'http' from 'scapy.layers' (/usr/local/lib/python3.7/dist-packages/scapy/layers/__init__.py)
So then I checked where scapy-http is really installed, which is module called http.py, so I just copied it to:
/usr/local/lib/python3.7/dist-packages/scapy/layers/
found the http.py file in :/usr/local/lib/python3.7/dist-packages/scapy_http/
And that did it :)!
I know its a bit glitchie but that worked!

Categories

Resources