I have a situation that I believe is relatively common. I want a script to import a module from another directory. My python project is laid out as follows:

~/project/
  |
  |---modules/
        |
        |---mod.py
  |---scripts/
        |---script.py

in script.py, I have from modules import mod. So my PYTHONPATH needs to be set to ~/project/ (something that PyCharm does automatically).

VSCode is a great editor, but everywhere else, it falls short, in my opinion. This is a perfect example of that.

I create a default launch.json file to "run the current file". A "cwd": "${fileDirname}" line has to be added to make things work like they do in PyCharm (FYI, a list of the built-in variables can be found here).

Debugging

For debugging (the "play" button on the sidebar, or the F5 key), the PYTHONPATH set in launch.json or your .env file takes effect. Note that in the .env file, you cannot use variables such as ${workspaceRoot}, but you can easily append or insert to the path by using the proper separator for your platform (; for Windows and : for everyone else).

Because I want to take advantage of that variable, I put this in my launch.json:

    "env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"}

(Thanks to @someonr for the suggestion to use ${pathSeparator}.)

It appears that you can prepend/append to whatever is inherited from the environment (this is not true for settings.json; see below).

This will also work for the hotkey Ctrl+F5 (run without debugging).

For reference, here's the full file, which replicates what PyCharm does automatically:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "cwd": "${fileDirname}",
            "env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"}
        }
    ]
}

Run in terminal

If I hit the "play" button that appears on the top right of the editor window (when a python file is the active tab), it will not work. This runs the current file in a terminal, which doesn't pay attention to launch.json at all. To make that work, you have to define PYTHONPATH in a settings.json file, by adding this:

    "terminal.integrated.env.osx": {"PYTHONPATH": "${workspaceFolder}"}

(Note there are different values for each platform.) If you've selected a python interpreter (e.g. from a virtual environment), you will already have a settings.json file in the .vscode directory. Mine looks like this:

{
    "python.pythonPath": "/Users/me/project/venv/bin/python3",
    "terminal.integrated.env.osx": {"PYTHONPATH": "${workspaceFolder}"}
}

You can't append or insert values into the inherited PYTHONPATH via the settings.json file. It will only take one string, and it will not parse separators. So even though you could get the value using ${env:PYTHONPATH}, you won't be able to do anything with it.

Moreover, you can't set the current working directory. Even though it would seem you could set it with "terminal.integrated.cwd": "${workspaceFolder}", it doesn't work. So if any of your scripts do anything with paths relative to their location in the tree, they won't work. The working directory will be your project root.

Note that any changes to the settings.json file will require that you exit the integrated terminal and restart it.

Linting

Nothing I do to launch.json regarding PYTHONPATH makes any difference to pylint, which will red-underline from modules import mod, despite the fact I can put the cursor on mod, hit F12, and the file opens. Snooping around linting settings, the defaults for mypy include --ignore-missing-imports. To replicate this behavior with pylint, add this to your settings.json:

    "python.linting.pylintArgs": [
        "--disable=F0401"
    ] 

Shame that we just have to work around this, but the autocomplete helps a lot when writing the import statements to begin with.

Conclusion

There are many layers to VSCode and it's hard to get things to work together. It seems multiple environments are floating around. In the end:

  1. I cannot "run in terminal" because I can't set the current working directory to be the path containing the current file.
  2. I cannot set PYTHONPATH for pylint as that runs in some environment different than the integrated terminal and whatever is controlled by launch.json, so I can only tell pylint to ignore import errors.
  3. Running with F5 works if you set PYTHONPATH either via an .env file or in launch.json
Answer from darda on Stack Overflow
Top answer
1 of 16
182

I have a situation that I believe is relatively common. I want a script to import a module from another directory. My python project is laid out as follows:

~/project/
  |
  |---modules/
        |
        |---mod.py
  |---scripts/
        |---script.py

in script.py, I have from modules import mod. So my PYTHONPATH needs to be set to ~/project/ (something that PyCharm does automatically).

VSCode is a great editor, but everywhere else, it falls short, in my opinion. This is a perfect example of that.

I create a default launch.json file to "run the current file". A "cwd": "${fileDirname}" line has to be added to make things work like they do in PyCharm (FYI, a list of the built-in variables can be found here).

Debugging

For debugging (the "play" button on the sidebar, or the F5 key), the PYTHONPATH set in launch.json or your .env file takes effect. Note that in the .env file, you cannot use variables such as ${workspaceRoot}, but you can easily append or insert to the path by using the proper separator for your platform (; for Windows and : for everyone else).

Because I want to take advantage of that variable, I put this in my launch.json:

    "env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"}

(Thanks to @someonr for the suggestion to use ${pathSeparator}.)

It appears that you can prepend/append to whatever is inherited from the environment (this is not true for settings.json; see below).

This will also work for the hotkey Ctrl+F5 (run without debugging).

For reference, here's the full file, which replicates what PyCharm does automatically:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "cwd": "${fileDirname}",
            "env": {"PYTHONPATH": "${workspaceFolder}${pathSeparator}${env:PYTHONPATH}"}
        }
    ]
}

Run in terminal

If I hit the "play" button that appears on the top right of the editor window (when a python file is the active tab), it will not work. This runs the current file in a terminal, which doesn't pay attention to launch.json at all. To make that work, you have to define PYTHONPATH in a settings.json file, by adding this:

    "terminal.integrated.env.osx": {"PYTHONPATH": "${workspaceFolder}"}

(Note there are different values for each platform.) If you've selected a python interpreter (e.g. from a virtual environment), you will already have a settings.json file in the .vscode directory. Mine looks like this:

{
    "python.pythonPath": "/Users/me/project/venv/bin/python3",
    "terminal.integrated.env.osx": {"PYTHONPATH": "${workspaceFolder}"}
}

You can't append or insert values into the inherited PYTHONPATH via the settings.json file. It will only take one string, and it will not parse separators. So even though you could get the value using ${env:PYTHONPATH}, you won't be able to do anything with it.

Moreover, you can't set the current working directory. Even though it would seem you could set it with "terminal.integrated.cwd": "${workspaceFolder}", it doesn't work. So if any of your scripts do anything with paths relative to their location in the tree, they won't work. The working directory will be your project root.

Note that any changes to the settings.json file will require that you exit the integrated terminal and restart it.

Linting

Nothing I do to launch.json regarding PYTHONPATH makes any difference to pylint, which will red-underline from modules import mod, despite the fact I can put the cursor on mod, hit F12, and the file opens. Snooping around linting settings, the defaults for mypy include --ignore-missing-imports. To replicate this behavior with pylint, add this to your settings.json:

    "python.linting.pylintArgs": [
        "--disable=F0401"
    ] 

Shame that we just have to work around this, but the autocomplete helps a lot when writing the import statements to begin with.

Conclusion

There are many layers to VSCode and it's hard to get things to work together. It seems multiple environments are floating around. In the end:

  1. I cannot "run in terminal" because I can't set the current working directory to be the path containing the current file.
  2. I cannot set PYTHONPATH for pylint as that runs in some environment different than the integrated terminal and whatever is controlled by launch.json, so I can only tell pylint to ignore import errors.
  3. Running with F5 works if you set PYTHONPATH either via an .env file or in launch.json
2 of 16
60

The documentation is missing some important details.

Example

Suppose your project layout is like this

myproject/
    .vscode/
        settings.json
    .env
    src/
        a_module.py
    tests/
        test_a.py

Open the settings.json file and insert these lines

// On linux use "terminal.integrated.env.linux": {
"terminal.integrated.env.windows": {
    "PYTHONPATH": "${workspaceFolder}/src;${workspaceFolder}/tests"
},
// The next line can be omitted, unless you've modified the global default
"python.envFile": "${workspaceFolder}/.env",

Note that ${workspaceFolder} evaluates to myproject, it is not to the .vscode folder.

In the .env file enter this

PYTHONPATH=src;test
# Paths are relative to the workspace folder, so above is equivalent to
# WORKSPACE_FOLDER=C:/full/path/to/myproject
# PYTHONPATH=${WORKSPACE_FOLDER}/src;${WORKSPACE_FOLDER}/tests

Note that on all platforms, including Windows, the slashes in the path lean forward, like so /. Different paths are separated with a ; on Windows, on other platforms with a :.

Final step, restart VS Code.

This blog was helpful.

🌐
GitHub
github.com › microsoft › vscode-python-debugger › issues › 343
add ${workspaceFolder} to "PYTHONPATH" in launch.json by default · Issue #343 · microsoft/vscode-python-debugger
May 9, 2024 - Previously I used Jetbrains Pycharm and not for a long time ago switched to VSCode. Please add "env": { "PYTHONPATH": "${workspaceFolder};${env:PYTHONPATH}" } as default configuration parameters, when create to launch.json Pycharm did it for a long time ago Thank you in advance
Author   Akopov4
Discussions

When python.pythonPath includes ${workspaceFolder}, tasks that use ${config:python.pythonPath} fail to start
From @segevfiner on August 28, 2018 22:39 Environment data VS Code version: 1.26.1 Extension version (available under the Extensions sidebar): 2018.7.1 OS and version: Windows 10.0.17134.228 x64 Py... More on github.com
🌐 github.com
11
August 30, 2018
${workspaceFolder} does not work well in .env file, but "${workspaceFolder}." works
All VS Code versions · Add below strings in .env: PYTHONPATH = ${PYTHONPATH}:${workspaceFolder} PYTHONPATH = ${PYTHONPATH}:${workspaceFolder}./module2 More on github.com
🌐 github.com
4
May 26, 2020
${workspaceFolder} and ${env:PYTHONPATH} in PYTHONPATH in env file not resolved during test discovery
Environment data VS Code version: 1.47.0 Extension version (available under the Extensions sidebar): v2020.6.91350 OS and version: Windows_NT x64 10.0.18362 Python version (& distribution if ap... More on github.com
🌐 github.com
4
September 2, 2020
Workspace environment variable ${workspaceFolder} is not being set/empty on WSL
Type: Bug I develop using WSL on my Windows machine. I use the Remote plugin to connect to my Ubuntu 22.04 instance and open folders from there. Issue: I have been running into a consistent problem... More on github.com
🌐 github.com
2
February 13, 2025
🌐
GitHub
github.com › microsoft › vscode-python › issues › 12289
Setting pythonPath with ${workspaceFolder} in launch.json configs doesn't work · Issue #12289 · microsoft/vscode-python
June 11, 2020 - When I set e.g. this in a config of my workspace's launch.json: "pythonPath": "${workspaceFolder}/build/my/own/python", I get an error about the pythonPath being invalid when I try to run it. As soon as I replace it with the full path it...
Author   koenlek
🌐
Xebia
xebia.com › home › blog › setting python source folders in visual studio code
Setting Python Source Folders In Visual Studio Code | Xebia
3 weeks ago - You can extend the existing PYTHONPATH by referencing the current environment variable and appending your source folder, such as ${env:PYTHONPATH}:${workspaceFolder}/src (or using ; on Windows).
🌐
Visual Studio Code
code.visualstudio.com › docs › python › settings-reference
Python settings reference
November 3, 2021 - ${workspaceFolder} - the path of the folder opened in VS Code
🌐
Visual Studio Code
code.visualstudio.com › docs › python › environments
Python environments in VS Code
November 3, 2021 - When you assign an environment to a project, the extension writes to your workspace settings (.vscode/settings.json):
🌐
Redreamality's Blog
redreamality.com › blog › pythonpathvs-code
Setting PYTHONPATH Environment Variable: A Comprehensive Guide for All Platforms & VS Code Development
August 21, 2025 - Open or create the .vscode/settings.json file and add: ... ${workspaceFolder} is a predefined variable in VS Code that represents the root directory of the project you currently have open.
🌐
Bacancy Technology
bacancytechnology.com › qanda › python › set-the-root-directory-for-visual-studio-code-python-extension
Set Root Directory for Visual Studio Code Python Extension
2. Configure the Python Path and Import Root: In your workspace settings (.vscode/settings.json), add the python.autoComplete.extraPaths to include the server directory: { "python.pythonPath": "C:\\path\\to\\your\\virtualenv\\Scripts\\python.exe", "python.autoComplete.extraPaths": [ "${workspaceFolder}/server" ] } Another approach to configuring your Python root directory is by using an environment variable, set through a .env file in your project.
Find elsewhere
🌐
GitHub
github.com › microsoft › vscode › issues › 57551
When python.pythonPath includes ${workspaceFolder}, tasks that use ${config:python.pythonPath} fail to start · Issue #57551 · microsoft/vscode
August 30, 2018 - (python.pythonPath should be set to a path using ${workspaceFolder}). Create a task that uses ${config:python.pythonPath} to run anything you want, and try to run it. Nothing relevant under default log level. Copied from original issue: microsoft/vscode-python#2459
Author   brettcannon
🌐
GitHub
github.com › microsoft › vscode-python › issues › 11983
${workspaceFolder} does not work well in .env file, but "${workspaceFolder}." works · Issue #11983 · microsoft/vscode-python
May 26, 2020 - All VS Code versions · Add below strings in .env: PYTHONPATH = ${PYTHONPATH}:${workspaceFolder} PYTHONPATH = ${PYTHONPATH}:${workspaceFolder}./module2
Published   May 26, 2020
Author   haibaoli
🌐
GitHub
github.com › microsoft › vscode-python › issues › 13749
${workspaceFolder} and ${env:PYTHONPATH} in PYTHONPATH in env file not resolved during test discovery · Issue #13749 · microsoft/vscode-python
September 2, 2020 - ---------------------------- Captured stdout call ----------------------------- PYTHONPATH = ${workspaceFolder}\src;${env:PYTHONPATH}
Author   mlisovyi
🌐
GitHub
github.com › microsoft › vscode-python › issues › 24818
Workspace environment variable ${workspaceFolder} is not being set/empty on WSL · Issue #24818 · microsoft/vscode-python
February 13, 2025 - I have confirmed this by setting my "PYTHONPATH" to "PYTHONPATH=${workspaceFolder}" in a .env file and from the terminal, after loading in variables from this .env file I run echo $PYTHONPATH and it returns empty. I have double checked this by opening the same folder in vscode running on Windows and it is set correctly here.
Author   enda-quantmatix
🌐
GitHub
github.com › microsoft › vscode-python › issues › 20461
.env files don't resolve ${workspaceFolder} in PYTHONPATH · Issue #20461 · microsoft/vscode-python
print(os.getcwd()) # prints the correct ${workspaceFolder} print(sys.path) # path has ${workspaceFolder}/examples/src and not ${workspaceFolder}/src print(sys.environ['PYTHONPATH']) # pythonpath is "./src"
🌐
GitHub
github.com › microsoft › vscode-python › issues › 11918
Having relative paths in .code-workspace files for interpreter path setting doesn't work · Issue #11918 · microsoft/vscode-python
May 20, 2020 - #requires -Version 3 $PSDefaultParameterValues['Out-File:Encoding'] = 'utf8' $root = "${PWD}\repro-example" $niParams = @{ Path = "$root\src\server\.vscode", "$root\src\client" ItemType = 'Directory' Force = $true } New-Item @niParams > $null @' { "folders": [ {"path": "."}, {"path": ".\\src\\server"}, {"path": ".\\src\\client"} ] } '@ | Out-File -FilePath "$root\vscode.code-workspace" @' { "python.pythonPath": "..\\.venv\\Scripts\\python.exe", "python.jediEnabled": false, } '@ | Out-File -FilePath "$root\src\server\.vscode\settings.json" '' | Out-File -FilePath "$root\src\server\__init__.py" -NoNewline py.exe -3 -m venv "$root\.venv" code.cmd "$root\vscode.code-workspace"
Published   May 20, 2020
Author   morsley
🌐
GitHub
github.com › microsoft › vscode-python › issues › 13965
${workspaceFolder} does not work in .env file · Issue #13965 · microsoft/vscode-python
September 17, 2020 - I have set the PYTHONPATH environment variable in the .env file located in the root of my project workspace. That is working fine in the editor, all Python packages that should be found in the folders specified via PYTHONPATH can be found. One of these folders is a sub directory under my project root, so I replaced that part with ${workspaceFolder} in the .env file.
Author   haimat
🌐
GitHub
github.com › microsoft › vscode-python › issues › 11671
`${workspaceFolder}` & `.` not being resolved in settings in some cases · Issue #11671 · microsoft/vscode-python
May 7, 2020 - Resolving ${workspaceFolder} Having "python.testing.unittestArgs": [ "-p", "*test.py", "-s", "${workspaceFolder}/src", ] instead of "python.testing.unittestArgs": [ "-p", "*test.py", "-s", "./src", ] doesn't work. Resolving . This proble...
Author   karrtikr
🌐
Donjayamanne
donjayamanne.github.io › pythonVSCodeDocs › docs › python-path
Python Path and Version | Python in Visual Studio Code
Option 1: Ensure the path to the python interpreter is set in python.pythonPath as defined previously.
🌐
eSparkBiz
esparkinfo.com › root directory for visual studio code python
Proper Way to Set Python Root Directory in VS Code
January 21, 2026 - “cwd”: “${workspaceFolder}/src” · } ] } This is essential when debugging scripts that live in nested folders. This doesn’t change the root folder but lets Python find modules in custom paths. Put it in your root folder and add: PYTHONPATH=./src · Add this to your .vscode/settings.json: { “python.envFile”: “${workspaceFolder}/.env” ·
Price   $12
Address   12th Floor, The Orion, Sarkhej - Gandhinagar Hwy, Ahmedabad, Gujarat 382481
🌐
GitHub
github.com › microsoft › vscode-python › issues › 10533
Explain once and for all how to set python.pythonPath using environment variables or remove this from docs · Issue #10533 · microsoft/vscode-python
March 12, 2020 - The file is identified by the default entry "python.envFile": "${workspaceFolder}/.env" in your user settings (see General settings). You can change the python.envFile setting at any time to use a different definitions file. I'm certain this means that the extension is supposed to read the .env file and use the values found there. If that's the case, why does it fail to use the environment variables I set, to fill in python.pythonPath?
Author   smac89
🌐
GitHub
github.com › Microsoft › vscode-python › issues › 2459
Don't set ${workspaceFolder} in settings.json · Issue #2459 · microsoft/vscode-python
August 28, 2018 - Select it as the Python interpreter of VS Code using the status bar. (python.pythonPath should be set to a path using ${workspaceFolder}). Create a task that uses ${config:python.pythonPath} to run anything you want, and try to run it.
Author   segevfiner