VS Code & Python Projects

posted in: Software 0

*** these notes are a work-in-progress and will be updated as needed ***

This post documents how I set up projects in Python and how to configure VS Code for debugging.

Project Structure

There are 2 basic forms of project structure that seem to work for me.

Simple Projects

project-name
    doc/
    data/
    inc/
        __init__.py
        shared-code1.py
        shared-code2.py
    tests/
        __init__.py
        test_test1.py
        test_test2.py
    program.py
    program2.py

Complex Projects

This is my preferred setup.

project-name
    doc/
    data/    
    tests/
        testfiles/
            temp&permanent-test-files
        __init__.py
        test_test1.py
        test_test2.py
    project-name
        inc/
            __init__.py
            shared-code1.py
            shared-code2.py
        __init__.py
        __main__.py
        program.py

Testing

The __init__.py in the testing folder should contain the following code.  This adds the project folder to the python path so the imports work as expected.

import os
import sys
PROJECT_PATH = os.getcwd()
PROJECT_FOLDER = os.path.basename(PROJECT_PATH)
SOURCE_PATH = os.path.join(
    PROJECT_PATH,PROJECT_FOLDER
)
sys.path.append(SOURCE_PATH)

VS Code Configuration

The challenge with both of these structures is importing the programs and shared programs in the tests modules. If you are in the main directory, then running the tests with discovery (ie python -m unittest) will generally work. However, if you are in the test directory and trying to debug a test with VS Code, the imports fail with module not found.

The following options in the project.code-workspace will set the PYTHONPATH to the workspace folder so all imports can be found. The PYTHONPATH must be updated in two locations: (1)settings and (2) launch.

Note:  The /project-name is only needed for the complex project setup.


{
 "folders": [
    {
	"path": "."
    }
 ],
 "settings": {
    "python.linting.cwd": "${workspace}/project-name",
    "python.analysis.extraPaths": [
		"${workspaceFolder}/project-name"
		],
    "terminal.integrated.cwd": "${workspaceFolder}",
    "terminal.integrated.env.windows": {
	"PYTHONPATH": "${workspaceFolder}/project-name",
		},
    "terminal.integrated.env.linux": {
	"PYTHONPATH": "${workspaceFolder}/project-name",
		},
 },
 "launch": {
	"version": "0.2.0",
	"configurations": [
	  {
	    "name": "Python: Current File",
	    "type": "python",
	    "request": "launch",
	    "program": "${file}",
	    "env": {"PYTHONPATH": "${workspaceFolder}/project-name"},
	    "console": "integratedTerminal",
	    "justMyCode": true,
            "cwd": "${workspaceFolder}",
	  }

        ]
 }
}

WSL

With Windows and WSL, I have a .bashrc modification which opens the bash terminal in my data directory when the terminal is opened from the command line.  The code snippet below ignores the change directory command when a terminal is opened from VS Code.

# start in data directory if not vs code
if [ "$TERM_PROGRAM" != "vscode" ]; then
    cd /mnt/c/Data
fi
Comments are closed.