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.
 
     
     
    
