[Local development]

Install, test, lint, and run PYNE surfaces on a developer machine — Make, hatch, Bun, and dual-language loops.

Local development

Abstract

A PYNE checkout is a polyglot workspace: Python (src-layout package + Flask backend), TypeScript/Bun (AXIS frontend, Cloudflare worker, pine-worker), and Node (VS Code extension). Local DevOps is about choosing the right orthography for the surface you are changing without spinning up the entire mesh.

Conceptual model

Interface surface

Make targets (primary)

TargetEffect
make installpip install -e ".[lsp]"
make install-bunRoot + frontend/worker Bun deps
make testFrontend Bun tests + full pytest tests/
make test-lsptest_langserver.py + test_lsp_features.py
make test-backendtests/test_backend.py
make lint / make fmtRuff check / format on src/, tests/, backend/
make typecheckRoot TS + frontend worker tsc
make buildNuitka LSP via scripts/build/compile.py --jobs=4
make build-checkFast import resolution only (~30s)
make build-vscodeCompile + package VSIX
make runpython -m backend.app
make run-lsppython -m pynescript.langserver
make run-frontendAXIS PWA on :8081 (expects API on :5002)
make docker-builddocker buildx bake api (production image)
make docker-build-allbake api + api-dev + lsp
make docker-buildxmulti-platform release bake
make docker-up / docker-runcompose API on :5002 (dev target)
make docker-up-fullcompose with redis profile (not lsp)
make docker-prodgunicorn overlay, no source mounts (needs ADMIN_TOKEN)
make docker-smokecurl healthcheck on :5002
make docker-down / docker-logsstop stack / follow API logs

Hatch equivalents

hatch run test:test
hatch run test:test-cov
hatch run lint:style
hatch run lint:typing
hatch run lint:gen-parser   # ANTLR regeneration — see grammar guide

See also CONTRIBUTING.md and AGENTS.md for hatch-first workflows.

Internals

PathWhy it matters locally
src/pynescript/Editable package root (src-layout)
tests/conftest.pyParametrizes pinescript_filepath over every tests/data/builtin_scripts/*.pine (~hundreds of cases)
tests/data/library/Reference corpus only — not auto-parametrized
backend/requirements.txtExtra deps for Pro API (Flask, numpy, matplotlib, …)
pine-worker/Colocated TS port; Bun tests independent of Python wheel

Python requirements

  • Requires-Python: >=3.10 (pyproject.toml)
  • CI matrix: 3.10–3.13
  • Recommended local: 3.12 or 3.13 with a virtualenv / hatch env

Optional extras

pip install -e ".[lsp]"       # pygls + lsprotocol
pip install -e ".[dev-lsp]"   # + pytest-lsp for e2e LSP
pip install -e ".[data]"      # ccxt for data providers
pip install -r backend/requirements.txt

Invariants & edge cases

  1. from __future__ import annotations is mandatory on every new Python file (ruff isort required-imports).
  2. Do not edit generated grammar. Change only src/pynescript/ast/grammar/antlr4/resource/*.g4, then regenerate.
  3. No stale backups in src/. Live builder.py and technical.py are sole sources of truth.
  4. Corpus fixture cost. Any test using pinescript_filepath multiplies across the builtin script corpus. Narrow with --example-scripts-dir=... when iterating.
  5. Console scripts are separate. Installing .[lsp] gives both pynescript and pynescript-lsp; invoking the wrong one is a common first-day footgun.

Worked examples

Library + parse round-trip

make install
python -c "from pynescript.ast.helper import parse, unparse; print(unparse(parse('//@version=6\nindicator(\"x\")\nplot(close)')))"

Pro API + AXIS

# terminal 1
make run
# terminal 2
make run-frontend
# open http://127.0.0.1:8081 — /run hits backend on :5002 per compose/docs convention

LSP without Nuitka

make install
make run-lsp
# point editor to stdio server: python -m pynescript.langserver

pine-worker only

cd pine-worker
bun install
bun test
bun run typecheck

Failure modes

SymptomCauseMitigation
ModuleNotFoundError: pynescriptNot editable-installedmake install
Hundreds of unexpected test failuresEditing shared conftest fixtureIsolate unit tests; avoid corpus fixture
Frontend fails calling APIBackend not on expected portStart make run; check CORS / ALLOWED_ORIGINS
antlr4 not foundCLI not on PATHUse hatch lint:gen-parser or full path to antlr4
Ruff I import errorsMissing future annotationsAdd from __future__ import annotations

See also