66

I have no trouble running and debugging my project with VSCode Python Extension (ms-python.python), but since python sub-project root directory is not the whole project directory, all imports from my sources are underlined with red color and are listed in the problems and so Go to definition and some similar features don't work properly. How can I tell the IDE where's the start point of my project:

Whole Project path:
  docs
  server
    entities
      user.py
      customer.py
  env
  viewer
  db

The server directory is where the imports path are started from:

from entities.user import User
mtoloo
  • 1,795
  • 3
  • 22
  • 28

4 Answers4

81

You can create a .env file with:

PYTHONPATH=server

That will add your server folder to PYTHONPATH as needed.

(You may need to restart VSCode for it to take PYTHONPATH into account correctly.)


Edited to clarify...

Create a file named .env under the repo root e.g. your_repo/.env.

Also creating the file under the folder where your consuming code is, instead of under repo root, seems to work e.g. your_repo/service/.env.

For more details, see documentation on environment variable definition files.

For me this worked without restarting VSC, perhaps this is a matter of newer VSC and extensions versions.

Danny Varod
  • 17,324
  • 5
  • 69
  • 111
Brett Cannon
  • 14,438
  • 3
  • 45
  • 40
  • 11
    I had to restart VSC for it to work --spent a painful amount of time – Kentative Apr 21 '19 at 06:44
  • 3
    Could you clarify? Where do I put the `.env` file, in the `.vscode` folder of my project or in the project root folder? And should its name literally just be `.env`, or should it be something like `python.env`? – Ray May 01 '19 at 11:55
  • 1
    @Ray We automatically pick up the file if it's named `.env` and it's at the top of your workspace. You can also manually specify the location your settings. Se the [docs on environment files](https://code.visualstudio.com/docs/python/environments#_environment-variable-definitions-file) for details. – Brett Cannon May 17 '19 at 20:33
  • @BrettCannon: is there any way to check if this doesn't work? I am using VS Code on MacOS, with Python and Pyright extensions. I did restart VS Code after modifying .env file (PYTHONPATH=./apps:${PYTHONPATH}). Thanks. – Averell Jun 11 '19 at 10:26
  • @Averell you can simply run a script that prints out your `PYTHONPATH` environment variable, e.g. `import os; print(os.environ("PYTHONPATH")` – Brett Cannon Jun 11 '19 at 19:48
  • 2
    That should be `print(os.environ.get("PYTHONPATH"))` i.e. you need the `.get`() – abulka Jul 22 '19 at 06:25
  • @BrettCannon does VSC have anything similar when doing wdl? I checked your link, and it doesn't have anything at all about wdl/cromwell, so I'm guessing the answer is no – Greg Dougherty Jul 31 '20 at 17:11
  • @GregDougherty I don't even know what wdl is, so I'm also going to say "no" – Brett Cannon Aug 04 '20 at 20:05
  • @BrettCannon .wdl are files from the cromwell language from Broad – Greg Dougherty Aug 05 '20 at 19:59
  • @GregDougherty https://marketplace.visualstudio.com/search?term=cromwell&target=VSCode&category=All%20categories&sortBy=Relevance suggests that no one has written an extension for Cromwell – Brett Cannon Aug 06 '20 at 19:08
  • After struggling with the `.env` file for hours I gave up and deleted the `.env` file. Renamed my source folder from `my_project/my_project` to `my_project/src`. And then the imports worked like magic without any kind of setting (that I'm aware of). @BrettCannon Is there some kind of magic going on here? – CyberFly Sep 24 '20 at 13:29
  • @CyberFly depends on what you mean by "imports worked like magic"; it's possible as we try to support `src/` where we can, but admittedly it isn't plumbed through everywhere. – Brett Cannon Sep 24 '20 at 17:04
  • @BrettCannon I found the source of the magic, the Pylance extension has an option to automatically look for common source folder names like src. The option is called `python.analysis.autoSearchPaths` and is active by default. Pylance also has an option to set the name of a source folder. This option is called `python.analysis.extraPaths`. – CyberFly Sep 28 '20 at 13:27
  • In my case, I was developing just the modules in VSCode. I had to set `PYTHONPATH=..` for the import statements to work in VSCode. That's two dots to reference the root of the project as being one directory above the module. – Grant Carthew May 12 '22 at 02:06
  • 3
    no luck with this solution :( – johannstark May 25 '23 at 22:50
37

If you are using the Pylance extension you can set your source folder via the python.analysis.extraPaths option. It also looks for common source folder names like src by default, this option is called python.analysis.autoSearchPaths.

Go to File > Preferences > Settings, search for pythonpath. Under the Pylance options you should see Extra Paths, this is where you set your source folder.

CyberFly
  • 757
  • 1
  • 10
  • 15
  • 2
    Pylance is the only solution I have found to get the VSCode linter to recognize my additional search directories. Thank you! – mherzog Nov 30 '20 at 20:56
  • Easiest solution – Kevin Lemaire Dec 07 '20 at 14:27
  • 5
    Just remember to apply this modification in the **workspace's settings** to avoid all projects inherit this extra paths – cpinamtz Feb 28 '21 at 12:23
  • i tried both of those settings, but after switching to pylance all of my imports are broken :( `Unable to import 'my.library'pylint(import-error)` i am using standard practice of `src` as root python dir.. pylance wants to keep including `src....` in import paths – Sonic Soul Jun 14 '21 at 17:54
  • Already setup but not working when you it has to find files in other folders inside the specified path :( – johannstark May 25 '23 at 22:51
10

The PYTHONPATH is an environment variable which you can set to add additional directories where python will look for modules and packages.

If you need to set working directory for Visual Studio Code,

The better way is to customize Settings.json and launch.json, do like this:

// vi .vscode/Settings.json
{
    "python.pythonPath": "venv/bin/python",
}

use cwd to Specifies the current working directory for the debugger, which is the base folder for any relative paths used in code. If omitted, defaults to ${workspaceFolder} (the folder open in VS Code).

// vi .vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: your project name",
            "type": "python",
            "request": "launch",
            "cwd": "${workspaceRoot}/server",
        }
    ]
}

If you want the server run properly without any IDE, just insert the Root Drectory in front of PYTHONPATH . Assume there is a server/run.py:

import sys
src_path = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, _src_path)   

refer: https://code.visualstudio.com/docs/editor/debugging#_launch-versus-attach-configurations

refer: https://code.visualstudio.com/docs/python/debugging#python-articles

refer: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH

NicoNing
  • 3,076
  • 12
  • 23
  • 1
    I believe, `PYTHONPATH` here refers to the environment variable `PYTHONPATH` that is fed to `python`, not VSCode's `python.pythonPath` setting. So technically setting the `PYTHONPATH` env variable is exactly what is needed to tell Python about the source roots. – Yuri Shatrov Jul 29 '20 at 07:23
  • 1
    Yes , but the question of "root directory" is expected to 'How can I tell the IDE where's the start point of my project' – NicoNing Sep 16 '20 at 12:45
  • The actual question was, if I'm correct, `all imports from my sources are underlined with red color ... go to definition don't work properly`. AFAICT, all VSCode Python extension cares about is that the imported modules are importable, i.e. lie on the PYTHONPATH. At least, setting it fixed the "underline" and "go to definition" issues for me. And definitely the statement `The PYTHONPATH is the path to Python interpreter` is wrong. I don't know if there is anything else about "root directory" that I am unaware about, but most likely it has nothing to do with the issues of the TS. – Yuri Shatrov Sep 17 '20 at 13:50
  • @YuriShatrov Thanks and I have updated the statement `The PYTHONPATH is an environment variable which you can set to add additional directories where python will look for modules and packages.` , – NicoNing Apr 29 '21 at 01:15
  • small thing. workspaceRoot has been deprecated, use workspaceFolder instead https://code.visualstudio.com/docs/editor/variables-reference#_why-isnt-workspaceroot-documented – jamiet Jun 20 '23 at 21:02
2

Setting PYTHONPATH is what makes it work, as noted above. I use the following .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=...
A Jar of Clay
  • 5,622
  • 6
  • 25
  • 39
val
  • 139
  • 1
  • 6
  • 1
    wheere can i define export PYTHONPATH= in the launch.json/settings.json? – Maths12 Sep 01 '21 at 13:55
  • I haven't tried that, but these days I just step around the issue by setting the path in the code: `current_path = os.path.abspath(os.path.dirname(__file__))` `sys.path.append(current_path)` `project_dir = str(current_path)` – val Sep 02 '21 at 14:07