Docs Contributing

Contributing

Dev setup, test conventions, and style guide for KynML.

Dev Environment

git clone <repo>
cd kynml
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e '.[dev,serving,mcp,hf,objectstore]'

Python 3.11+ is required (the codebase uses X | Y union type hints throughout).

The dev extra installs pytest. The other extras are needed to run the full test suite, which includes connectivity tests for the serving and MCP modules.

Running Tests

.venv/bin/python -m pytest -q

The suite must stay green. The target is 83+ passing tests. Check before and after every change:

.venv/bin/python -m pytest -q --tb=short

Run a single test file:

.venv/bin/python -m pytest tests/test_codegen.py -v

Test Files

File Covers
tests/test_parser.py Tokenisation, all value types, error paths
tests/test_semantic.py All validation rules, typo suggestions
tests/test_codegen.py Generated script content, layer rendering, optimizer/loss/scheduler/AMP/checkpoint/early_stop snippets
tests/test_core_features.py End-to-end compile from example specs
tests/test_examples.py Roundtrip parse+validate on all examples/*.kyn files
tests/test_connectivity.py kynml.serving, kynml.mcp, kynml.integrations module contracts (no heavy deps needed — imports are mocked where necessary)
tests/test_cli_train.py CLI commands via subprocess

Adding a Test

New behaviour must come with at least one test. Place tests in the most specific existing file. If a test file does not exist for your area, create one under tests/.

Follow the existing style:

def test_new_activation_renders_correctly() -> None:
    spec = """
dataset D:
    source = csv("data.csv")
    target = "y"

model M:
    input 4
    dense 8 silu
    dense 1 linear

train:
    model = M
    data = D
    loss = mse
    optimizer = adam(lr=0.001)
    epochs = 1
    batch = 8
""".strip()
    from kynml.parser import parse_text
    from kynml.semantic import validate_program
    from kynml.codegen.pytorch import generate_pytorch
    program = parse_text(spec)
    validate_program(program)
    script = generate_pytorch(program)
    assert "nn.SiLU()" in script

Code Style

  • No type: ignore except for third-party imports that lack stubs. Annotate all public functions.
  • Frozen dataclasses for all AST nodes — no mutable state in the AST.
  • Pure functions in parser, semantic, and codegen where possible — all I/O lives in the thin wrappers (parse_file, write_pytorch, generate_service).
  • f-strings for code generation — do not use % or .format().
  • Lazy imports for optional dependencies — import inside the function, not at module top level, in serving/, mcp/, and integrations/. This is enforced by the architectural boundary: import kynml without extras must not pull in fastapi or the MCP SDK.
  • KynMLError hierarchy — all user-visible errors must be a subclass of KynMLError.

Extending the Language

See Compiler Internals for the exact files and functions to modify when adding activations, losses, optimizers, schedulers, layer types, or export formats.

The change checklist for a new activation (the simplest change):

  • [ ] Add to SUPPORTED_ACTIVATIONS in kynml/semantic.py
  • [ ] Add mapping entry in _activation_expr() in kynml/codegen/pytorch.py
  • [ ] Add a test in tests/test_codegen.py asserting the emitted nn.* class
  • [ ] Add an example or entry in the Cookbook if the feature warrants one
  • [ ] Run pytest -q and confirm green

Commit Style

One logical change per commit. Short imperative subject line (≤72 chars). No AI attribution trailers, no robot emoji, no "Generated with" footers.

feat: add silu activation and nn.SiLU() codegen
fix: reject batchnorm before first input layer
docs: add onecycle scheduler cookbook recipe
test: cover fp16 AMP codegen path

Docs

Wiki pages live in docs/wiki/. Update the relevant page when changing user-visible behaviour. Keep code examples verified — paste the spec into the compiler and confirm it validates before committing.

See Also