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

aio-libs / multidict / 34788665032
87%

Build:
DEFAULT BRANCH: master
Ran 13 Sep 2026 11:06PM UTC
Jobs 1
Files 33
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

13 Sep 2026 11:05PM UTC coverage: 85.827% (-0.01%) from 85.838%
34788665032

push

github

web-flow
Make pure-Python MultiDict safe under free-threading (#1447)

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

## What do these changes do?

Adds per-instance locking to the pure-Python `MultiDict`/`CIMultiDict`
fallback (`multidict/_multidict_py.py`) so it gives the same
crash-free, corruption-free guarantee as the C extension under a
free-threaded (no-GIL) build. Every method that touches an instance's
hash table takes that instance's own `RLock` (created once in
`__new__`, reused across a later re-init); two-object operations
(`update()`, `extend()`, `merge()`, `__eq__()`, copy construction) lock
both objects together in a fixed, deadlock-safe order; view iterators
take the lock per step rather than for the whole iteration, so a
concurrent mutation between steps surfaces as the same "changed during
iteration" `RuntimeError` a single-threaded caller already gets today
instead of a deadlock; and the version counter shared by every
instance gets its own lock. On a regular GIL-enabled interpreter the
locked methods are the exact same function objects as before this
change -- no wrapper, no lock, no measurable overhead.

## Are there changes in behavior for the user?

Yes, but only on a free-threaded build: concurrent use of a
pure-Python `MultiDict`/`CIMultiDict` from multiple threads is now
safe against crashes and data corruption, matching the C extension.
On a regular (GIL-enabled) build there is no behavior or performance
change.

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

No. The change is self-contained to `_multidict_py.py`, gated entirely
behind a runtime free-threading check computed once at import, and
mirrors the locking approach already reviewed and merged for the C
extension (#1438, #1441, #1445, #1446). The C extension itself is
unaffected; this only touches the pure-Python fallback.

## Related issue number

N/A -- no linked issue. Continues the free-threading hardening already
done for the C extension.

## Checklist

... (continued)

710 of 1420 branches covered (50.0%)

Branch coverage included in aggregate %.

329 of 342 new or added lines in 2 files covered. (96.2%)

5079 of 5325 relevant lines covered (95.38%)

1.91 hits per line

Uncovered Changes

Lines Coverage ∆ File
12
71.68
0.47% multidict/_multidict_py.py
1
92.4
0.14% tests/test_multidict.py
Jobs
ID Job ID Ran Files Coverage
1 MyPy - 34788665032.1 13 Sep 2026 11:06PM UTC 66
85.82
GitHub Action Run
Source Files on build 34788665032
  • Tree
  • List 33
  • Changed 3
  • Source Changed 2
  • Coverage Changed 3
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #34788665032
  • 1ecdbb05 on github
  • Prev Build on master (#34782403362)
  • Next Build on master (#34789454978)
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