Skip to content

Tags: msgspec/msgspec

Tags

0.22.0

Toggle 0.22.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Fix a reference leak of a non-Struct base's type dict (#1199)

On Python 3.12+ `MS_GET_TYPE_DICT` expands to `PyType_GetDict`, which
returns a new reference; in the comment above the macro the result is
described as borrowed. At its only call site, in
`structmeta_collect_base`, there is no matching release on either exit,
so defining a `Struct` with a non-`Struct` base leaks one reference to
that base's type dict. Nothing holds that reference afterwards, so the
dict is never freed, and on 3.12 through 3.14 that keeps the base class
itself alive along with everything in its namespace, for the rest of the
process. `typing.Generic` counts as such a base, so generic `Struct`
definitions leak one too, in both the explicit and the PEP 695 spelling;
there the dict stays reachable regardless, so only the count grows.

Adds a release macro and applies it on both exits. It expands to
`Py_XDECREF` on 3.12+ and to nothing before that, where the `tp_dict`
slot is read directly and the reference is borrowed. Corrects the
comment to match. The remaining `tp_dict` uses in the file are direct
slot reads guarded against `NULL` and need no release.

A base that has not been readied yet, which a C extension can expose,
has no type dict, and on main the `__init__` and `__new__` check crashes
on such a base on every supported version. Such a base is now rejected
with `TypeError` before its type dict or inherited slots are read, and
`TypeError` is also raised if a readied base still has no type dict. The
check that the base is a type now comes first.

Adds a regression test that the base's contents are released when the
base passes the `__init__` and `__new__` check. On current main it fails
on 3.12, 3.13 and 3.14, and passes on 3.10 and 3.11, where the leak does
not exist. It also passes on main on 3.15, where the leaked dict no
longer keeps the base class reachable, so the class is collected and its
contents are released even though the dict itself is still retained.

Fixes #1198.

---------

Co-authored-by: Tseluiko Aleksandr <4410812+Siyet@users.noreply.github.com>
Co-authored-by: sobolevn <mail@sobolevn.me>

0.21.1

Toggle 0.21.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Add changelog for 0.21.1 (#1020)

Co-authored-by: aleksandr.tseluyko <aleksandr.tseluyko@mysky.com>

0.21.0

Toggle 0.21.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Update changelog for release 0.21.0 (#1001)

0.20.0

Toggle 0.20.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Make GitHub action resilient to release runs (#953)

0.19.0

Toggle 0.19.0's commit message
Update changelog for 0.19.0

0.18.6

Toggle 0.18.6's commit message

Verified

This tag was signed with the committer’s verified signature.
jcrist Jim Crist-Harif
Version 0.18.6

0.18.5

Toggle 0.18.5's commit message
Update changelog for 0.18.5

0.18.4

Toggle 0.18.4's commit message
Release 0.18.4

0.18.3

Toggle 0.18.3's commit message
Release 0.18.3

0.18.2

Toggle 0.18.2's commit message
Release 0.18.3