Latest Results
Keep int bounds exact, like the Decimal ones
`ensure_is_finite_numeric` converted int bounds with `PyLong_AsDouble`
and never checked the result. For an int outside the range of a double
the `OverflowError` was left pending and the function still returned
true, so `Meta(gt=10**400)` surfaced as `SystemError`, and for
`multiple_of` the `-1.0` sentinel tripped the `<= 0` check and reported
a large positive bound as non-positive. On this branch the misreport got
worse: `Meta(gt=10**400, lt=Decimal("5"))` blamed `decimal.Decimal`.
Rejecting those ints is not an option here, because `Meta` already
treats the two spellings as one value: `Meta(gt=10**400)` and
`Meta(gt=Decimal("1E+400"))` compare equal, hash equal, and collapse to
a single object inside `Annotated`. Accepting one and refusing the other
would also contradict this branch's own argument that a double is the
wrong gate for large-but-finite bounds.
So drop the double entirely for ints. Every int is finite, and the only
remaining check, positivity for `multiple_of`, is done exactly against
zero, which is what the Decimal branch already does; that block is
factored out into `ensure_is_positive` and shared.
Whether a bound is usable stays a per-type question, decided where the
annotated type is known, as it already was for `Meta(gt=2**64)`: int64
for `int` targets, float64 for `float` targets, exact for `Decimal`
targets. `_constr_as_f64` grows the missing half of that, turning the
overflow into the same kind of message `_constr_as_i64` already gives
instead of relying on an invariant that only held because the bug
crashed first.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Fix SystemError when convert()'ing an out-of-range int to float (#1162)
## Summary
`msgspec.convert(obj, float)` converts a Python `int` to a C `double`
via `PyLong_AsDouble` without checking for overflow. For an `int` too
large to represent as a finite `float` (e.g. `10**400`),
`PyLong_AsDouble` sets `OverflowError` internally but still returns
`-1.0`, and that value was passed straight through to `ms_decode_float`
and returned to the interpreter with the exception still set ā which
surfaces as:
```
SystemError: <built-in function convert> returned a result with an exception set
```
This bypasses the documented `ValidationError` contract entirely, so a
caller wrapping the call in `except msgspec.ValidationError` doesn't
catch it.
`json.decode` already handles the equivalent case correctly, raising
`ValidationError: Number out of range`. This PR applies the same "check
`PyErr_Occurred()` after a lossy C conversion, then report via
`ms_error_with_path`" pattern already used elsewhere in this file (e.g.
`_constr_as_f64`), so `convert()` reports the overflow the same way ā
for both bare (`convert(big, float)`) and nested (`convert({"x": big},
dict[str, float])`) targets, under both `strict=True` and
`strict=False`.
Fixes #1122.
## Testing
- Reverted the fix locally and reproduced the exact reported
`SystemError` before reapplying it.
- Added `test_float_from_int_out_of_range` to `TestFloat` in
`tests/unit/test_convert.py`, covering bare and nested targets under
both strict modes.
- Ran the full `tests/unit/` suite: 6052 passed, 473 skipped, 0
failures. Add missing 0.22.0 changelog entries (#1171)
The 0.21.1 to 0.22.0 changelog batch (#1112) landed on 2026-07-03. Four
user-visible changes merged between then and the 0.22.0 release on
2026-08-11 never got an entry:
- #700, overloads on the `Meta` stub, so type checkers reject mixing
`gt` with `ge` and `lt` with `le`
- #1028, `null` placed last in the `anyOf` generated for optional unions
- #1114, `__struct_encode_fields__` added to `src/msgspec/__init__.pyi`
(its companion #813 only touched `tests/typing`, so it needs no entry of
its own)
- #1118, `json.encode` raising `TypeError` for a `dict` keyed by a plain
`str`-valued `enum.Enum`
I went over every PR merged in that window. The rest need no entry: #813
and #1117 are tests only, #1121 fixes an unreleased regression from
#1028, #1145 is an unused variable under free-threaded builds, and #1146
and #1148 are CI and tooling. #1127, #1135 and #1080 already have
entries.
Docs build clean with `--fail-on-warning`.
Note for whoever retries the release: the section is still headed
`Version 0.22.0 (2026-08-11)`, and that date will need updating, since
the tag was deleted after the upload failed. Refs #1134.
Co-authored-by: Siyet <Siyet@users.noreply.github.com> Latest Branches
0%
fix-profile-workflow-benchmark-flags 0%
Brohammad:fix-raw-yaml-decode-error -10%
Ā© 2026 CodSpeed Technology