[Contributing]

Hard constraints, workflow, and style rules for contributors and agents working on PYNE.

Contributing

Abstract

Contributions to PYNE are welcome when they respect the repo’s mechanical invariants: generated code boundaries, src-layout packaging, dual console scripts, test corpus costs, and encryption secrets. This page distills CONTRIBUTING.md and AGENTS.md into an operational contract for humans and agents.

Conceptual model

Interface surface

Baseline workflow

  1. Fork and branch from main
  2. Install: make install or hatch envs
  3. Run tests: make test / hatch run test:test
  4. Implement with tests (prefer TDD for non-trivial behavior)
  5. Lint/format: make lint / make fmt or hatch run lint:style + lint:typing
  6. Open a PR with rationale + test evidence

Official short form also lives in root CONTRIBUTING.md (points at Sphinx docs historically).

Everyday commands

GoalCommand
Editable install + LSPmake install
Full testsmake test
LSP onlymake test-lsp
Backend onlymake test-backend
Lint / formatmake lint / make fmt
Fast build sanitymake build-check
APImake run
LSP processmake run-lsp

Hard constraints

Grammar & generated code

  • Edit only src/pynescript/ast/grammar/antlr4/resource/*.g4 for grammar work
  • Never hand-edit …/antlr4/generated/ or …/asdl/generated/
  • Regenerate via hatch lint:gen-parser / project scripts; see grammar guides under .opencode/context/

No stale backups

Do not recreate removed backups such as builder.py.bak or evaluator/builtins/technical_refactored.py. Live builder.py and technical.py are sole sources of truth.

Future annotations

Every new Python file must start with:

from __future__ import annotations

Enforced by ruff isort required-imports.

Console scripts

ScriptRole
pynescriptClick CLI
pynescript-lspLanguage Server (pygls)

Do not conflate entrypoints in docs, packaging, or process managers.

Test corpus fixture

tests/conftest.py parametrizes pinescript_filepath over every tests/data/builtin_scripts/*.pine. A new test using that fixture may run hundreds of cases. Narrow with --example-scripts-dir=... when iterating.

tests/data/library/ is reference material, not auto-parametrized.

Builtin metadata

builtin_metadata.json is generated from code. After adding builtins:

python scripts/generate_builtin_metadata.py

Do not hand-maintain the catalog long-term.

Secrets & crypto

  • scripts/build/.metadata.key is gitignored
  • CI must supply stable CRYPTO_KEY from METADATA_KEY / _METADATA_KEY for reproducible .enc blobs
  • Never commit Fernet keys or API admin tokens

Internals (where to change what)

Want to…Look at
Parse / unparsesrc/pynescript/ast/helper.py
Add builtinsrc/pynescript/ast/evaluator/builtins/<ns>.py + metadata generator
LSP featuresrc/pynescript/langserver/features/ + server.py
CLI subcommandsrc/pynescript/__main__.py
Grammarresource/*.g4 then regenerate
Pro API routebackend/api/preview.py, backend/app.py
TS portpine-worker/

Style

  • Ruff line length 120; broad rule set in pyproject.toml
  • Black target py310 (via toolchain config)
  • Mypy strict-ish; exemptions for generated grammar, evaluator.builtins.*, tests
  • Voice for docs: academic nerdy-cool per docs/WRITING.md — no empty marketing adjectives

pine-worker contributions

  • Bun for install/test/typecheck
  • Python remains oracle; update parity fixtures via generator
  • Converter stubs are starting points only

Failure modes for contributors

MistakeFallout
Editing generated ANTLR/ASDLOverwritten / review hell
Skipping corpus cost awareness10-minute “unit” tests
Hand-editing metadata JSONDrift from dispatch
Committing .metadata.keySecret leak; rotate immediately
PR without lintCI red on ruff/mypy

See also