Here's my file structure
test/
-dir1
-thing.py
-dir2
-__init__.py
-thing2.py
I am using python 3.7 and windows 10.
In thing.py, I'm trying to import a function called foo from thing2.py and have it execute when I run thing.py. My code works perfectly in PyCharm when I press run. However, when I run thing.py from the terminal directly or through code runner in VSCode, I get the following error:
from dir2.thing2 import foo
ERROR: ModuleNotFoundError: No module named 'dir2
Is the issue something to do with my PYTHONPATH or something else?
Based on the information you provided, I reproduced the problem you described. And you could use the following methods to solve it:
Please add the following code at the beginning of the "thing.py" file, which adds the path of the currently opened file to the system path so that VSCode can find "foo" according to "from dir2.thing2 import foo":
import os, sys
sys.path.append('./')
If you don't want to add code, you could add the following setting in "launch.json", which adds the path of the project when debugging the code:
"env": {
"PYTHONPATH": "${workspaceFolder}"
}
Related
I have a directory that contains sub directories of code that I reuse.
MyBaseDirectory
\genericcodedir1
reuse1.py
\simpleapp1
app1.py
app1.py has the following line
import reuse1
Visual studio will fail to run this since it says it can't find the library.
On windows I simply added the genericcodedir1 to the PYTHONPATH environment variable and all is well.
What should I do on the raspberry pi to allow this to run?
error message:
Exception has occurred: ModuleNotFoundError
No module named 'reuse1'
File "/home/pi/Desktop/Mybasedirectory/simpleapp1/app1.py", line 5, in <module>
import reuse1
I assume you have file structure like this and you open Test folder in VS Code As follows.
You can specify the path by adding the following code above the import statement in app.py:
import sys
sys.path.append("./genericcodedir1")
import reuse1
In addition, you can add the following configuration to the settings.json file to make vscode recognize reuse1.
{
"python.analysis.extraPaths": [
"./genericcodedir1"
]
}
code and result
so if your files looks like :
|_genericcodedir
|_reuse1.py
|_simpleapp1
|_app1.py
you need to add an empty file called __init__.py in your genericcodedir.
another note worthy thing is your working directory (the directory in which your terminal runs)
you may need to append to os path depending on where you are when launching the program
I'm trying to debug a project that has a lot of additional libraries added to PYTHONPATH at runtime before launching the python file.
I was not able to add those commands with tasks.json file prior to debugging python file in Visual Studio code (see post Visual Studio Code unable to set env variable paths prior to debugging python file), so I'm just adding them via an os.system("..") command
I'm only showing 1 of the libraries added below:
# Standard library imports
import os
import sys
os.system("SET PYTHONPATH=D:\\project\\calibration\\pylibrary\\camera")
# Pylibrary imports
from camera import capture
When I debug, it fails on line from camera import capture with:
Exception has occurred: ModuleNotFoundError
No module named 'camera'
File "D:\project\main.py", line 12, in <module>
from camera.capture import capture
I also tried
os.environ['PYTHONPATH']="D:\\project\\pylibrary\\camera" and I still get the same error
Why is it not remembering the pythonpath while running the script?
How else can I define the pythonpath while running Visual Studio Code and debugging the project file?
I know I can add the pythonpath to env variables in windows, but it loads too many libraries and I want it to only remember the path while the python script is executed.
Thanks
Using os.system() won't work because it starts a new cmd.exe shell and sets the env var in that shell. That won't affect the env vars of the python process. Assigning to os.environ['PYTHONPATH'] won't work because at that point your python process has already cached the value, if any, of that env var in the sys.path variable. The solution is to
import sys
sys.path.append(r"D:\project\calibration\pylibrary\camera")
What I want
I'm using Visual Studio Code and Python 3.7.0 and I'm just trying to import another Python file, from another folder, into my python file.
Details
Here is my folder structure
root/
dir1/
data.txt
task11.py
task12.py
dir2/
data.txt
task21.py
task22.py
Helpers/
FileHelper/
ReadHelper.py
So a short explanation:
I use the same function in every "task"-file
Instead of putting the function in every "task"-file, I've created a helper file where the function exists
I want to import the helper file "ReadHelper.py" into my task files
What I've tried
e.g. in the file task11.py:
from Helpers.FileHelper.ReadHelper import *
import os, sys
parentPath = os.path.abspath("../../")
if parentPath not in sys.path:
sys.path.insert(0, parentPath)
from Helpers.FileHelper.ReadHelper import *
import os, sys
sys.path.append('../../')
from Helpers.FileHelper.ReadHelper import *
None of the above solutions works as I always end up with the error:
ModuleNotFoundError: No module named 'Helpers'
I've also tried:
from ..Helpers.FileHelper.ReadHelper import *
But it ends up with the error: ValueError: attempted relative import beyond top-level package
So how can I import the file ReadHelper.py to my task files?
P.S
There are some similar questions to this but they are really old and the answers have not helped me.
Update 1
There is an option in Visual Studio code, If I run this command with this import from Helpers.FileHelper import ReadHelper then no errors are generated and the code executes perfectly.
One downside is that this interactive window is slow at starting and it cannot handle inputs.
I tried the answer of #Omni as well:
$> python -m root.dir1.task11
And it worked! but as he said, there is a downside: it is slow to type in the terminal.
So I tried to create a task in Visual Studio Code that could execute the above shell command for the file that I'm currently in, but did not succeed.
Do you know how to create a task in vscode to run the above command?
I've also tried to add __init__.py-files under every directory so they would be seen as packages Python3 tutorial - 6.4 Module Packages. But this didn't help and the same error occurred.
Update 2
I come up with a way to make it really easy to have a folder structure like this and get the imports to work correctly in the terminal.
Basically what I did was:
created a Python script
created a task in visual studio code
With this, I can now run my python files, with the imports, by only pressing cmd + shift + B.
Explanation
The visual studio task:
{
"version": "2.0.0",
"tasks": [
{
"label": "Run python file",
"type": "shell",
"command": "python3 /PATH_TO_ROOT_FOLDER/run_python_file.py ${file}",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new",
"focus": true
}
}
]
}
The part that we want to focus on is this one:
"command": "python3 /PATH_TO_ROOT_FOLDER/run_python_file.py ${file}",
This part runs the new python file I created at the root folder and passes the path, of the file which is active, as a parameter
The python script:
import os, sys
# This is a argument given trough a shell command
PATH_TO_MODULE_TO_RUN = sys.argv[1]
ROOT_FOLDER = "root/"
def run_module_gotten_from_shell():
# Here I take only the part of the path that is needed
relative_path_to_file = PATH_TO_MODULE_TO_RUN.split(ROOT_FOLDER)[1]
# Creating the shell command I want to run
shell_command = createShellCommand(relative_path_to_file)
os.system(shell_command)
# Returning "python3 -m PATH.TO.MODULE"
def createShellCommand(relative_path_to_file):
part1 = "python3"
part2 = "-m"
# Here I change the string "dir1/task11.py" => "dir1.task11"
part3 = relative_path_to_file.replace("/", ".")[:-3]
shell_command = "{:s} {:s} {:s}".format(part1, part2, part3)
return shell_command
run_module_gotten_from_shell()
This python script gets as a parameter the path to the active file
Then it creates a shell command of the path (the shell command is like #kasper-keinänen 's answer)
Then it runs that shell command
With these modifications, I can run any file inside the root directory with imports from any file inside the root directory.
And I can do it by only pressing cmd + shift + B.
You could try running the script with the -m option that allows modules to be located using the Python module namespace docs.python.org.
If you run the task11.py script then:
$ python3 -m dir1.task11
And in the task11.py do the import like:
from Helpers.FileHelper.ReadHelper import *
Adding the full absolute path to the sys.path variable should make it work.
import sys
sys.path.append('/full/path/to/Helpers/FilesHelper/')
from ReadHelper import *
If you're only trying to do this in VSCode, and not during normal run time. You can add the path in the .vscode/settings.json
{
"python.analysis.extraPaths": [
"${workspaceFolder}/webapp"
],
}
NOTE: This does not solve standard Python importing. My use-case was specific to a monolithic project where all editor config files where in the root and thus I couldn't open 'webapp/' as a workspace itself.
a) Execute the task modules as scripts within an environment that knows about the helper functions. That way the code in the taks modules does not have to know anything about the package structure present. It imitates the builtins of the python interpreter.
# cli argument #1 is the task module to execute
import sys
task_to_execute = sys.argv[1]
from Helpers.FileHelper.ReadHelper import *
exec(open(task_to_execute).read())
b) Use relative imports correctly. In order to do so, you have to execute the task code via (this might be a disadvantage of this solution).
$> python -m root.dir1.task11.task11
The problem is your file/folder structure. I would suggest creating a sort of 'control' file in your root folder, which can then work from the top-down to reference all your other modules.
So let's say you had a file in your root folder called MasterTask.py it could look like this:
from dir1.task11.task11 import *
from dir1.task12.task12 import *
from dir2.task21.task21 import *
from dir2.task22.task22 import *
from Helpers.FileHelper.ReadHelper import *
class Master:
#Do your task work here
pass
One other option would be to move the Helpers folder into your Python37\Lib\site-packages folder, which would also allow the use of from Helpers.FileHelper.ReadHelper import * as is - assuming that you are not planning on this to be used on other machines other than your own.
dev is my root directory. I have the below files.
dev\sitehealthcheck\test.py
dev\sitehealthcheck\draw.py
In test.py, the first line reads:
from sitehealthcheck.draw import *
If I run test.py in the VSCode terminal, everything works as expected. However, when I try to execute test.py in the interactive window, Jupyter returns:
ModuleNotFoundError: No module named 'sitehealthcheck'
What can I do so VSCode automatically searches for modules in the same directory as the file I'm executing?
I would prefer just to type the below line.. and, have the VSCode editor/Intellisense and Jupyter to automatically search for modules in the same directory as the file I'm executing.
from draw import *
In support of the existing answers, you need to add the jupyter.notebookFileRoot line to your settings.json file in your workspace when using a notebook in a subfolder and modules in a sibling folder:
.vscode/settings.json:
{
"python.pythonPath": "env/bin/python",
"jupyter.notebookFileRoot": "${workspaceFolder}"
}
To solve this problem, you can search for a setting in the Python extension which is called "Python › Data Science: Notebook File Root". The line below the title of this setting says: "Set the root directory for loading files for the Python Interactive window.". Then you change ${workspaceFolder} to ${fileDirname}, close the interactive Python terminal and restart it, and it should work.
For the interactive window the current working directory is not set to the path of the file being executed, instead it's set to the path of the workspace folder that you have open in VSCode. If I have the following:
WorkspaceFolder:
SubFolder:
MyScript.py
ImportMe.py
If you run MyScript.py in the terminal you would want this:
from importme import * since the file location is added to the path
But if you are using the interactive window you can either add to your PythonPath as suggested above. Or you can use this:
from SubFolder.importme import *
Since the CWD is set to the workspace root for the Interactive Window session.
Easy way to set proper kenral and venv. Try setting proper venv like below.
if error in jupyter notebook
open -: anaconda prompt
pip install import-ipynb
open main file
import import_ipynb
import first
If you add .../dev/sitehealthcheck to your PYTHONPATH, then you can import draw.
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!