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

aio-libs / multidict / 35507790002
87%

Build:
DEFAULT BRANCH: master
Ran 20 Sep 2026 11:26AM UTC
Jobs 1
Files 39
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

20 Sep 2026 11:25AM UTC coverage: 87.303%. Remained the same
35507790002

push

github

web-flow
Stop getall() from hiding a live key mid-update on free-threaded builds (#1484)

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

## What do these changes do?

On the free-threaded build, `getall()` and the
`items()`/`keys()`/`values()`
equality path shared a finder with `_md_replace()`'s and
`md_to_dict()`'s
internal marking protocol. A concurrent
`update()`/`extend()`/`__setitem__()`
call can have its critical section transiently suspended while an entry
it
just wrote is still marked as part of its own bookkeeping (a decref
triggering the allocator's own lock, see the existing comment in
`_md_replace()`), and a reader landing in exactly that window treated
the
mark as "not found" instead of "still there, in flight", raising
`KeyError`
for a key that was never deleted.

The shared finder now takes a readonly mode for
`getall()`/`md_finder_collect()`:
it matches identity with a masked hash comparison instead of a raw one,
and
never writes to the entry, tracking its own already-returned slots
locally
instead. `_md_replace()`, `_md_update()` and `md_to_dict()`'s inner scan
keep
the existing raw comparison and marking, since they can restart their
own
scan and need to tell an entry they already marked apart from a fresh
duplicate.

## Are there changes in behavior for the user?

No visible behavior change on the happy path. On the free-threaded
build,
`getall()` (and equality checks that materialize
`items()`/`keys()`/`values()`)
no longer spuriously raises `KeyError` for a live key racing a
concurrent
update to that same key.

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

No. The change is contained to `multidict/_multilib/hashtable.h` and
only
affects the free-threaded build's read-only finder path.

## Related issue number

While investigating this, testing under a much wider (artificially
delayed)
version of the race window surfaced a second, more serious, pre-existing
bug:
two threads calling `update()` on the *same* key concurrently... (continued)

762 of 1524 branches covered (50.0%)

Branch coverage included in aggregate %.

6320 of 6588 relevant lines covered (95.93%)

1.92 hits per line

Jobs
ID Job ID Ran Files Coverage
1 MyPy - 35507790002.1 20 Sep 2026 11:26AM UTC 78
87.3
GitHub Action Run
Source Files on build 35507790002
  • Tree
  • List 39
  • Changed 2
  • Source Changed 0
  • Coverage Changed 2
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #35507790002
  • f56ac581 on github
  • Prev Build on master (#35499797092)
  • Next Build on master (#35507866989)
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