pfs: test_pipe_gaps fails under full-suite run — duckdb replacement-scan TypeError + multi-GB stdout spew #598
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
6 tests in tests/pfs/test_pipe_gaps.py fail when the whole suite runs (
uv run python -m pytest tests/ --no-cov, the pre-commit hook invocation) but pass in isolation. Root error:_duckdb.Error: TypeError: isinstance() arg 2 must be a type, a tuple of types, or a unionat src/pfs/pipe.py:1764 (_insert_into,CREATE TABLE ... AS SELECT * FROM df WHERE 1=0). The same run wrote ~10 GB to pytest captured stdout before being killed (22 min wall, 2:38 CPU, state D). Suite was green at 3341d9e's hook run; duckdb 1.4.4 / polars 1.38.1 unchanged since 2026-07-17. Blocks every commit on the p36-cy2026-rule branch (P36).Fixed in
2c39737. Root cause:tests/pfs/test_pipe_gaps.py::TestLoadZipCarrierEdges::test_no_year_quarter_columnpatchedpfs.pipe.pl.DataFrame— butpfs.pipe.plIS the global polars module, so the test replacedpolars.DataFrameprocess-wide with a MagicMock. When duckdb's Python replacement scan resolved the polars type for the first time inside that window, it cached the MagicMock permanently; every laterSELECT * FROM dfin the same process raisedTypeError: isinstance() arg 2 must be a type...at pfs/pipe.py:1764. Order-dependent: single-file runs pass because an earlier test primes duckdb's cache with the real class; under the hook's scoped-n autorun the cold-cache worker hit the poison.Fix: patch
pfs.pipe.plwith a proxytypes.ModuleType(real polars__dict__, onlyDataFrameoverridden) so the global class is never touched.Proof: (1) deterministic minimal repro both directions (cold process fails pre-fix, primed passes); (2) previously-failing 6 tests pass in the poisoned context post-fix; (3) full serial suite green: 14023 passed, 1 skipped, 26m45s. Also resolved en route: the multi-GB write volume attributed to this bug was actually distributed sqlite-journal churn from exercise-style tests (normal, if slow), and the stale
.git/hooks/pre-commitcopy that misdirected diagnosis was removed (#599).