-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Permalink
Choose a base ref
{{ refName }}
default
Choose a head ref
{{ refName }}
default
Checking mergeability…
Don’t worry, you can still create the pull request.
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
base repository: python/mypy
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
...
head repository: python/mypy
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: release-2.1
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
- 6 commits
- 30 files changed
- 8 contributors
Commits on May 9, 2026
-
[mypyc] Add librt.random module (#21433)
The stdlib `random` module is fairly often used in performance critical code, and it's not super efficient. Add `librt.random` with a subset of the stdlib module interface that is optimized for performance when compiled. Use ChaCha8 as the algorithm. Based on some research, this is a modern, high-quality PRNG algorithm. It's used by Go `math/rand/v2`, among others. This is a non-cryptographic PRNG, similar to the stdlib `random` module (but this uses a different algorithm). I used Claude Code and Codex to write all the code, but I iterated on it quite a lot and did a bunch of manual validation and code review. I also asked Codex to explicitly check that the ChaCha8 implementation is correct by comparing it to a reference implementation. Use thread-local RNG state for module-level functions to enable good scaling in free-threaded builds. There's some extra complexity from having to free the state at thread exit. I asked a LLM to generate and run a benchmark, and here are the results on 3.14: ``` │ Function │ vs stdlib(compiled) │ vs stdlib(interpreted) │ │ random() │ 3.2x │ 4.8x │ │ randint() │ 16.6x │ 18.0x │ │ randrange() │ 14.5x │ 16.2x │ │ choice() │ 12.9x │ 10.3x │ ``` `choice()` was replaced with `randrange` when using `librt`, since we don't provide it as part of this fairly minimal API.Configuration menu - View commit details
-
Copy full SHA for 4b8fdca - Browse repository at this point
Copy the full SHA 4b8fdcaView commit details
Commits on May 10, 2026
-
Fix function call message change for small number of args (#21432)
Refs #21427 I used `2` as a magic number, because in my opinion it is easier to tell the difference when all errors show up for the small number of args. --------- Co-authored-by: hauntsaninja <hauntsaninja@gmail.com>
Configuration menu - View commit details
-
Copy full SHA for 6c4af8e - Browse repository at this point
Copy the full SHA 6c4af8eView commit details -
Configuration menu - View commit details
-
Copy full SHA for 116d60b - Browse repository at this point
Copy the full SHA 116d60bView commit details -
Respect file config comments for stale modules (#21444)
In mypy 1.19, re-running `mypy` with a saved cache and a file containing an inline configuration comment (e.g. `# mypy: disable-error-code="import-not-found"`) acted 'correctly', i.e. the same behaviour on the first run vs subsequent runs. In mypy 1.20 and newer, this is no longer the case. Running `mypy` with a pre-existing cache fails to respect inline configuration comments for stale modules, leading to confusing false-positive errors that can be hard to debug. This PR introduces a failing test as at current master, and then a fix for the issue. I believe this is the right fix, though happy to change as suggested by the maintainers, I'm not nearly as familiar with mypy internals. Notably also from L2376-80, it's by design that file-level comments aren't cached: ```python # Note that the options we store in the cache are the options as # specified by the command line/config file and *don't* reflect # updates made by inline config directives in the file. This is # important, or otherwise the options would never match when # verifying the cache. ``` I believe that this regression was introduced in #20773 A Co-authored-by: Adam Turner <turner@hudson-trading.com>Configuration menu - View commit details
-
Copy full SHA for 8152f4a - Browse repository at this point
Copy the full SHA 8152f4aView commit details -
[mypyc] Enable incremental self-compilation (#21369)
Six fixes on top of #21299, all required to self-compile mypy or to install a `separate=True` wheel via pip. - `mypyc/build.py`: pip invokes `setup.py` twice when building a wheel. On the second invocation mypy's incremental cache is fully warm, so we generate no new C source for any group; the resulting extensions ship without their entry points and import as stubs. - **Fix**: when a group emits no C source, reuse the .c file from the previous pass. - `mypyc/codegen/{emit,emitfunc}.py`: when code in one compiled group reads an attribute on an object whose class lives in another group, the generated cast depends on that other group's struct definitions. We weren't recording the dependency, so the C compiler couldn't see the layout and the build failed. - **Fix**: register the dependency at the cast site. - `mypyc/codegen/emitmodule.py`: when mypy compiles itself, a generated shim file can share a basename with a runtime C file. The C compiler resolves the runtime include relative to the shim's directory and picks up the shim instead. - **Fix**: search the include path explicitly so shims can't shadow runtime files. - `mypyc/lib-rt/misc_ops.c`: each compiled module gets its own shared library next to it in the package tree. The runtime was computing the module's file path as if a single shared library sat above the whole package, which doubled the package prefix and broke submodule lookups. - **Fix**: detect the per-module case and use only the module's leaf name. - `mypyc/irbuild/prepare.py`: traits and builtin-derived classes don't get a real C constructor emitted. A clean build sidesteps that, but a fully cached rebuild was taking the direct-call path and producing C that referenced a constructor that doesn't exist. - **Fix**: skip the registration the same way a clean build does. - `mypyc/build.py`: on every build_ext, setuptools rewrites every compiled .so in the source tree even when nothing changed. On macOS this invalidates the OS signature cache, so every import on the next run pays a re-verification cost. - **Fix**: skip the copy when source and destination already match, taking a 1-line edit rebuild from ~72s to ~6s. This is really a `setup` tools limitation though (relevant [mypy issue](mypyc/mypyc#1068) ?) I also added a `MYPYC_SEPARATE` env knob so CI can exercise the codegen path against mypy itself. ## Benchmarks Mypy self-compile on macOS, `MYPYC_OPT_LEVEL=0`, `-j 11`. Three scenarios: | | monolithic | separate=True | |:---:|:---:|:---:| | Clean build | 180s | 108s | | No-op rebuild | 124s | 5s | | 1-line edit | 106s | 6s |
Configuration menu - View commit details
-
Copy full SHA for 2b1eb58 - Browse repository at this point
Copy the full SHA 2b1eb58View commit details -
Configuration menu - View commit details
-
Copy full SHA for 3f4067b - Browse repository at this point
Copy the full SHA 3f4067bView commit details
Loading
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff master...release-2.1