Add the option to compile key modules to C using mypyc#2134
Open
chadrik wants to merge 16 commits into
Open
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2134 +/- ##
==========================================
+ Coverage 61.32% 61.44% +0.11%
==========================================
Files 164 166 +2
Lines 20568 21528 +960
Branches 3575 3689 +114
==========================================
+ Hits 12613 13227 +614
- Misses 7084 7386 +302
- Partials 871 915 +44 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
chadrik
commented
Jun 15, 2026
|
|
||
|
|
||
| def get_latest_package(name: str, *, range_: VersionRange | None = None, | ||
| paths: list[str] | None = None, |
Contributor
Author
There was a problem hiding this comment.
This is a breaking change: range_, paths, and error are now keyword-only arguments. You can no longer pass values by position. This was done because the alternative is a very long list of overloads covering all the permutations of positional and keyword scenarios.
Signed-off-by: Chad Dombrova <chadrik@gmail.com>
77f594b to
adfd9e0
Compare
Signed-off-by: Chad Dombrova <chadrik@gmail.com>
Signed-off-by: Chad Dombrova <chadrik@gmail.com>
Signed-off-by: Chad Dombrova <chadrik@gmail.com>
Signed-off-by: Chad Dombrova <chadrik@gmail.com>
The bulk of the mypyc port: replace custom metaclasses with __init_subclass__ plus explicitly written-out resource members, migrate from the home-grown cached_property to functools.cached_property, add mypyc_attr directives, native-class type-narrowing asserts/casts, split PackageOrderList out into package_order_list.py, and assorted runtime fixes. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
Add a 'mypyc' axis to the installation and tests workflows so CI exercises both the pure-python build (REZ_MYPYC=0) and the mypyc-compiled build (REZ_MYPYC=1) across the full OS x Python matrix. fail-fast is off, so each configuration reports independently and we can see exactly which ones the compiled build supports. Point the pyproject build requirement at our mypy fork (github.com/chadrik/mypy@rez-mypyc-fixes), which carries the fixes needed to compile rez. This makes an isolated build (pip install ., install.py, ...) automatically pick up the right mypy when building with mypyc, with no extra CI steps. Verified end to end: an isolated REZ_MYPYC=1 build pulls the fork and produces the compiled extensions. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
Bump the mypy used by the static-analysis workflow from 1.14.1 to 2.1.0, the version our mypyc fork is based on, so type-checking matches what the compiled build sees. mypy 2.1 requires the type-check target (tool.mypy python_version) to be 3.10+, so it can no longer be rez's lowest supported runtime (3.8); set it to 3.10. Regenerate mypy-baseline.txt against mypy 2.1.0 (the error set differs from 1.14.1: 594 -> 234 baselined entries). Verified the baseline keeps the mypy workflow green (mypy | mypy-baseline filter reports no new errors). Signed-off-by: Chad Dombrova <chadrik@gmail.com>
Add a mypyc=true/false matrix axis to the benchmark workflow so the resolving benchmark runs for both the compiled and pure-python builds. mypyc requires Python >= 3.10, so the run moves from 3.7 to 3.10 and both variants run there for an apples-to-apples comparison. REZ_MYPYC is wired into the install step, and result artifacts are named per-variant. The store job keeps the pure (mypyc=false) result as the canonical baseline, since store_benchmark.py keys results by python+rez version only. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
The @atexit.register decorator on _atexit (and the atexit import) had been commented out during the mypyc work. util.py is not compiled, so there is no reason to disable it; restore it so the tmpdir cleanup runs at exit as it does on main. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
self.vcs is Optional. The mypyc work added an `if self.vcs:` guard around the changelog lookup to satisfy the type checker. Confirm it is also safe at runtime: get_release_data only reaches get_changelog after an early vcs-is-None return, and the rez-release caller already catches and nulls a failed changelog. Record that reasoning in a comment so the guard is not mistaken for an unexplained behaviour change. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
range_, paths and error became keyword-only during the typing work (the error value determines the return type, and covering every positional and keyword permutation with overloads is impractical). This is a breaking change, so record it and the rationale in the docstring rather than leaving it as an unannounced signature change. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
The auto-generated Package.version accessor had been hand-corrected from the
schema-derived 'Version | None' to 'Version': a package always exposes a
Version, but 'version' is Optional in the pod schema so the generator emitted
'Version | None'. Hand-editing generated source is fragile (it is wiped on
regeneration), so add a declarative FORWARDER_TYPE_OVERRIDES map to the
generator and register ("Package", "version") -> "Version". The generator now
emits the correct type itself, and the manual-correction note is removed.
Signed-off-by: Chad Dombrova <chadrik@gmail.com>
ResolverStatus stores a human-readable description as the first (and only) element of each member's tuple value, but the accessor for it was left as a commented-out Enum __init__. Expose it as a `description` property returning value[0] instead, and drop the dead __init__ stub. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
Mirror ResolverStatus: SolverStatus members carry their human-readable description as the first element of their tuple value. Expose it via a `description` property so callers can read it without reaching into .value. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
The @pool_memcached_connections decorator had been removed from iter_package_families and iter_packages during the mypyc work. Both are generators, and mypyc cannot compile a decorated generator method that overrides a base-class method: it raises KeyError in handle_ext_method while reconciling the override signature. That is why the decorator was dropped. Restore the pooling in a mypyc-compatible way by inlining a memcached_client() context manager around each generator body, so a single client is pooled for the whole iteration while the method stays a plain, compilable generator. Verified by a full mypyc build plus selftest. Signed-off-by: Chad Dombrova <chadrik@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Here is an interesting payoff from my recent type annotations PR that was merged: we can now use
mypycto compile key libraries into C for added performance.Running the benchmarks locally I see a speedup of about ~2.6x.
Notes:
Obviously, if this gets released we'll need a plan for gradual deployment/adoption in order to release something this radical. Gradual adoption is one of the big advantages of using something like mypyc over rewriting specific modules in rust: the business logic and API interface remains the same between pure python and C-extension, compilation is just a installation setting. Here are some thoughts: