• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aio-libs / multidict / 34481271608
87%

Build:
DEFAULT BRANCH: master
Ran 10 Sep 2026 01:13PM UTC
Jobs 1
Files 31
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

10 Sep 2026 01:13PM UTC coverage: 85.279% (+0.1%) from 85.141%
34481271608

push

github

web-flow
Protect MultiDict update()/extend()/merge()/clear() with a critical section (#1433)

<!-- Thank you for your contribution! -->

## What do these changes do?

Protects `MultiDict.update()`, `.extend()`, `.merge()`, `.clear()`,
`.copy()`,
and the `MultiDict`/`CIMultiDict` constructors (including the fast-clone
path and, for an explicit re-init on an already-published multidict, the
reset step) in the C extension with a critical section, so each
operation
is atomic from the point of view of other threads. When
update()/extend()/
merge() take a plain dict argument, that dict is locked too (in addition
to self), since PyDict_Next() is not thread-safe against a foreign
thread
concurrently mutating the dict being iterated.

## Are there changes in behavior for the user?

No behavioral change for single-threaded code. On the free-threaded
build of CPython, this fixes a real segmentation fault and/or data
corruption.

## Is it a substantial burden for the maintainers to support this?

No, it only touches the extend/update/merge/copy/clone/init
implementation
in the C extension and uses the critical section macros already vendored
via
`pythoncapi_compat.h`.

## Related issue number

Part of #1432

## Checklist

- [x] I think the code is well written
- [x] Unit tests for the changes exist
- [x] Documentation reflects the changes
- [ ] If you provide code modification, please add yourself to
`CONTRIBUTORS.txt`
- [x] Add a new news fragment into the `CHANGES/` folder
- [x] `make doc-spelling` passes and any new technical words are added
to `docs/spelling_wordlist.txt`

<details>
<summary>Agent run details (optional, for reviewers)</summary>

Reproduced the crash against `master` with a threaded stress script and
a
`gdb` backtrace pinpointing a NULL key/value read in
`_md_add_with_hash()`, using a genuine free-threaded CPython 3.13.7t
build (via pyenv), not just compiling the macros. Confirmed the fix
under the same build: 25+ stress runs and 3 `gdb`-driven runs wi... (continued)

638 of 1276 branches covered (50.0%)

Branch coverage included in aggregate %.

79 of 80 new or added lines in 1 file covered. (98.75%)

4321 of 4539 relevant lines covered (95.2%)

1.9 hits per line

Uncovered Changes

Lines Coverage ∆ File
1
91.03
0.27% tests/test_multidict.py
Jobs
ID Job ID Ran Files Coverage
1 MyPy - 34481271608.1 10 Sep 2026 01:13PM UTC 62
85.29
GitHub Action Run
Source Files on build 34481271608
  • Tree
  • List 31
  • Changed 2
  • Source Changed 1
  • Coverage Changed 2
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #34481271608
  • f3e65eb0 on github
  • Prev Build on master (#34468450272)
  • Next Build on master (#34588321475)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc