Skip to content

Record ADR-010 and an opt-in mypyc-accelerated engine build#48

Draft
frenck wants to merge 1 commit into
mainfrom
frenck/adr-mypyc
Draft

Record ADR-010 and an opt-in mypyc-accelerated engine build#48
frenck wants to merge 1 commit into
mainfrom
frenck/adr-mypyc

Conversation

@frenck

@frenck frenck commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Breaking change

None. The default build stays pure Python and nothing is adopted. This adds an opt-in, dev-only accelerated build behind just build-fast.

Proposed change

Records ADR-010 and the actual opt-in build code behind it, capturing the mypyc exploration as a proposed, deferred decision so the validated path and its costs are written down rather than rediscovered later.

After the profile-driven perf work flipped construction to ~1.64x faster than voluptuous and held a ~2.3x validation lead, the profiles show the hot paths doing irreducible work (validation is ~47% one Python for loop). The next significant speedup is architectural.

An earlier spike compiled the four core modules (error, markers, _engine, schema) and reported ~1.30x construction and ~1.38x validation, but it never ran the test suite against the compiled build. Building it for real and running the full suite tells a narrower story: "compiles without error" is not "behaves correctly", and three of the four modules fail the suite once compiled.

  • error.py breaks the error model. The Invalid hierarchy reads its per-subclass default_code off the type object, which mypyc stores as an instance slot rather than a class attribute, so reading .code raises and the failure path segfaults. It is pure failure-path code, so compiling it buys nothing on the hot path.
  • schema.py cannot be compiled. Schema must stay non-native because DataclassSchema/TypedDictSchema and user code subclass it (mypyc forbids an interpreted class inheriting a compiled one), and a non-native Schema then trips an internal mypyc assertion on _compile_self's nested closure. This is the module that holds construction, the spike's headline.
  • markers.py compiles but silently breaks isinstance(x, Marker) on the non-native marker subclasses, so marker ordering and equality go wrong.

Only _engine.py, the validation hot loop, compiles cleanly: zero source changes, full behavioral parity (the whole suite passes against it). On a Home-Assistant-representative workload:

pure Python mypyc (engine only) gain
construction 0.87s 0.81s 1.08x
validation 0.80s 0.61s 1.29x

The payoff is validation, not the construction win the spike advertised, because construction lives in schema.py. The opt-in build is wired behind just build-fast, which runs scripts/build_accelerated.py to drop the compiled .so next to the source; just clean removes it.

Decision: pure Python stays the default and guaranteed fallback; the compiled engine is an opt-in accelerator and adoption is deferred. This PR stays a draft on purpose, so the record and the runnable build exist and can be picked up when the trade is worth it.

Type of change

  • Dependency or tooling upgrade
  • Bugfix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Deprecation (replaces or removes a feature, with a migration path)
  • Breaking change (a fix or feature that changes existing behavior)
  • Code quality, refactor, or test-only change
  • Documentation only

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to:
  • Link to a separate documentation pull request:

Checklist

  • I fully understand the code in this pull request and can explain every line, including any AI-assisted changes.
  • The change is covered by tests, and uv run --no-sync just test passes locally. A pull request cannot be merged unless CI is green.
  • uv run --no-sync just lint passes.
  • uv run --no-sync just typecheck passes.
  • No commented-out or dead code is left in the pull request.

Copilot AI review requested due to automatic review settings June 29, 2026 07:27
@frenck frenck added the documentation Solely about the documentation of the project. label Jun 29, 2026
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 30ebd200-b349-4688-9cc1-8424a5f252cb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch frenck/adr-mypyc

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codspeed-hq

codspeed-hq Bot commented Jun 29, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 12 untouched benchmarks


Comparing frenck/adr-mypyc (0ccaa18) with main (b711eab)

Open in CodSpeed

@codecov-commenter

codecov-commenter commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (b711eab) to head (0ccaa18).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #48   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           44        44           
  Lines         4670      4670           
  Branches       817       817           
=========================================
  Hits          4670      4670           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR records ADR-010, capturing the exploration of mypyc as an optional accelerated build as a proposed, deferred decision. It documents the validated path, the measured spike results (~1.30x construction, ~1.38x validation on the core modules), and the costs (per-platform wheels plus a pure-Python fallback) so the analysis is preserved rather than rediscovered. No code is adopted; pure Python remains the default and guaranteed fallback, consistent with ADR-004 and ADR-005.

Changes:

  • Add adr/010-mypyc-accelerated-build.md documenting the proposed/deferred mypyc decision, its rationale, consequences, and prerequisites.
  • Add ADR-010 to the index in adr/README.md, with table columns realigned to fit the longer title.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
adr/010-mypyc-accelerated-build.md New ADR recording mypyc as a proposed, deferred optional accelerated build; claims verified against current code.
adr/README.md Adds the ADR-010 index row and widens the table columns to accommodate the new entry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Captures the mypyc exploration as a proposed (not adopted) decision, with
the actual build code behind it.

An earlier spike compiled the four core modules and reported ~1.30x
construction and ~1.38x validation, but it never ran the suite against the
compiled build. Building it for real and running the full suite tells a
narrower story: only the validation engine compiles cleanly.

  error.py    breaks the error model. It reads default_code off the type
              object, which mypyc stores as an instance slot, so .code
              raises and the failure path segfaults.
  schema.py   will not compile a non-native Schema, which it must be, since
              DataclassSchema/TypedDictSchema and user code subclass it.
              mypyc trips an internal assertion on _compile_self's closure.
  markers.py  compiles but breaks isinstance on the non-native marker
              subclasses, so marker ordering and equality go wrong.

_engine.py, the validation hot loop, compiles with zero source changes and
full behavioral parity (the whole suite passes against it):

  construction  0.87s to 0.81s  1.08x
  validation    0.80s to 0.61s  1.29x

The payoff is validation, not the construction win the spike advertised,
because construction lives in schema.py. The opt-in build is wired behind
`just build-fast` (scripts/build_accelerated.py drops the compiled .so next
to the source; `just clean` removes it). Pure Python stays the default and
guaranteed fallback; adoption is deferred.
@frenck frenck force-pushed the frenck/adr-mypyc branch from 5ce608a to 0ccaa18 Compare June 29, 2026 09:22
@frenck frenck changed the title Record ADR-010: mypyc as an optional accelerated build Record ADR-010 and an opt-in mypyc-accelerated engine build Jun 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Solely about the documentation of the project.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants