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

aio-libs / multidict / 36719750192
86%

Build:
DEFAULT BRANCH: master
Ran 30 Sep 2026 01:11PM 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

30 Sep 2026 01:10PM UTC coverage: 86.585% (+0.02%) from 86.563%
36719750192

push

github

web-flow
Build an istr from an exact str without str.__new__() (#1645)

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

## What do these changes do?

`IStr_New()`, which the C extension calls whenever it hands out a `str`
key of a `CIMultiDict` as an `istr` (the first read of the key,
`popitem()`), and `istr(str)` itself packed an argument tuple and went
through `str.__new__()`: argument parsing, a `str()` call and a type
dispatch around the copy. For an exact `str` they now build the `istr`
directly, the way CPython's `unicode_subtype_new()` does: allocate the
object, fill in the string's header, and copy the characters into a
buffer from the allocator `str`'s dealloc frees it with
(`PyObject_Malloc()` up to 3.12, `PyMem_Malloc()` from 3.13). A `str`
subclass keeps the old path, so the C API's `IStr_FromUnicode()` still
calls its `__str__()` as `istr(str)` does. The C extension is never
built for PyPy.

This writes fields of CPython's string objects, so it is checked per
version: 3.10 and 3.11 also set the legacy `wstr` fields and the `ready`
bit, 3.12 onwards the `statically_allocated` bit. The code was compared
against `unicode_subtype_new()` and `unicode_dealloc()` of 3.10.17,
3.11.13, 3.12.7, 3.13.7, 3.14.7 and 3.15.0rc2, and the build fails with
`#error` on any newer CPython until it has been checked the same way.

Callgrind, Ir per operation against master built the same way:

| operation | GIL | FT |
| --- | ---: | ---: |
| `CIMultiDict.popitem()` | 1,511 to 1,062 (-29.7%) | 1,633 to 1,154
(-29.3%) |
| build a 10-header `CIMultiDict` with `str` names and read its keys
once | 22,409 to 17,769 (-20.7%) | |
| `istr("Content-Header")` | 2,463 to 2,020 (-18.0%) | |

Every other row of `benchmarks/callgrind_driver.py --impl cimultidict_c`
moved less than 0.5% on both builds. The copy itself dropped from about
990 to about 535 Ir; what is left is mostly CPython's two allocations
and frees, since a `str` subclass keeps its characters in a separate
buffer.

## Are t... (continued)

789 of 1578 branches covered (50.0%)

Branch coverage included in aggregate %.

19 of 19 new or added lines in 1 file covered. (100.0%)

1 existing line in 1 file now uncovered.

9009 of 9738 relevant lines covered (92.51%)

1.85 hits per line

Coverage Regressions

Lines Coverage ∆ File
1
93.81
1.51% tests/test_istr.py
Jobs
ID Job ID Ran Files Coverage
1 MyPy - 36719750192.1 30 Sep 2026 01:11PM UTC 98
86.58
GitHub Action Run
Source Files on build 36719750192
  • Tree
  • List 49
  • Changed 3
  • Source Changed 1
  • Coverage Changed 3
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #36719750192
  • 98c4b345 on github
  • Prev Build on master (#36705619278)
  • Next Build on master (#36783420217)
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