skip to Main Content

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.

2

Answers


  1. # MyModule.py
    from extensions.mycode import myutils
    from myutils import MyModule`
    

    This code should work well because when you see the PATH tree, you can observe that extensions and utils are on the same level.

    Login or Signup to reply.
  2. Usually, vscode takes the workspace you open as the root directory.

    For your first file, you can use the following codes to import your module:

    # myscript.py
     
    from utils.modules import Module
    from extensions.mycode.myutils.mymodule import MyModule
    

    And if you used pycharm once, pycharm compiles files in the directory where the current running files are located. You can search "Terminal: Execute In File Dir" in the settings and check it:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search