mypy
ab8e4bf1 - [mypyc] Fix missing cross-group header deps in incremental builds (#21490)

Commit
36 days ago
[mypyc] Fix missing cross-group header deps in incremental builds (#21490) ## Problem In `separate=True` mode, each group's `__native_internal_<mod>.h` reaches into a sibling group's export-table header via an angled include: ```c // __native_internal_caller.h #include <other_group/__native_other.h> ``` The consumer's `.o` file bakes in byte offsets from that struct at C compile time. If the sibling group's struct layout shifts (e.g. a class is inserted earlier in the source, shifting all subsequent offsets), the consumer's `.o` must be recompiled, otherwise it silently resolves offsets to the wrong object at runtime. Two bugs in the old `get_header_deps` combined to hide this dep from setuptools' `Extension.depends`: 1. **No transitive walk.** The cross-group include lives inside `__native_internal_<mod>.h`, not in the `.c` file itself. The old code only scanned the `.c` file's direct includes and never opened the resolved headers. 2. **Single-pass resolution.** Deps were resolved per-group before sibling groups had written their headers to disk, so the cross-group header didn't yet exist even if we had looked. ## Fix - **`_extract_includes` / `_INCLUDE_RE`**: distinguishes `#include "foo"` (quoted) from `#include <foo>` (angled), matching the preprocessor's own search rules — quoted form searches the includer's directory first; angled form searches `-I` paths only. - **`resolve_cfile_deps`**: transitive walker that opens each resolved header and follows its `#include` directives, bounded by a visited set. Headers that don't exist under `target_dir` (lib-rt headers like `<Python.h>`) are dropped since they never change between builds. - **Two-pass loop in `mypyc_build`**: first pass writes all groups' files to disk; second pass resolves deps so every group's headers are present when cross-group includes are looked up. ## Impact on non-incremental builds None. `Extension.depends` is only consulted by setuptools when a `.o` already exists. Cold builds compile everything unconditionally. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Author
Parents
Loading