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

aio-libs / multidict / 36973563009
86%

Build:
DEFAULT BRANCH: master
Ran 02 Oct 2026 06:27AM UTC
Jobs 1
Files 49
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

01 Oct 2026 02:57PM UTC coverage: 86.621% (+0.04%) from 86.585%
36973563009

push

github

web-flow
Give an istr taken from a CIMultiDict the source's identity (#1647)

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

## What do these changes do?

`MultiDict.extend()`, `update()`, `merge()` and the `MultiDict`
constructor, given a `CIMultiDict`, built an `istr` for each source key
with the case-sensitive destination's identity as its canonical form,
which is the key itself rather than its lower-cased form. A
`CIMultiDict` keyed by such an `istr` then could not find it under any
spelling:

```python
ci = CIMultiDict([("Foo", 1)])
md = MultiDict(); md.extend(ci)
(k,) = md.keys()
d = CIMultiDict([(k, 1)])
"foo" in d, "Foo" in d   # (False, False) on the C extension
```

The C fix in `_md_update_from_ht_k()` passes the source entry's own
identity as the canonical, holding a reference to it before anything
that can run Python code.

The pure-Python backend never had a wrong canonical, since it lowers
lazily, but it handed over these keys as plain `str` while the C
extension handed over `istr`. It now passes them through the source's
key conversion too, so both backends yield `istr`, the same as iterating
the `CIMultiDict` does. The other paths that build an `istr` from a
stored key (`md_ensure_key()`, `popitem()`, the dict, sequence and
keyword update paths) all pair the key with the identity of the same
multidict and were not affected.

## Are there changes in behavior for the user?

Yes. On the C extension, such keys now work as `CIMultiDict` keys. On
the pure-Python backend, a `MultiDict` filled from a `CIMultiDict` now
holds `istr` keys instead of `str`, matching the C extension.

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

No; a few lines in one function per backend.

## Related issue number

N/A, found while reviewing the `istr` construction paths.

## 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 ... (continued)

789 of 1578 branches covered (50.0%)

Branch coverage included in aggregate %.

58 of 62 new or added lines in 2 files covered. (93.55%)

9065 of 9798 relevant lines covered (92.52%)

1.85 hits per line

Uncovered Changes

Lines Coverage ∆ File
3
98.23
-0.89% tests/test_update.py
1
71.7
0.01% multidict/_multidict_py.py
Jobs
ID Job ID Ran Files Coverage
1 MyPy - 36973563009.1 02 Oct 2026 06:27AM UTC 98
86.62
GitHub Action Run
Source Files on build 36973563009
  • Tree
  • List 49
  • 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 #36973563009
  • 3b1e531d on github
  • Prev Build on master (#36783420217)
  • Next Build on master (#36992438938)
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