Edit: Slightly cleaner solution:
Don't make a separate workspace for your code (unless you want it, in which case mostly follow the guide below), and instead of putting a .vscode folder in the parent root folder, open up the workspace launch config from the Run and Debug menu on the left. Make it look something like this:
{
"folders": [
{
"path": "%path to parent%/parent"
}
],
"settings": {},
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "Launch Python parent",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}\\extensions\\mycode", // <-- Important
"env": {"PYTHONPATH": "${workspaceFolder}; ${workspaceFolder}\\extensions\\mycode; ${env:PYTHONPATH}"} // <-- Important
}
]
}
}
Not much cleaner, but you don't have to modify the parent project or set up multiple workspaces.
Not so much a question, but a solution to the very specific problem I had. Might be a duplicate of vscode import error for python module or ModuleNotFoundError - Python VSCode I can´t import modules:
I am working on an extension for an extension for a parent project. The folder structure looks something like:
parent/
extensions/
mycode/
myutils/
IMyModule.py
MyModule.py
myscripts/
myscript.py
utils/
__init__.py
modules.py
scripts/
script.py
where myscript.py wants to
# myscript.py
from utils.modules import Module
from myutils.mymodule import MyModule
and MyModule.py wants to
# MyModule.py
from IMyModule import IMyModule
(I'm trying out OOP for the first time)
This lead to the dreaded ModuleNotFoundError: No module named 'myutils'
tl;dr Put __init__.py in the proper places and add a .vscode/launch.json to the parent directory.
Several things had to happen to fix this problem (for my method, anyway), and I have confirmed that (most) every step was necessary.
First, I didn't know about __init__.py (I'm new to Python, so I had to google this). I'm leaving this part in in case some other newbie doesn't know about that and is having this same problem.
So I added __init__.py to the myutils folder with contents that look like this:
# myutils/__init__.py
from .IMyModule import *
from .MyModule import *
I also had multiple nested folders in there, so an __init__.py went in every subfolder.
This alone still gave me the ModuleNotFoundError.
After that didn't work, (and after much trial and error), I imported the parent folder as a second workplace in VSCode by going into File->Add Folder to Workspace... (This may not be necessary. See below).
In addition, I added a .vscode folder with a launch.json file into mycode/. The launch.json looks like this:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"cwd": "${fileWorkspaceFolder}",
"env": {"PYTHONPATH": "${workspaceFolder:parent}; ${workspaceFolder:mycode}; ${env:PYTHONPATH}"}
}
]
}
Unpacking this,
"cwd": "${fileWorkspaceFolder}"
makes the working directory for parent files remain in parent/, but the working directory for mycode files becomes mycode/. This makes sure I can still run parent's code while also being able to run my code separately.
"env": {"PYTHONPATH": "${workspaceFolder:parent}; ${workspaceFolder:mycode}; ${env:PYTHONPATH}"}
says to Python, "look in parent/ for parent's packages, mycode/ for mycode's packages, and keep the current PYTHONPATH in case there's something in there." This is why I added mycode as a separate workspace (now that I think about it, that may have not been necessary if you change
${workspaceFolder:parent}; ${workspaceFolder:mycode}
to
${workspaceFolder}; ${workspaceFolder}/extensions/mycode
but I'm too lazy to test that now).
All of this together, and tada! Working myscript.py that can import code from myutils/, call parent code, and also parent code still works on its own.
The final directory structure looks like:
parent/
.vscode/
launch.json
extensions/
mycode/
myutils/
__init__.py
IMyModule.py
MyModule.py
myscripts/
myscript.py
utils/
modules.py
scripts/
script.py
Any comments and suggestions are welcome, especially if there's a simpler method to solve this particular problem.
