Development with VS Code¶

This guide covers the full development workflow in Visual Studio Code. The project ships committed task definitions and settings under .vscode/. Once you select a Python interpreter, every common task is available from the Command Palette with no extra configuration.
Setup¶
1. Fork, clone, and install¶
Follow steps 1–4 of the setup walkthrough in the contributing guide to fork the repository, clone it, and install dependencies. Then come back here for VS Code–specific setup.
2. Open in VS Code¶
Or File → Open Folder → select the ChuMicro directory.
3. Install recommended extensions¶
VS Code may prompt you to install recommended extensions. Accept, or install manually:
- Python (
ms-python.python): required - Pylance (
ms-python.vscode-pylance): recommended for type checking
4. Select the Python interpreter¶
Open the Command Palette (⌘⇧P / Ctrl+Shift+P) → Python: Select Interpreter.
If you already have a .venv:
- Select it from the list
If not, create one first:
Then select the .venv interpreter from the Command Palette.
5. Run workspace setup¶
Open the integrated terminal (⌃\`` / `` Ctrl+ ``) and run:
This installs dependencies, runs editable installs for every library and support package, and regenerates IDE configs. It also materializes three gitignored starter files at the repo root if they're missing: devices.yml, workspace.yml, and secrets.toml. If you plan to run functional tests on real hardware, see Device Testing for board registration and secrets.toml setup.
setup produces a lot of output. Look for this at the end:
============================================================
Workspace is ready
============================================================
Import resolution¶
The mono-workspace layout means each library has its own src/ directory. VS Code resolves imports through two generated config files:
pyrightconfig.json: setsextraPathsfor each library'ssrc/directory.vscode/settings.json: setspython.analysis.extraPathsfor Pylance
Both are generated by sync-ide (called automatically during setup). Imports like from chumicro_timing import ticks_ms should resolve without errors.
If imports show as unresolved:
- Run
python scripts/run.py sync-idein the terminal - Reload the window: Command Palette → Developer: Reload Window
Note: VS Code uses
extraPathsfor import resolution. You don't need to runpip install -emanually. The workspace setup script handles editable installs automatically.
Running tasks¶
The project provides pre-configured tasks in .vscode/tasks.json. Open the Command Palette (⌘⇧P / Ctrl+Shift+P) → Tasks: Run Task:
| Task | What it runs |
|---|---|
| Preflight | Full CI gate: lint, test, build, docs, examples, compat |
| Lint | Ruff across the workspace |
| Test | CPython tests for all libraries |
| Test Scripts | Infrastructure tests for scripts/ |
| Build | Build all package distributions |
| Verify Examples | AST-based import check of all examples |
| Docs | Build documentation for all libraries |
| Docs Preview | Deploy and serve versioned docs locally |
| Check API | Detect API breakages |
| Check Version | Verify VERSION bumps |
| Test MicroPython | Library unit tests on the MicroPython unix port |
| Test CircuitPython | Library unit tests on the CircuitPython unix port |
| Test All Runtimes | Unit tests on CPython + MicroPython + CircuitPython (parallelized) |
| Setup | python scripts/run.py setup: installs dev deps, runs editable installs, regenerates IDE configs, generates starter device configs |
| Prepare Workspace | Lower-level workspace prep: invokes scripts/prepare_workspace.py directly (advanced users; Setup is usually what you want) |
| Test Functional | Run all hardware-gated functional suites: test-libraries-functional then test-workbench-functional against devices.yml defaults |
| Test Libraries Functional | Run defaults-backed real-board functional tests for library code |
| Test Workbench Functional | Run hardware-gated functional tests for every workbench/*/functional_tests/ suite |
Output appears in the Terminal panel at the bottom of the window.
Running tests¶
From the task runner (with coverage)¶
Command Palette → Tasks: Run Task → Test. This runs all libraries with the coverage threshold and leaves a .coverage data file at the project root. To browse coverage visually, see Browsing coverage below.
From the test explorer (quick check, no coverage)¶
VS Code's Testing panel (beaker icon in the sidebar, or ⌘⇧T / Ctrl+Shift+T) discovers tests via the python.testing.pytestArgs setting in .vscode/settings.json.
Click the ▶ button next to any test file or function to run it. This is fast for iterating but does not produce coverage data or enforce the coverage threshold.
For real-board functional_tests/, the same Testing panel can target the explicit functional_tests/ file, directory, or function. The repository's pytest device plugin intercepts those targets and routes them to hardware. The test tree shows extra Setup: <runtime> and Run overhead: <runtime> nodes alongside the individual tests.
If no device is configured yet, pytest skips the run with a message telling you to generate or fill in devices.yml. See Device Testing for setup, the schema, and CLI options.
From the terminal¶
The integrated terminal (⌃` / Ctrl+`) works the same as any terminal:
Validating your work¶
Quick validation (during development)¶
- Click ▶ next to your test in the Testing panel
- Green ✓ = passing, red ✗ = failing
- Click a failed test to see the assertion error
Full validation (before opening a PR)¶
Command Palette → Tasks: Run Task → Preflight.
When it passes, the terminal shows:
When it fails, the terminal shows the failing step. The development loop in the contributing guide covers how to read the common failures (coverage gaps, ruff style violations, griffe docstring warnings, a missed VERSION bump, cross-runtime breaks) and how to reproduce each. Terminal links are clickable: Ctrl+click / ⌘+click a file:line reference to jump straight to it.
Step-by-step validation¶
If preflight fails, run individual tasks to isolate the problem:
- Command Palette → Tasks: Run Task → Lint
- Command Palette → Tasks: Run Task → Test
- Command Palette → Tasks: Run Task → Verify Examples
- Command Palette → Tasks: Run Task → Docs
Or use the terminal for more control:
# Test one library with the coverage gate
python scripts/run.py test --libraries timing
# Day-to-day iteration (no coverage gate)
pytest libraries/timing/tests/ -k heartbeat -x -v
Device functional tests from the terminal or task runner¶
The committed VS Code workspace also includes a Test Libraries Functional task, which runs:
That command uses the defaults: section in devices.yml to choose the target runtime(s), board(s), and default deploy mode.
Common overrides:
python scripts/run.py test-libraries-functional --library timing
python scripts/run.py test-libraries-functional --runtime both
python scripts/run.py test-libraries-functional --circuitpython-device desk-cp-board
python scripts/run.py test-libraries-functional --library timing --deploy-mode flash
Useful shortcuts¶
| Action | macOS | Windows/Linux |
|---|---|---|
| Open Command Palette | ⌘⇧P |
Ctrl+Shift+P |
| Open terminal | ⌃` |
Ctrl+` |
| Run task | ⌘⇧P → "Tasks: Run Task" |
Ctrl+Shift+P → "Tasks: Run Task" |
| Go to file | ⌘P |
Ctrl+P |
| Go to symbol | ⌘⇧O |
Ctrl+Shift+O |
| Find in files | ⌘⇧F |
Ctrl+Shift+F |
| Toggle test explorer | ⌘⇧T |
Ctrl+Shift+T |
Browsing coverage¶
Running the Test task (or python scripts/run.py test from the terminal) produces a .coverage data file at the project root. To see it in the editor gutter, install the Coverage Gutters extension, generate an XML report with python -m coverage xml, and toggle the display with the Coverage Gutters: Display Coverage command. Coverage Gutters reads coverage.xml and highlights covered and uncovered lines directly in the editor. (coverage.xml is gitignored.)
For the HTML report and the rest of the coverage workflow, see Browsing coverage in the Style Guide.
Quirks and tips¶
- Pylance may show false-positive errors for
micropythonimports (e.g.,from micropython import const). These modules only exist on-device. The code handles this with try/except at the module level. - Test discovery in the sidebar may be slow on first open. Wait for Pylance to finish indexing (check the status bar).
- If a new library is added, run
python scripts/run.py sync-ideto regeneratepyrightconfig.jsonand.vscode/settings.json. Reload the window afterward. .vscode/tasks.jsonand.vscode/settings.jsonare committed and shared. Workspace-specific settings (.vscode/launch.json, etc.) are gitignored if not present.- Terminal links are clickable. When a lint error or test failure shows
file.py:42,Ctrl+click/⌘+clickto jump directly to that line. - Device-testing support is wired through ordinary pytest. The committed VS Code settings and tasks are generated from
sync-ide, and explicitfunctional_tests/targets go through the same plugin path PyCharm uses. A dedicated live VS Code validation pass remains on the project plan, so VS Code-specific bugs are worth reporting.