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

aio-libs / multidict / 35975771385
86%

Build:
DEFAULT BRANCH: master
Ran 24 Sep 2026 08:32AM 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 08:31AM UTC coverage: 87.523% (-0.01%) from 87.533%
35975771385

push

github

web-flow
Keep the implicit None default of setdefault() in the module state (#1553)

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

## What do these changes do?

`setdefault()` called without an explicit default built the implicit
`None` on every call, then carried a flag to release it again, although
only the call that actually inserts consumes it. `md_set_default()` now
reads a `NULL` *value* as `None`, so the method simply forwards what it
parsed and the flag, its branch and the `Py_CLEAR()` all go away.

The constant lives in the module state rather than coming from
`Py_GetConstant()` at the point of use, because the substitution happens
just before the critical section is taken. On 3.13+ either would do; on
3.10 to 3.12 the `pythoncapi_compat` shim initialises its table lazily
and calls `PyLong_FromLong()`, so a first call landing under the lock
could collect.

Instruction counts against `cd92a6c`, callgrind, 200k calls:

| case | master | this branch | |
| --- | --- | --- | --- |
| `d.setdefault(key)`, present key | 491,825,979 | 486,878,820 | -1.01%
|
| `d.setdefault(key, default)`, present key | 494,626,107 | 493,681,201
| -0.19% |
| `d.setdefault(key)`, inserting | 290,700,236 | 290,812,020 | +0.04% |

The inserting call is unchanged, as expected: it still stores the same
constant, just one that was not built for the occasion.

Only the C extension is touched; the pure-Python implementation is
unchanged.

## Are there changes in behavior for the user?

Not at the Python level; `setdefault()` returns and stores exactly what
it did before.

The public C API gains a little: `MultiDict_SetDefault()` forwards
straight to `md_set_default()`, so it now accepts `NULL` for
*default_value* and reads it as `None`, where the documentation
previously called the argument required. `docs/capi.rst` says so, and
both `_testcapi.c` and `_testcyapi.pyx` exercise it.

`MultiDict_CAPI_VERSION` stays at 1 deliberately. It exists to stop a
client built against a newer header fr... (continued)

767 of 1534 branches covered (50.0%)

Branch coverage included in aggregate %.

6 of 8 new or added lines in 1 file covered. (75.0%)

7440 of 7843 relevant lines covered (94.86%)

1.9 hits per line

Uncovered Changes

Lines Coverage ∆ File
2
76.1
-0.02% tests/test_capi.py
Jobs
ID Job ID Ran Files Coverage
1 MyPy - 35975771385.1 24 Sep 2026 08:32AM UTC 86
87.52
GitHub Action Run
Source Files on build 35975771385
  • 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 #35975771385
  • 6657ea88 on github
  • Prev Build on master (#35971910018)
  • Next Build on master (#35976930328)
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