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

aio-libs / multidict / 35965377150
87%

Build:
DEFAULT BRANCH: master
Ran 24 Sep 2026 06:38AM UTC
Jobs 1
Files 43
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

24 Sep 2026 06:37AM UTC coverage: 87.483% (+0.02%) from 87.464%
35965377150

push

github

web-flow
Speed up the argument binding of the C extension (#1549)

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

## What do these changes do?

Three changes to the argument handling of the C extension, no behaviour
change in any of them.

`parse2()` compiled to a single outlined clone shared by all eleven call
sites and was inlined nowhere, so `md.get(key)` paid a call into the
keyword machinery it never used. The all-positional case now binds in
the inline wrapper, five instructions at the call site, and the rest
moved to a `COLD parse2_slow()`. Since the keyword walk is out of line
anyway, it takes the tuple through `PyTuple_GET_SIZE()` and
`PyTuple_GET_ITEM()`; all eleven methods are
`METH_FASTCALL | METH_KEYWORDS`, so `kwnames` is a tuple or `NULL` and
the error branches of the checked calls were unreachable.

Parameter names are now interned in the module state and matched against
`kwnames` by identity before falling back to a comparison, which is what
`find_keyword()` in CPython's `Python/getargs.c` does. A call written as
`get(key=k)` settles on a pointer compare; the `memcmp()` it replaces
was
45% of the keyword path. The fallback is not optional: `get(**{"key":
k})`
builds names that never reach the intern table, and there is a test for
exactly that.

Finally, `multidict_get()` built the implicit `None` default on every
call and carried a flag to release it again, although it is only
reachable when the key is absent. It now does the lookup directly and
produces the constant on the miss path, where it is the return value.
`setdefault()` keeps the old shape, since it has to hand the default to
`md_set_default()` inside the critical section.

Instruction counts against `9682ba1`, callgrind, 200k calls:

| case | master | this branch | |
| --- | --- | --- | --- |
| `md.get(key)` | 506,599,099 | 492,590,531 | -2.77% |
| `md.get(key, default=None)` | 560,167,840 | 538,574,218 | -3.85% |
| `md.getone(key=key)` | 553,395,042 | 531,801,895 | -3.90% |
| `md.get(ke... (continued)

767 of 1534 branches covered (50.0%)

Branch coverage included in aggregate %.

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

7375 of 7773 relevant lines covered (94.88%)

1.9 hits per line

Jobs
ID Job ID Ran Files Coverage
1 MyPy - 35965377150.1 24 Sep 2026 06:38AM UTC 86
87.48
GitHub Action Run
Source Files on build 35965377150
  • Tree
  • List 43
  • 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 #35965377150
  • 443d7453 on github
  • Prev Build on master (#35963992961)
  • Next Build on master (#35965407040)
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