Skip to content

native: annotate local functions; a real program through mypy - #163

Merged
simontreanor merged 1 commit into
mainfrom
lowering/native-local-annotations
Sep 28, 2026
Merged

simontreanor merged 1 commit into
mainfrom
lowering/native-local-annotations

Conversation

@simontreanor

Copy link
Copy Markdown
Owner

Takes --native further toward a real program, using the private Scrabble game (locally only; the game repo is untouched and nothing of it goes to CI) as the audit.

Changes

  • Block-local functions are annotated as they lower: lower_binding_as has the binding, its span and so its type. User-type spellings are computed up front (native_type_spellings) and typed_signature is shared with the top-level pass.
  • Unit results stay unannotated. Pyfun returns a unit call's value (return sys.stdout.flush()), which mypy rejects under -> None.
  • Native projects' shared runtime (_pyfun_rt.py) gets Any fields too (runtime_module_native). Without it, every Option payload arrived typed object.
  • pyfun build also disables three mypy error codes that only restate the Python boundary: func-returns-value (_ = f(x) for unit calls), var-annotated and union-attr (module-level values mypy can't infer, typeshed unions at extern calls). The extern declarations are the contract there, and Pyfun's checker has already enforced them.

The audit: the game's native output went from 64 mypy errors to 0 (12 files), and all 5 recorded replays print identically in both builds. mypyc itself then stops on Cannot determine type for module-level values another module reads at import time (nullary singletons like board._QW, layout tables), even though plain mypy is happy. That's recorded in ROADMAP as the next native blocker.

Test: native_annotates_block_local_functions_and_leaves_unit_returns_bare. DESIGN §5.6 and ROADMAP updated.

Functions defined inside functions are annotated in native mode as they lower
(lower_binding_as has the binding and its type), with the user-type
spellings computed up front. Unit results are left unannotated, since mypy
rejects returning a unit call's value under -> None. In a native project the
shared runtime's data class fields say Any too. pyfun build passes mypyc three
more flags that disable error codes restating the Python boundary
(func-returns-value, var-annotated, union-attr).

With these, the native output of the 11-module Scrabble game passes mypy's
front end (64 errors to 0) and its replays print the same. mypyc itself stops
on module-level values another module reads at import time, recorded in
ROADMAP as the next blocker.
@simontreanor
simontreanor merged commit 65ccb35 into main Sep 28, 2026
21 checks passed
@simontreanor
simontreanor deleted the lowering/native-local-annotations branch September 28, 2026 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant