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

aio-libs / multidict / 34334407335
87%

Build:
DEFAULT BRANCH: master
Ran 09 Sep 2026 09:24AM 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

09 Sep 2026 09:23AM UTC coverage: 85.099% (+0.03%) from 85.07%
34334407335

push

github

web-flow
Mark temporarily-removed entries via the hash's high bit, not -1 (#1426)

## What do these changes do?

Both backends marked a hash table entry invalid mid-update by
overwriting its hash with `-1`, then recomputed it from the identity to
restore it. This replaces that with a marker bit (the hash's high bit):
OR to set, AND to clear. That needs every hash non-negative first, so
hashes are folded once, right where computed (`& MAXSIZE` in Python,
inside `_unicode_hash()` in C). Restoring is then a bit-clear or a
direct assignment of an already-known value, never a recomputation.

Python's `hash()` is arbitrary precision, so a negative hash already
reads the high bit as set, which is why plain OR/AND needs the fold
first. C's `Py_hash_t` is fixed-width, so once folded, "is marked" is
just `entry->hash < 0`. `_unicode_hash()` folds only the value it
returns to multidict, never the unicode object's own cached hash slot
(shared process-wide). The ~15 `_unicode_hash(...) == -1` checks for a
genuine hash-computation error are untouched — a different,
CPython-standard meaning of `-1`.

Also adds a test for a related previously-uncovered path: a multidict
already at `update()`'s size-estimate cap needing a resize
mid-`update()`, which no existing test reached.

CodSpeed flagged a transient regression on `getall` partway through this
PR (a read-modify-write per marked entry where the `-1` sentinel only
wrote a constant); fixed by assigning known values directly and hoisting
the loop-invariant mark value out of the hot loops. Latest CodSpeed run
shows a **12.98% improvement**, including measurable C-extension
`getall` gains.

## Are there changes in behavior for the user?

No. Internal implementation detail of both backends.

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

No.

## Related issue number

N/A

## Checklist

- [x] I think the code is well written
- [x] Unit tests for the changes exist (existing suite covers these
paths; added a te... (continued)

634 of 1268 branches covered (50.0%)

Branch coverage included in aggregate %.

47 of 47 new or added lines in 2 files covered. (100.0%)

4226 of 4443 relevant lines covered (95.12%)

1.9 hits per line

Jobs
ID Job ID Ran Files Coverage
1 MyPy - 34334407335.1 09 Sep 2026 09:24AM UTC 62
85.11
GitHub Action Run
Source Files on build 34334407335
  • Tree
  • List 31
  • 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 #34334407335
  • 265d3e5c on github
  • Prev Build on master (#34247370512)
  • Next Build on master (#34342944354)
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