Skip to content

Add PyTorch TensorDict validation backend - #2403

Open
cosmicBboy wants to merge 3 commits into
mainfrom
nielsb/pytorch-tensordict
Open

Add PyTorch TensorDict validation backend#2403
cosmicBboy wants to merge 3 commits into
mainfrom
nielsb/pytorch-tensordict

Conversation

@cosmicBboy

Copy link
Copy Markdown
Collaborator

Summary

Brings the TensorDict integration work from dev/pytorch-tensordict-phase4 (phases 1–4) onto latest main as a single squashed change, reviewed and updated against the current state of the pytorch/tensordict library (tensordict 0.13, torch 2.12).

Integration surface

  • TensorDictSchema / Tensor components validating dtype, shape, batch_size, and value checks for TensorDict and tensorclass objects
  • Class-based TensorDictModel API with Field annotations and Config
  • dtype coercion (schema-level and per-tensor)
  • Schema inference from TensorDict/tensorclass data (pa.infer_schema)
  • YAML/JSON schema serialization plus save/load with embedded schema metadata
  • Hypothesis strategies for TensorDict and tensorclass generation
  • New docs guide (docs/source/pytorch_guide/) and API reference page
  • New torch extra: pip install 'pandera[torch]'

Updates on top of the original branch

Reviewed against tensordict 0.13 and fixed issues found along the way:

  • Modern tensordict type handling: use the canonical is_tensor_collection / is_tensorclass predicates and register the validation backend on TensorDictBase, so all subclasses validate — including LazyStackedTensorDict (TensorDict.lazy_stack results are not isinstance of TensorDict, so the original code missed them)
  • IO fixes: save() on a plain dict previously crashed (bogus Engine.dtype("tensordict") call) — now builds a TensorDict and infers batch dims via auto_batch_size_(); load() referenced an unimported infer_schema
  • Model config fixes: Config.coerce (and name/title/description) and per-field nullable/coerce/required were silently dropped when building the schema; per-tensor coerce=True now works without schema-level coerce
  • Strategies rewrite: generation now uses hypothesis.extra.numpy with exact dtype fidelity (was hardcoded float32/int64), batch-dim alignment (was generating tensors inconsistent with batch_size, a hard RuntimeError in current tensordict), and check-aware element generation (isin, ge/gt/le/lt, in_range)
  • Engine: register modern torch dtypes (uint16/32/64, float8_e4m3fn, float8_e5m2), drop deprecated quantized dtypes, and raise a clear error for unknown dtype inputs
  • Import hygiene: pandera.io, pandera.strategies, and pandera.schema_inference stay lazy — importing pandera does not import torch (strategies exports use module __getattr__)
  • Docs: removed merge-conflict markers that had been committed into tensordict_io.md, and fixed several doc examples that were broken or numerically unsound; all 41 executable code cells in the pytorch guide now run cleanly against tensordict 0.13
  • Dropped unrelated drive-by reformatting of pandas/pyspark/xarray modules that the old branch carried, keeping the diff purely additive

Test plan

  • tests/tensordict/ — 90 tests pass (84 from the original branch + 6 new regression tests for LazyStackedTensorDict validation, plain-dict save() round-trip, and strategy dtype/batch fidelity)
  • All 41 mystnb code cells in docs/source/pytorch_guide/ execute cleanly (3 consecutive runs to shake out hypothesis flakiness)
  • tests/pandas/test_schemas.py passes with torch installed (no cross-backend regressions)
  • pre-commit hooks (ruff, mypy, pyupgrade, flynt, codespell) pass on all changed files
  • Verified import pandera remains torch-free

🤖 Generated with Claude Code

Squashed rebase of dev/pytorch-tensordict-phase4 (phases 1-4 of the
TensorDict integration) onto main, reviewed and updated against
tensordict 0.13 / torch 2.12.

Integration surface:
- TensorDictSchema / Tensor components with dtype, shape, batch_size,
  and value-check validation for TensorDict and tensorclass objects
- Class-based TensorDictModel API with Field annotations and Config
- dtype coercion (schema-level and per-tensor)
- Schema inference from TensorDict/tensorclass data
- YAML/JSON schema serialization plus save/load with embedded schema
- Hypothesis strategies for TensorDict and tensorclass generation
- Docs guide (docs/source/pytorch_guide) and API reference

Updates on top of the original branch work:
- Use tensordict's canonical type predicates (is_tensor_collection,
  is_tensorclass) and register the backend on TensorDictBase so all
  subclasses validate, including LazyStackedTensorDict
- Fix save() on plain dicts (auto_batch_size_ inference) and load()'s
  broken infer_schema reference
- Fix TensorDictModel Config options (coerce, name, title, description)
  and per-field nullable/coerce/required being silently dropped
- Honor per-tensor coerce=True when schema-level coerce is off
- Rewrite strategies on hypothesis.extra.numpy: exact dtype fidelity,
  batch-dim alignment, and check-aware element generation (isin,
  ge/gt/le/lt, in_range)
- Register modern torch dtypes (uint16/32/64, float8) and drop
  deprecated quantized dtypes; fix engine handling of unknown dtypes
- Keep pandera.io/pandera.strategies/pandera.schema_inference lazy so
  importing pandera does not require torch
- Remove committed merge-conflict markers from docs and fix doc
  examples (all 41 code cells in the pytorch guide now execute)
- Regression tests for LazyStackedTensorDict validation, dict save
  round-trip, and strategy dtype/batch fidelity (90 tests total)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.42992% with 1158 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.77%. Comparing base (26d54f2) to head (501eb2f).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
pandera/api/tensordict/model.py 0.00% 337 Missing ⚠️
pandera/backends/tensordict/base.py 0.00% 185 Missing ⚠️
pandera/io/tensordict_io.py 0.00% 134 Missing ⚠️
pandera/strategies/tensordict_strategies.py 0.00% 89 Missing ⚠️
pandera/engines/tensordict_engine.py 0.00% 88 Missing ⚠️
pandera/schema_inference/tensordict.py 0.00% 64 Missing ⚠️
pandera/backends/tensordict/checks.py 0.00% 54 Missing ⚠️
pandera/api/tensordict/container.py 0.00% 46 Missing ⚠️
pandera/backends/tensordict/builtin_checks.py 0.00% 44 Missing ⚠️
pandera/api/tensordict/model_components.py 0.00% 34 Missing ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2403      +/-   ##
==========================================
- Coverage   90.89%   84.77%   -6.13%     
==========================================
  Files         192      210      +18     
  Lines       17087    20060    +2973     
==========================================
+ Hits        15532    17006    +1474     
- Misses       1555     3054    +1499     
Flag Coverage Δ
unit-tests-base-Linux-py3.10 14.33% <0.00%> (-1.08%) ⬇️
unit-tests-base-Linux-py3.11 14.33% <0.00%> (-1.08%) ⬇️
unit-tests-base-Linux-py3.12 14.33% <0.00%> (-1.08%) ⬇️
unit-tests-base-Linux-py3.13 14.33% <0.00%> (-1.08%) ⬇️
unit-tests-base-Linux-py3.14 14.21% <0.00%> (-1.07%) ⬇️
unit-tests-base-Windows-py3.10 14.26% <0.00%> (-1.07%) ⬇️
unit-tests-base-Windows-py3.11 14.26% <0.00%> (-1.07%) ⬇️
unit-tests-base-Windows-py3.12 14.26% <0.00%> (-1.07%) ⬇️
unit-tests-base-Windows-py3.13 14.26% <0.00%> (-1.07%) ⬇️
unit-tests-base-Windows-py3.14 14.14% <0.00%> (-1.07%) ⬇️
unit-tests-base-macOS-py3.10 14.28% <0.00%> (-1.08%) ⬇️
unit-tests-base-macOS-py3.11 14.28% <0.00%> (-1.08%) ⬇️
unit-tests-base-macOS-py3.12 14.28% <0.00%> (-1.08%) ⬇️
unit-tests-base-macOS-py3.13 14.28% <0.00%> (-1.08%) ⬇️
unit-tests-base-macOS-py3.14 14.15% <0.00%> (-1.07%) ⬇️
unit-tests-dask-Linux-py3.10-pandas2.3.3-polars 22.61% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Linux-py3.11-pandas2.3.3-polars 22.61% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Linux-py3.12-pandas2.3.3-polars 22.61% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Linux-py3.13-pandas2.3.3-polars 22.61% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Linux-py3.14-pandas2.3.3-polars 22.52% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Windows-py3.10-pandas2.3.3-polars 22.53% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Windows-py3.11-pandas2.3.3-polars 22.53% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Windows-py3.12-pandas2.3.3-polars 22.53% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Windows-py3.13-pandas2.3.3-polars 22.53% <0.25%> (-1.63%) ⬇️
unit-tests-dask-Windows-py3.14-pandas2.3.3-polars 22.44% <0.25%> (-1.63%) ⬇️
unit-tests-fastapi-Linux-py3.10-pandas2.3.3-pydantic2.12.3 23.01% <0.25%> (-1.68%) ⬇️
unit-tests-fastapi-Linux-py3.11-pandas2.3.3-pydantic2.12.3 23.01% <0.25%> (-1.69%) ⬇️
unit-tests-fastapi-Linux-py3.11-pandas3.0.0-pydantic2.12.3 23.08% <0.25%> (-1.69%) ⬇️
unit-tests-fastapi-Linux-py3.12-pandas3.0.0-pydantic2.12.3 23.08% <0.25%> (-1.69%) ⬇️
unit-tests-fastapi-Linux-py3.14-pandas2.3.3-pydantic2.12.3 22.93% <0.25%> (-1.68%) ⬇️
unit-tests-fastapi-Windows-py3.11-pandas2.3.3-pydantic2.12.3 22.93% <0.25%> (-1.63%) ⬇️
unit-tests-geopandas-Linux-py3.10-pandas2.3.3-pydantic2.12.3 28.03% <0.25%> (-2.06%) ⬇️
unit-tests-geopandas-Linux-py3.11-pandas2.3.3-pydantic2.12.3 28.03% <0.25%> (-2.07%) ⬇️
unit-tests-geopandas-Linux-py3.11-pandas3.0.0-pydantic2.12.3 28.03% <0.25%> (-2.05%) ⬇️
unit-tests-geopandas-Linux-py3.12-pandas3.0.0-pydantic2.12.3 28.03% <0.25%> (-2.05%) ⬇️
unit-tests-geopandas-Windows-py3.10-pandas2.3.3-pydantic2.12.3 27.93% <0.25%> (-2.05%) ⬇️
unit-tests-geopandas-Windows-py3.11-pandas2.3.3-pydantic2.12.3 27.93% <0.25%> (-2.05%) ⬇️
unit-tests-hypotheses-Linux-py3.10-pandas2.3.3-pydantic2.12.3 20.97% <0.25%> (-1.51%) ⬇️
unit-tests-hypotheses-Linux-py3.11-pandas2.3.3-pydantic2.12.3 20.97% <0.25%> (-1.52%) ⬇️
unit-tests-hypotheses-Linux-py3.11-pandas3.0.0-pydantic2.12.3 21.01% <0.25%> (-1.53%) ⬇️
unit-tests-hypotheses-Linux-py3.12-pandas2.3.3-pydantic2.12.3 20.97% <0.25%> (?)
unit-tests-hypotheses-Linux-py3.13-pandas2.3.3-pydantic2.12.3 20.97% <0.25%> (-1.47%) ⬇️
unit-tests-hypotheses-Linux-py3.13-pandas3.0.0-pydantic2.12.3 21.01% <0.25%> (-1.52%) ⬇️
unit-tests-hypotheses-Linux-py3.14-pandas3.0.0-pydantic2.12.3 20.90% <0.25%> (-1.48%) ⬇️
unit-tests-hypotheses-Windows-py3.10-pandas2.3.3-pydantic2.12.3 20.90% <0.25%> (-1.52%) ⬇️
unit-tests-hypotheses-Windows-py3.11-pandas3.0.0-pydantic2.12.3 20.94% <0.25%> (-1.43%) ⬇️
unit-tests-ibis-Linux-py3.10-pandas2.3.3-polars 26.91% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Linux-py3.11-pandas2.3.3-polars 26.91% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Linux-py3.12-pandas2.3.3-polars 26.91% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Linux-py3.13-pandas2.3.3-polars 26.91% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Linux-py3.14-pandas2.3.3-polars 26.73% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Windows-py3.10-pandas2.3.3-polars 26.84% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Windows-py3.11-pandas2.3.3-polars 26.84% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Windows-py3.12-pandas2.3.3-polars 26.84% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Windows-py3.13-pandas2.3.3-polars 26.84% <0.25%> (-1.97%) ⬇️
unit-tests-ibis-Windows-py3.14-pandas2.3.3-polars 26.66% <0.25%> (-1.96%) ⬇️
unit-tests-io-Linux-py3.10-pandas2.3.3-pydantic2.12.3 35.53% <0.25%> (-2.54%) ⬇️
unit-tests-io-Linux-py3.11-pandas3.0.0-pydantic2.12.3 35.54% <0.25%> (-2.57%) ⬇️
unit-tests-io-Linux-py3.12-pandas2.3.3-pydantic2.12.3 35.56% <0.25%> (-2.58%) ⬇️
unit-tests-io-Linux-py3.12-pandas3.0.0-pydantic2.12.3 35.54% <0.25%> (-2.58%) ⬇️
unit-tests-io-Linux-py3.13-pandas3.0.0-pydantic2.12.3 35.54% <0.25%> (?)
unit-tests-io-Linux-py3.14-pandas2.3.3-pydantic2.12.3 35.45% <0.25%> (-2.58%) ⬇️
unit-tests-io-Linux-py3.14-pandas3.0.0-pydantic2.12.3 35.43% <0.25%> (-2.54%) ⬇️
unit-tests-io-Windows-py3.11-pandas3.0.0-pydantic2.12.3 35.20% <0.25%> (-2.55%) ⬇️
unit-tests-modin-dask-Linux-py3.11-pandas2.3.3-polars 28.62% <0.42%> (-2.08%) ⬇️
unit-tests-modin-dask-Linux-py3.12-pandas2.3.3-polars 28.62% <0.42%> (-2.06%) ⬇️
unit-tests-modin-dask-Windows-py3.11-pandas2.3.3-polars 28.54% <0.42%> (-1.98%) ⬇️
unit-tests-modin-dask-Windows-py3.12-pandas2.3.3-polars 28.54% <0.42%> (-2.06%) ⬇️
unit-tests-modin-ray-Linux-py3.10-pandas2.3.3-polars 28.60% <0.42%> (-2.06%) ⬇️
unit-tests-modin-ray-Linux-py3.11-pandas2.3.3-polars 28.60% <0.42%> (-2.06%) ⬇️
unit-tests-modin-ray-Linux-py3.12-pandas2.3.3-polars 28.60% <0.42%> (-2.06%) ⬇️
unit-tests-mypy-Linux-py3.10-pandas2.3.3-pydantic2.12.3 21.86% <0.25%> (-1.60%) ⬇️
unit-tests-mypy-Linux-py3.11-pandas2.3.3-pydantic2.12.3 21.86% <0.25%> (-1.55%) ⬇️
unit-tests-mypy-Linux-py3.12-pandas2.3.3-pydantic2.12.3 21.86% <0.25%> (?)
unit-tests-narwhals-Linux-py3.10 26.36% <0.25%> (-1.95%) ⬇️
unit-tests-narwhals-Linux-py3.11 26.36% <0.25%> (-1.95%) ⬇️
unit-tests-narwhals-Linux-py3.12 26.36% <0.25%> (-1.95%) ⬇️
unit-tests-narwhals-Linux-py3.13 26.36% <0.25%> (-1.95%) ⬇️
unit-tests-narwhals-Linux-py3.14 26.15% <0.25%> (-1.94%) ⬇️
unit-tests-narwhals-backend-ibis-py3.10 29.67% <0.25%> (-2.18%) ⬇️
unit-tests-narwhals-backend-ibis-py3.11 29.56% <0.25%> (-2.18%) ⬇️
unit-tests-narwhals-backend-ibis-py3.12 29.56% <0.25%> (-2.18%) ⬇️
unit-tests-narwhals-backend-ibis-py3.13 29.56% <0.25%> (-2.18%) ⬇️
unit-tests-narwhals-backend-ibis-py3.14 29.36% <0.25%> (-2.17%) ⬇️
unit-tests-narwhals-backend-polars-py3.10 32.17% <0.25%> (-2.34%) ⬇️
unit-tests-narwhals-backend-polars-py3.11 32.15% <0.25%> (-2.34%) ⬇️
unit-tests-narwhals-backend-polars-py3.12 32.15% <0.25%> (-2.34%) ⬇️
unit-tests-narwhals-backend-polars-py3.13 32.15% <0.25%> (-2.34%) ⬇️
unit-tests-narwhals-backend-polars-py3.14 32.01% <0.25%> (-2.34%) ⬇️
unit-tests-narwhals-backend-pyspark-py3.10 40.55% <0.42%> (?)
unit-tests-narwhals-backend-pyspark-py3.11 40.58% <0.42%> (?)
unit-tests-pandas-Linux-py3.10-pandas2.3.3-pydantic1.10.11 39.88% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Linux-py3.10-pandas2.3.3-pydantic2.12.3 40.03% <0.25%> (-2.78%) ⬇️
unit-tests-pandas-Linux-py3.11-pandas2.3.3-pydantic1.10.11 39.88% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Linux-py3.11-pandas2.3.3-pydantic2.12.3 40.03% <0.25%> (-2.78%) ⬇️
unit-tests-pandas-Linux-py3.11-pandas3.0.0-pydantic1.10.11 39.89% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Linux-py3.11-pandas3.0.0-pydantic2.12.3 40.04% <0.25%> (-2.75%) ⬇️
unit-tests-pandas-Linux-py3.12-pandas2.3.3-pydantic1.10.11 39.87% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Linux-py3.12-pandas2.3.3-pydantic2.12.3 40.01% <0.25%> (-2.78%) ⬇️
unit-tests-pandas-Linux-py3.12-pandas3.0.0-pydantic1.10.11 39.88% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Linux-py3.12-pandas3.0.0-pydantic2.12.3 40.03% <0.25%> (-2.78%) ⬇️
unit-tests-pandas-Linux-py3.13-pandas2.3.3-pydantic1.10.11 39.87% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Linux-py3.13-pandas2.3.3-pydantic2.12.3 40.01% <0.25%> (-2.78%) ⬇️
unit-tests-pandas-Linux-py3.13-pandas3.0.0-pydantic1.10.11 39.88% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Linux-py3.13-pandas3.0.0-pydantic2.12.3 40.03% <0.25%> (-2.78%) ⬇️
unit-tests-pandas-Linux-py3.14-pandas2.3.3-pydantic2.12.3 39.99% <0.25%> (-2.79%) ⬇️
unit-tests-pandas-Linux-py3.14-pandas3.0.0-pydantic2.12.3 40.00% <0.25%> (-2.79%) ⬇️
unit-tests-pandas-Windows-py3.10-pandas2.3.3-pydantic1.10.11 39.80% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-Windows-py3.10-pandas2.3.3-pydantic2.12.3 39.94% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Windows-py3.11-pandas2.3.3-pydantic1.10.11 39.80% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-Windows-py3.11-pandas2.3.3-pydantic2.12.3 39.94% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Windows-py3.11-pandas3.0.0-pydantic1.10.11 39.81% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-Windows-py3.11-pandas3.0.0-pydantic2.12.3 39.96% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Windows-py3.12-pandas2.3.3-pydantic1.10.11 39.79% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-Windows-py3.12-pandas2.3.3-pydantic2.12.3 39.93% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Windows-py3.12-pandas3.0.0-pydantic1.10.11 39.80% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-Windows-py3.12-pandas3.0.0-pydantic2.12.3 39.94% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Windows-py3.13-pandas2.3.3-pydantic1.10.11 39.79% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-Windows-py3.13-pandas2.3.3-pydantic2.12.3 39.93% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Windows-py3.13-pandas3.0.0-pydantic1.10.11 39.80% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-Windows-py3.13-pandas3.0.0-pydantic2.12.3 39.94% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-Windows-py3.14-pandas2.3.3-pydantic2.12.3 39.91% <0.25%> (-2.78%) ⬇️
unit-tests-pandas-Windows-py3.14-pandas3.0.0-pydantic2.12.3 39.92% <0.25%> (-2.78%) ⬇️
unit-tests-pandas-macOS-py3.10-pandas2.3.3-pydantic1.10.11 39.82% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-macOS-py3.10-pandas2.3.3-pydantic2.12.3 39.97% <0.25%> (-2.77%) ⬇️
unit-tests-pandas-macOS-py3.13-pandas2.3.3-pydantic1.10.11 39.81% <0.25%> (-2.76%) ⬇️
unit-tests-pandas-macOS-py3.13-pandas3.0.0-pydantic2.12.3 39.97% <0.25%> (-2.77%) ⬇️
unit-tests-polars-Linux-py3.10-pandas2.3.3-polars1.33.1 28.99% <0.25%> (-2.10%) ⬇️
unit-tests-polars-Linux-py3.11-pandas2.3.3-polars1.33.1 28.98% <0.25%> (-2.10%) ⬇️
unit-tests-polars-Linux-py3.12-pandas2.3.3-polars1.33.1 28.98% <0.25%> (-2.10%) ⬇️
unit-tests-polars-Linux-py3.13-pandas2.3.3-polars1.33.1 28.98% <0.25%> (-2.10%) ⬇️
unit-tests-polars-Linux-py3.14-pandas2.3.3-polars1.33.1 28.86% <0.25%> (-2.10%) ⬇️
unit-tests-polars-Windows-py3.10-pandas2.3.3-polars1.33.1 28.92% <0.25%> (-2.09%) ⬇️
unit-tests-polars-Windows-py3.11-pandas2.3.3-polars1.33.1 28.91% <0.25%> (-2.09%) ⬇️
unit-tests-polars-Windows-py3.12-pandas2.3.3-polars1.33.1 28.91% <0.25%> (-2.09%) ⬇️
unit-tests-polars-Windows-py3.13-pandas2.3.3-polars1.33.1 28.91% <0.25%> (-2.09%) ⬇️
unit-tests-polars-Windows-py3.14-pandas2.3.3-polars1.33.1 28.79% <0.25%> (-2.09%) ⬇️
unit-tests-strategies-Linux-py3.11-pandas2.3.3-pydantic2.12.3 31.99% <0.25%> (-2.18%) ⬇️
unit-tests-strategies-Linux-py3.12-pandas2.3.3-pydantic2.12.3 31.99% <0.25%> (?)
unit-tests-strategies-Linux-py3.14-pandas2.3.3-pydantic2.12.3 31.94% <0.25%> (-2.14%) ⬇️
unit-tests-strategies-Windows-py3.10-pandas2.3.3-pydantic2.12.3 31.92% <0.25%> (?)
unit-tests-xarray-Linux-py3.10-pandas2.3.3-polars 29.74% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Linux-py3.11-pandas2.3.3-polars 29.74% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Linux-py3.12-pandas2.3.3-polars 29.74% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Linux-py3.13-pandas2.3.3-polars 29.74% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Linux-py3.14-pandas2.3.3-polars 29.66% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Windows-py3.10-pandas2.3.3-polars 29.67% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Windows-py3.11-pandas2.3.3-polars 29.67% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Windows-py3.12-pandas2.3.3-polars 29.67% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Windows-py3.13-pandas2.3.3-polars 29.67% <0.42%> (-2.06%) ⬇️
unit-tests-xarray-Windows-py3.14-pandas2.3.3-polars 29.60% <0.42%> (-2.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 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.

cosmicBboy and others added 2 commits July 15, 2026 22:10
Signed-off-by: cosmicBboy <niels.bantilan@gmail.com>
pyspark 4.2.0 (released 2026-07-14) leaks "Worker Monitor for python3"
threads for reused python workers — a regression of SPARK-35009. On
macOS CI runners the Spark JVM exhausts the per-process thread limit
mid-suite and dies with "OutOfMemoryError: unable to create native
thread"; every subsequent test in tests/pyspark/
test_schemas_on_pyspark_pandas.py then fails with
ConnectionRefusedError. Ubuntu runners have higher thread limits and
pass. The same PR head passed CI on pyspark 4.1.2 before 4.2.0 came
out, so this is dependency drift, not a code issue.

Pin pyspark to < 4.2 in the nox testing requirements (CI-only; the
user-facing pyspark extra is unchanged since pandera itself works with
4.2) until the thread leak is fixed upstream.

Also copy the pyproject dependencies list in _testing_requirements
before appending extras — the previous in-place += mutated the shared
PYPROJECT dict, leaking one session's requirements into the next when
multiple nox sessions run in one process.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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