Skip to content

Commit 9dc2d66

Browse files
committed
skills: generalize gotcha 402 beyond abi3 legs; queue: note grain's matrix fix
grain's cp312/cp313/cp314 legs were include-only on a version-only matrix and collapsed to a single cp314 job on a green run, so the collapse is not an abi3/free-threading shape - it is any include entry that keys on no real dimension. Applying that rule across .github/workflows flags 58 jobs, four packages of which have already published incomplete wheel sets.
1 parent 99ff246 commit 9dc2d66

3 files changed

Lines changed: 24 additions & 2 deletions

File tree

‎.queue.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2427,7 +2427,7 @@ packages:
24272427
repo: https://github.com/google/grain
24282428
status: in-progress
24292429
pr: 2124
2430-
notes: '8 Linux wheels upstream (abi: cp311,cp312,cp313,cp314); no riscv64 on PyPI or pypi.riseproject.dev. Feasible: the compiled surface is one pybind11 extension (index_shuffle, statically linking abseil-cpp) plus a generated protobuf module, and array-record 0.8.3 - the dependency that would have blocked this - is already published here for cp312/cp313/cp314 (no cp311, which sets the matrix). Bazel bootstrapped from source at 7.5.0 like array-record/ray/labmaze, sharing their actions/cache key. Upstream''s `bazel build ...` is unusable on riscv64: 85 BUILD deps reach the @pypi hub, whose test_requirements lock pins jaxlib==0.8.0 and scipy with hashes, and jaxlib has no riscv64 wheel and no sdist - so only the three targets whose output reaches the wheel are built (verified locally in manylinux_2_34_x86_64: the module graph resolves and all three analyse with zero @pypi/jaxlib/scipy fetches). rules_python 1.6.0 carries riscv64 CPython for 3.11-3.14 inclusive. Tests (gotcha 439): upstream''s default CI mode is `bazel test`, one process per py_test target, and its OSS pytest fallback is not a tested path - `pytest --pyargs grain` in one process makes data_loader_test''s 120 tests fail that pass 120/120 alone, and hangs around 4%. So each of the 45 test files runs as its own process, invoked as a module (`python -m grain...`) because ipc/queue.py shadows the stdlib queue when its own directory is sys.path[0], which killed queue_test and variable_size_queue_test; with the env/args upstream''s rules supply (--test_srcdir on data_loader/data_sources/tfrecord_dataset, EXPECTED_FRAMEWORK=NO_FRAMEWORK, PYTHON_VERSION). 9 files dropped: 8 need jax or tensorflow (batch_test among them - it reads sys.modules["jax"] without importing it and its py_test declares @pypi//jax), and multiprocessing_test, which upstream declares no target for and whose __main__ calls an undefined name. dataset_test goes through pytest so grain''s own RUN_IN_PYTEST expectedFailure applies to its two execution-summary tests, which wait on a summary-logging thread that only reports under upstream''s runner. All of that verified in manylinux_2_34_x86_64 against upstream''s released cp312 wheel: data_loader 120, dataset_test 156, traceback_util 18, queue 6, variable_size_queue 19, and no failures in the shipped configuration. Wheel also gains LICENSE.abseil-cpp/LICENSE.pybind11 (both statically linked, upstream ships neither); confirmed setuptools 82 globs them into dist-info/licenses. Local ceiling: no riscv64 bazel compile (the session proxy 403s github.com/pybind/pybind11/archive/*). PR #2124 open; every check still queued on the org''s Actions backlog, so CI has not been proven green yet.'
2430+
notes: '8 Linux wheels upstream (abi: cp311,cp312,cp313,cp314); no riscv64 on PyPI or pypi.riseproject.dev. Feasible: the compiled surface is one pybind11 extension (index_shuffle, statically linking abseil-cpp) plus a generated protobuf module, and array-record 0.8.3 - the dependency that would have blocked this - is already published here for cp312/cp313/cp314 (no cp311, which sets the matrix). Bazel bootstrapped from source at 7.5.0 like array-record/ray/labmaze, sharing their actions/cache key. Upstream''s `bazel build ...` is unusable on riscv64: 85 BUILD deps reach the @pypi hub, whose test_requirements lock pins jaxlib==0.8.0 and scipy with hashes, and jaxlib has no riscv64 wheel and no sdist - so only the three targets whose output reaches the wheel are built (verified locally in manylinux_2_34_x86_64: the module graph resolves and all three analyse with zero @pypi/jaxlib/scipy fetches). rules_python 1.6.0 carries riscv64 CPython for 3.11-3.14 inclusive. Tests (gotcha 439): upstream''s default CI mode is `bazel test`, one process per py_test target, and its OSS pytest fallback is not a tested path - `pytest --pyargs grain` in one process makes data_loader_test''s 120 tests fail that pass 120/120 alone, and hangs around 4%. So each of the 45 test files runs as its own process, invoked as a module (`python -m grain...`) because ipc/queue.py shadows the stdlib queue when its own directory is sys.path[0], which killed queue_test and variable_size_queue_test; with the env/args upstream''s rules supply (--test_srcdir on data_loader/data_sources/tfrecord_dataset, EXPECTED_FRAMEWORK=NO_FRAMEWORK, PYTHON_VERSION). 9 files dropped: 8 need jax or tensorflow (batch_test among them - it reads sys.modules["jax"] without importing it and its py_test declares @pypi//jax), and multiprocessing_test, which upstream declares no target for and whose __main__ calls an undefined name. dataset_test goes through pytest so grain''s own RUN_IN_PYTEST expectedFailure applies to its two execution-summary tests, which wait on a summary-logging thread that only reports under upstream''s runner. All of that verified in manylinux_2_34_x86_64 against upstream''s released cp312 wheel: data_loader 120, dataset_test 156, traceback_util 18, queue 6, variable_size_queue 19, and no failures in the shipped configuration. Wheel also gains LICENSE.abseil-cpp/LICENSE.pybind11 (both statically linked, upstream ships neither); confirmed setuptools 82 globs them into dist-info/licenses. Local ceiling: no riscv64 bazel compile (the session proxy 403s github.com/pybind/pybind11/archive/*). PR #2124 open; every check still queued on the org''s Actions backlog, so CI has not been proven green yet. Run 35492217884 then came back fully green while building a single wheel: the three interpreter legs were include-only entries ({tag, python}) on a version-only matrix, so GitHub merged them into one combination and only `Build grain 0.2.18 cp314-manylinux_riscv64` ran - gotcha 402, inherited from build-array-record.yml, which grain was derived from. Fixed by making `tag: [cp312, cp313, cp314]` a real dimension crossed with version, the include entries now only mapping tag -> python; expansion re-checked against GitHub''s documented include semantics (3 jobs per version, 6 for two pending versions) and run 35503063718 is the first to queue three build jobs. The same collapse is latent in 58 other jobs repo-wide (noted on gotcha 402; protobuf-py-ext, primp, arro3-core and rigour 2.5.0 have already published incomplete wheel sets).'
24312431
- pkg: ruptures
24322432
version: 1.1.10
24332433
home: https://github.com/deepcharles/ruptures/

‎skills/python-project-porting/references/gotchas-index.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,9 @@ The porting gotchas (431 of them) live in [`references/gotchas/`](gotchas/), spl
269269
- **402** — A two-leg abi3 + free-threaded matrix expressed only through `include:` collapses
270270
into a single job, so the abi3 wheel is never built and nothing fails — make the leg a real
271271
matrix dimension (the primp/arro3-core case: two already-published packages are quietly
272-
shipping only their free-threaded wheel).
272+
shipping only their free-threaded wheel). Any include-only leg set does it, not just abi3
273+
ones — grain's cp312/cp313/cp314 set collapsed to cp314, and 58 jobs repo-wide still carry
274+
the shape.
273275
- **408** — A `setup.py` that reaches for `wheel.bdist_wheel` behind a `try/except ImportError`
274276
still gets its abi3 tag under modern setuptools — setuptools ships a `wheel.bdist_wheel`
275277
shim, so do not add `wheel` to `build-system.requires` to "fix" it.

‎skills/python-project-porting/references/gotchas/cibuildwheel-matrix-and-abi3.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,26 @@ To pull up one entry: `grep -n '^N\. ' references/gotchas/cibuildwheel-matrix-an
858858
<tag>-manylinux_riscv64` jobs against the legs declared before believing a green
859859
run. `docs/packages/<pkg>.yaml` is the after-the-fact tell — a published version
860860
carrying only the free-threaded wheel where an earlier version carried both.
861+
- **It is not an abi3/free-threading shape, it is any include-only leg set.**
862+
`build-grain.yml` expressed a plain per-interpreter set that way —
863+
`include: [{tag: cp312, python: '3.12'}, {tag: cp313, ...}, {tag: cp314, ...}]`
864+
over a `version`-only base — and PR #2124's run 35492217884 went green with one
865+
build job, `Build grain 0.2.18 cp314-manylinux_riscv64`, no cp312/cp313 wheel at
866+
all. It was copied from `build-array-record.yml`, which carries the same three
867+
entries (0.8.3 shipped all three wheels from the older base matrix, so the loss
868+
only shows on its next rebuild).
869+
- **The rule that decides it**: an include entry that keys on *no* real dimension
870+
attaches to every base combination, so two such entries sharing a key overwrite
871+
each other; an entry that keys on a real dimension only updates the combinations
872+
it matches, which is the correct use (`build-lz4.yml`'s `- python: "cp314t"` over
873+
`python: ["cp312", "cp313", "cp314", "cp314t"]` — all four wheels published).
874+
- **It is repo-wide, not a two-package slip**: applying that rule to every
875+
`.github/workflows/*.yml` flags 58 jobs whose declared legs collapse into one
876+
(2 to 5 legs each, `build`/`tag`/`python`/`features`/`test_requires` the usual
877+
shared keys). Already visible on the registry: `protobuf-py-ext` 0.4.0/0.5.0 and
878+
`primp` 2.0.0/2.0.1 and `arro3-core` 0.8.2/0.8.3 carry only their cp314t wheel,
879+
and `rigour` 2.5.0 carries only cp314 where 2.4.1 carried five. Fix the workflow
880+
you are touching; the rest need a sweep of their own.
861881

862882
408. **A `setup.py` that reaches for `wheel.bdist_wheel` behind a `try/except ImportError`
863883
still gets its abi3 tag under modern setuptools — do not "fix" it by adding `wheel`

0 commit comments

Comments
 (0)