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

aio-libs / multidict / 37735945154
86%

Build:
DEFAULT BRANCH: master
Ran 08 Oct 2026 06:08AM 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

08 Oct 2026 06:07AM UTC coverage: 85.907% (-0.06%) from 85.962%
37735945154

push

github

web-flow
Ignore a str subclass's own lower() in a CIMultiDict identity (#1746)

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

## What do these changes do?

Computes the case-insensitive identity of a `str` subclass key as
`str.__str__(key).lower()` instead of calling the subclass's own
`lower()`, in both backends. `IStr_FromUnicode()` in the C API builds an
istr's canonical form with `str.lower()` called unbound for the same
reason. Computing an identity therefore never runs user code, which
removes a source of reentrancy from every lookup and bulk update.

In the C extension the exact copy then takes the existing ASCII fast
path instead of a method call, so a lookup with a subclass key got
faster; exact `str` and `istr` keys are unaffected.

## Are there changes in behavior for the user?

Yes. A `str` subclass that overrides `lower()` no longer changes how
`CIMultiDict` matches it: `CIMultiDict` lowercases the key's string
value with `str.lower()`, the same as for a plain `str`.

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

No. The tests that relied on an overridden `lower()` to run Python code
mid-operation were dropped or moved to another hook (`__getitem__()` on
a sequence item).

## Related issue number

N/A; follows #1744. Since a key's `lower()` can no longer mutate the
source mid-update, this drops the tests #1744 added for that case and
its pure-Python source version check, which nothing could trigger any
more.

## Checklist

- [x] I think the code is well written
- [x] Unit tests for the changes exist
- [x] Documentation reflects the changes (N/A, the override was never
documented)
- [ ] If you provide code modification, please add yourself to
`CONTRIBUTORS.txt` (N/A)
- [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>

Tests: `pytest -q` on 3.14.7 (40... (continued)

793 of 1586 branches covered (50.0%)

Branch coverage included in aggregate %.

30 of 32 new or added lines in 5 files covered. (93.75%)

1 existing line in 1 file now uncovered.

9314 of 10179 relevant lines covered (91.5%)

1.83 hits per line

Uncovered Changes

Lines Coverage ∆ File
2
74.0
-0.02% tests/test_capi.py

Coverage Regressions

Lines Coverage ∆ File
1
71.67
-0.07% multidict/_multidict_py.py
Jobs
ID Job ID Ran Files Coverage
1 MyPy - 37735945154.1 08 Oct 2026 06:08AM UTC 98
85.91
GitHub Action Run
Source Files on build 37735945154
  • Tree
  • List 49
  • Changed 6
  • Source Changed 5
  • Coverage Changed 6
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #37735945154
  • c53246f9 on github
  • Prev Build on master (#37733835205)
  • Next Build on master (#37737799381)
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