Skip to content

docs: add cython gotchas section to CLAUDE.md#654

Merged
bdraco merged 1 commit into
mainfrom
docs/cython-gotchas
May 15, 2026
Merged

docs: add cython gotchas section to CLAUDE.md#654
bdraco merged 1 commit into
mainfrom
docs/cython-gotchas

Conversation

@bdraco
Copy link
Copy Markdown
Member

@bdraco bdraco commented May 15, 2026

What

Adds a "Cython gotchas (things that have bitten us)" section to CLAUDE.md capturing the non-obvious traps in the .py + .pxd setup that work fine in pure-Python mode but break or silently misbehave in the shipped Cython wheels.

Why

The pure-Python (SKIP_CYTHON=1) CI leg is happy to sail past most of these — they only surface in the REQUIRE_CYTHON=1 leg, the s390x leg, or in CodSpeed deltas. Worth writing down so the next contributor doesn't re-hit them on the marshaller/unmarshaller hot paths.

Items captured:

  • cdef-typed module constants are not Python-importable (the trap hit on the MAX_MESSAGE_SIZE cap in fix(unmarshaller): cap message size at 128 MiB per d-bus spec #653 — needs the dual-name MAX_X / _MAX_X pattern).
  • unsigned int returned through cdef int can flip sign and bypass < 0 sentinel branches — applies to any new uint32 decode in the marshaller/unmarshaller.
  • Sign-compare warnings in generated C predict the above class of bug; match signedness in the .pxd.
  • noexcept cdef paths must be pure C — _ustr_uint32 is the template.
  • except * adds a per-call PyErr_Occurred() check; watch CodSpeed when adding it to the hot path.
  • Module-level Python int constants force PyLong_AsLong per access; declare a cdef'd alias for hot-path use.
  • CodSpeed regressions only show on the Cython build — pure-Python tests can pass while production hot paths regress.

Several of the lessons were distilled from upstream PRs esphome/aioesphomeapi#1651 and esphome/aioesphomeapi#1653, adapted to dbus-fast's marshaller/unmarshaller structure.

Documentation-only; no code changes, no tests needed.

Document the .py + .pxd traps that pass pure-Python (`SKIP_CYTHON=1`)
CI but break or silently misbehave in the shipped Cython wheels:

- cdef-typed module constants are not Python-importable (the trap
  hit on the `MAX_MESSAGE_SIZE` cap in #653 — needs the dual-name
  `MAX_X` / `_MAX_X` pattern).
- `unsigned int` returned through `cdef int` can flip sign and
  bypass `< 0` sentinel branches — applies to any new uint32
  decode in the marshaller/unmarshaller.
- Sign-compare warnings in generated C predict the above class
  of bug; match signedness in the .pxd.
- `noexcept` cdef paths must be pure C (no Python calls that
  can raise) — `_ustr_uint32` is the template.
- `except *` adds a per-call `PyErr_Occurred()` check; watch
  CodSpeed when adding it to the hot path.
- Module-level Python int constants force PyLong conversion;
  declare a cdef'd alias for hot-path use.
- CodSpeed regressions only show on the Cython build — pure-
  Python tests can pass while production hot paths regress.

Lessons distilled from PR #653 and from
esphome/aioesphomeapi#1651 / #1653.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.10%. Comparing base (5d181d5) to head (32f6086).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #654      +/-   ##
==========================================
- Coverage   89.16%   89.10%   -0.06%     
==========================================
  Files          29       29              
  Lines        3488     3488              
  Branches      602      602              
==========================================
- Hits         3110     3108       -2     
- Misses        228      229       +1     
- Partials      150      151       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 15, 2026

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing docs/cython-gotchas (32f6086) with main (5d181d5)

Open in CodSpeed

@bdraco bdraco merged commit ed75962 into main May 15, 2026
20 of 23 checks passed
@bdraco bdraco deleted the docs/cython-gotchas branch May 15, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant