Bump minimum Polars version to 1.35 - #22459
Conversation
📝 WalkthroughWalkthroughThis PR raises the minimum supported Polars version from 1.30 to 1.35 across the cudf-polars project, tightens Polars pins in tooling and environment files, and removes numerous Polars-version-gated code paths across the DSL, expression handlers, containers, aggregation logic, and tests. ChangesMinimum Version Bound and Dependency Updates
Core Library Compatibility Cleanup
Test Suite Compatibility Cleanup
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
python/cudf_polars/tests/expressions/test_sort.py (1)
62-78:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
test_setsortedno longer checks the sorted-hint behavior.
set_sorteddoes not change row values, soassert_gpu_result_equalwill still pass if we stop propagating sorted metadata. Please keep one assertion on the evaluated column metadata, or cover a downstream operation whose correctness depends on that hint.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/cudf_polars/tests/expressions/test_sort.py` around lines 62 - 78, The test_setsorted currently only asserts data equality via assert_gpu_result_equal on q (the LazyFrame after calling set_sorted), which won't catch lost sorted metadata because set_sorted doesn't modify row values; update the test to also assert that the evaluated LazyFrame or its column metadata retains the sorted hint. Locate test_setsorted (create ldf, call ldf.set_sorted("a", descending=descending) producing q) and add an assertion that q (or the materialized frame after q.collect()/q.evaluate()) has the sorted/descending and nulls_last metadata on column "a" (or exercise a downstream operation that relies on the sorted hint, e.g., a merge/join/rolling operation using q that would behave differently without the hint) so the test fails if sorted metadata is not propagated.python/cudf_polars/cudf_polars/dsl/utils/aggregations.py (1)
237-257:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftThis changes rolling
sumsemantics for all-null windows.The new top-level path always applies
replace_nulls(col, 0, is_top=is_top), regardless ofcontext. In rolling mode that turns a non-empty all-null window into0, even though the comment here still calls out the requirednullresult for that case.As per coding guidelines,
python/**/*.{py,pyx}: Logic errors producing wrong results - Verify algorithm correctness and data integrity in operations.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/cudf_polars/cudf_polars/dsl/utils/aggregations.py` around lines 237 - 257, The aggregation for agg.name == "sum" incorrectly always applies replace_nulls(col, 0, is_top=is_top) which changes rolling semantics; update the logic in the agg.name == "sum" branch to branch on the aggregation context (rolling vs groupby/top) instead of unconditionally calling replace_nulls: for non-rolling (groupby/top) keep the current replace_nulls(col, 0, is_top=is_top) behavior, but for rolling produce an expr.NamedExpr(name, ...) that preserves null for non-empty all-null windows and only fills zeros for empty windows (i.e., do not call the top-level replace_nulls for rolling). Locate this change around the agg.name == "sum" block (symbols: agg.name, col, replace_nulls, is_top, expr.NamedExpr) and implement a conditional based on the rolling context to restore correct semantics.python/cudf_polars/tests/expressions/test_rolling.py (1)
321-336:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winIncomplete refactoring:
request.applymarker()called without arguments will raiseTypeError.The
request.applymarker()call on line 330 requires a marker argument but none is provided. This will cause test collection to fail with aTypeError.Comparing with the other rank tests (
test_rank_over_with_ties,test_rank_over_with_null_values,test_rank_over_with_null_group_keys) which correctly removed both therequestfixture and anyapplymarkercalls, this function needs the same treatment.🐛 Proposed fix: Remove unused `request` fixture and no-op `applymarker` call
`@pytest.mark.parametrize`("method", ["ordinal", "dense", "min", "max", "average"]) `@pytest.mark.parametrize`("descending", [False, True]) `@pytest.mark.parametrize`("order_by", [None, ["g2", pl.col("x2") * 2]]) def test_rank_over( engine: pl.GPUEngine, - request, df: pl.LazyFrame, method: RankMethod, *, descending: bool, order_by: None | list[str | pl.Expr], ) -> None: - request.applymarker() q = df.select( pl.col("x") .rank(method=method, descending=descending) .over("g", order_by=order_by) ) assert_gpu_result_equal(q, engine=engine)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/cudf_polars/tests/expressions/test_rolling.py` around lines 321 - 336, The test function test_rank_over contains an unnecessary request.applymarker() call and an unused request fixture parameter which will raise TypeError; remove the request parameter from the test_rank_over signature and delete the request.applymarker() invocation so the function signature matches other rank tests (e.g., test_rank_over_with_ties) and no longer depends on request.applymarker.
🧹 Nitpick comments (2)
python/cudf_polars/tests/test_cache.py (1)
16-17: ⚡ Quick winDon't blanket-xfail this without
strict=True.A non-strict xfail on the whole test will silently accept XPASS and also hides whether the structural cache-node assertions below are still protecting anything. At minimum make the marker strict; ideally split the legacy hit-count assertions into a separate xfailed test and keep the structural checks active.
Minimal improvement
-@pytest.mark.xfail(reason="python no longer manages cache hits") +@pytest.mark.xfail(reason="python no longer manages cache hits", strict=True) def test_cache(engine: pl.GPUEngine):🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/cudf_polars/tests/test_cache.py` around lines 16 - 17, The test marked with pytest.mark.xfail (test_cache) is currently non-strict and may hide XPASS and suppress useful structural assertions; update the xfail marker to be strict (pytest.mark.xfail(reason=..., strict=True)) or, better, split the legacy cache-hit/count assertions into a separate test decorated with xfail(strict=True) (e.g., test_cache_hit_counts_xfail) while keeping the original test_cache to retain the structural cache-node assertions; locate the pytest marker on test_cache and either add strict=True to the marker or move only the flaky assertions into a new xfailed test so the remaining assertions continue to run.python/cudf_polars/tests/expressions/test_agg.py (1)
214-219: ⚡ Quick winAdd degenerate decimal
std/varcases while this path is being ungated.Now that this runs unconditionally, it still only covers a three-row happy path. Empty, all-null, and single-element decimal inputs are the cases most likely to drift when the implementation casts fixed-point values through float first, so I'd extend this before removing the old guard.
As per coding guidelines, "Missing edge case coverage in tests - Include tests for empty, all-null, single-element, and mixed type cases".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/cudf_polars/tests/expressions/test_agg.py` around lines 214 - 219, Extend the test_decimal_std_var coverage by adding degenerate cases (empty dataframe, all-null column, single-element column, and a mixed-type edge if relevant) for the same expressions q = decimal_df.select(std=pl.col("a").std(), var=pl.col("a").var()) used in test_decimal_std_var; create separate small decimal_df variants (or parametrize the test) that produce an empty frame, a frame where column "a" is all None, and a frame with a single decimal value, then call assert_gpu_result_equal(q, engine=engine) for each to ensure std/var behavior matches CPU for these edge conditions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@python/cudf_polars/cudf_polars/containers/datatype.py`:
- Around line 47-51: The TypedDict _DecimalDataTypeHeader must allow nullable
precision: change its precision field from int to int | None in
python/cudf_polars/cudf_polars/typing/__init__.py so it matches Polars'
pl.Decimal(None, scale); then update the consumer that reconstructs the dtype
(the call pl.Decimal(header["precision"], header["scale"]) in datatype handling)
to accept and forward None for precision (i.e., pass header["precision"]
directly or guard so pl.Decimal receives None when present) so no type/value
error occurs when precision is None.
In `@python/cudf_polars/cudf_polars/dsl/ir.py`:
- Around line 1972-1980: The code currently strips ColRef float→float casts
because the if-branch checks only for "both floating" and strips; restrict this
to avoid dropping non-idempotent float casts: in the condition around child and
expr.ColRef (the block using plc.traits.is_floating_point,
plc.traits.is_integral, src.plc_type and dst.plc_type.id()), only allow removing
the cast when it is safe/idempotent — e.g., keep the existing integral-same-id
branch (plc.traits.is_integral && src.plc_type.id() == dst.plc_type.id()), and
remove the broad floating-point branch so float→float casts are not stripped;
alternatively add an explicit idempotence check for decimals/scale+precision
equivalence before stripping. Ensure you update the logic in that if that
references child, src.plc_type and dst.plc_type so float casts remain intact
unless proven idempotent.
In `@python/cudf_polars/cudf_polars/dsl/translate.py`:
- Around line 795-807: The current branch that handles "log" incorrectly asserts
base is expr.NamedExpr which is wrong because translator.translate_expr()
returns expr.Expr; instead check if base is an expr.Literal and build the
expr.BinOp(LOG_BASE, child, expr.Literal(...)) in that case, otherwise raise a
targeted NotImplementedError indicating non-literal log bases are not supported;
replace the assert isinstance(base, expr.NamedExpr) with an if/else that uses
isinstance(base, expr.Literal) and raises NotImplementedError for other expr
types (keep the returned expr.BinOp construction using
plc.binaryop.BinaryOperator.LOG_BASE, child, and base.value).
In `@python/cudf_polars/tests/expressions/test_stringfunction.py`:
- Around line 590-595: The test currently expects Polars to raise
pl.exceptions.InvalidOperationError for negative zfill widths but leaves
cudf_except empty, allowing GPU to succeed and hide the mismatch; update the
assertion so both CPU and GPU paths must exhibit the same failure: set
cudf_except to include the same exception type (or otherwise require that
assert_collect_raises(q, polars_except=pl.exceptions.InvalidOperationError,
cudf_except=(pl.exceptions.InvalidOperationError,)) or the equivalent GPU-side
exception) so str.zfill(pl.col("fill")) fails consistently across CPU and GPU
rather than permitting a divergent success.
---
Outside diff comments:
In `@python/cudf_polars/cudf_polars/dsl/utils/aggregations.py`:
- Around line 237-257: The aggregation for agg.name == "sum" incorrectly always
applies replace_nulls(col, 0, is_top=is_top) which changes rolling semantics;
update the logic in the agg.name == "sum" branch to branch on the aggregation
context (rolling vs groupby/top) instead of unconditionally calling
replace_nulls: for non-rolling (groupby/top) keep the current replace_nulls(col,
0, is_top=is_top) behavior, but for rolling produce an expr.NamedExpr(name, ...)
that preserves null for non-empty all-null windows and only fills zeros for
empty windows (i.e., do not call the top-level replace_nulls for rolling).
Locate this change around the agg.name == "sum" block (symbols: agg.name, col,
replace_nulls, is_top, expr.NamedExpr) and implement a conditional based on the
rolling context to restore correct semantics.
In `@python/cudf_polars/tests/expressions/test_rolling.py`:
- Around line 321-336: The test function test_rank_over contains an unnecessary
request.applymarker() call and an unused request fixture parameter which will
raise TypeError; remove the request parameter from the test_rank_over signature
and delete the request.applymarker() invocation so the function signature
matches other rank tests (e.g., test_rank_over_with_ties) and no longer depends
on request.applymarker.
In `@python/cudf_polars/tests/expressions/test_sort.py`:
- Around line 62-78: The test_setsorted currently only asserts data equality via
assert_gpu_result_equal on q (the LazyFrame after calling set_sorted), which
won't catch lost sorted metadata because set_sorted doesn't modify row values;
update the test to also assert that the evaluated LazyFrame or its column
metadata retains the sorted hint. Locate test_setsorted (create ldf, call
ldf.set_sorted("a", descending=descending) producing q) and add an assertion
that q (or the materialized frame after q.collect()/q.evaluate()) has the
sorted/descending and nulls_last metadata on column "a" (or exercise a
downstream operation that relies on the sorted hint, e.g., a merge/join/rolling
operation using q that would behave differently without the hint) so the test
fails if sorted metadata is not propagated.
---
Nitpick comments:
In `@python/cudf_polars/tests/expressions/test_agg.py`:
- Around line 214-219: Extend the test_decimal_std_var coverage by adding
degenerate cases (empty dataframe, all-null column, single-element column, and a
mixed-type edge if relevant) for the same expressions q =
decimal_df.select(std=pl.col("a").std(), var=pl.col("a").var()) used in
test_decimal_std_var; create separate small decimal_df variants (or parametrize
the test) that produce an empty frame, a frame where column "a" is all None, and
a frame with a single decimal value, then call assert_gpu_result_equal(q,
engine=engine) for each to ensure std/var behavior matches CPU for these edge
conditions.
In `@python/cudf_polars/tests/test_cache.py`:
- Around line 16-17: The test marked with pytest.mark.xfail (test_cache) is
currently non-strict and may hide XPASS and suppress useful structural
assertions; update the xfail marker to be strict (pytest.mark.xfail(reason=...,
strict=True)) or, better, split the legacy cache-hit/count assertions into a
separate test decorated with xfail(strict=True) (e.g.,
test_cache_hit_counts_xfail) while keeping the original test_cache to retain the
structural cache-node assertions; locate the pytest marker on test_cache and
either add strict=True to the marker or move only the flaky assertions into a
new xfailed test so the remaining assertions continue to run.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 7802ed01-351f-45b8-84dc-9d0e056c1d0e
📒 Files selected for processing (36)
.pre-commit-config.yamlconda/environments/all_cuda-129_arch-aarch64.yamlconda/environments/all_cuda-129_arch-x86_64.yamlconda/environments/all_cuda-131_arch-aarch64.yamlconda/environments/all_cuda-131_arch-x86_64.yamlconda/recipes/cudf-polars/recipe.yamldependencies.yamlpython/cudf_polars/cudf_polars/containers/datatype.pypython/cudf_polars/cudf_polars/dsl/expressions/string.pypython/cudf_polars/cudf_polars/dsl/ir.pypython/cudf_polars/cudf_polars/dsl/translate.pypython/cudf_polars/cudf_polars/dsl/utils/aggregations.pypython/cudf_polars/cudf_polars/experimental/benchmarks/asserts.pypython/cudf_polars/cudf_polars/testing/asserts.pypython/cudf_polars/cudf_polars/utils/versions.pypython/cudf_polars/pyproject.tomlpython/cudf_polars/tests/dsl/test_serialization.pypython/cudf_polars/tests/experimental/test_explain.pypython/cudf_polars/tests/experimental/test_select.pypython/cudf_polars/tests/expressions/test_agg.pypython/cudf_polars/tests/expressions/test_booleanfunction.pypython/cudf_polars/tests/expressions/test_casting.pypython/cudf_polars/tests/expressions/test_numeric_binops.pypython/cudf_polars/tests/expressions/test_numeric_unaryops.pypython/cudf_polars/tests/expressions/test_rolling.pypython/cudf_polars/tests/expressions/test_sort.pypython/cudf_polars/tests/expressions/test_stringfunction.pypython/cudf_polars/tests/expressions/test_struct.pypython/cudf_polars/tests/test_cache.pypython/cudf_polars/tests/test_drop_nulls.pypython/cudf_polars/tests/test_groupby.pypython/cudf_polars/tests/test_join.pypython/cudf_polars/tests/test_mapfunction.pypython/cudf_polars/tests/test_scan.pypython/cudf_polars/tests/test_select.pypython/cudf_polars/tests/test_window_functions.py
💤 Files with no reviewable changes (2)
- python/cudf_polars/tests/expressions/test_numeric_unaryops.py
- python/cudf_polars/tests/experimental/test_explain.py
There was a problem hiding this comment.
🧹 Nitpick comments (1)
python/cudf_polars/cudf_polars/dsl/translate.py (1)
800-807: ⚡ Quick winPrefer explicit
NotImplementedErroroverassertfor feature detection.While the type check has been corrected to
expr.Literal, usingassertfor runtime feature detection is non-idiomatic. Assertions can be disabled with-Oand convey "invariant violation" rather than "unsupported input". An explicit check provides a clearer error message and correct semantics.Proposed fix
(child, base) = children - assert isinstance(base, expr.Literal) + if not isinstance(base, expr.Literal): + raise NotImplementedError("log with non-literal base is not supported") return expr.BinOp( dtype, plc.binaryop.BinaryOperator.LOG_BASE, child, expr.Literal(dtype, base.value), )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@python/cudf_polars/cudf_polars/dsl/translate.py` around lines 800 - 807, Replace the runtime assertion with an explicit check and raise NotImplementedError when the second child is not a literal: instead of using "assert isinstance(base, expr.Literal)" in the block that returns expr.BinOp(..., plc.binaryop.BinaryOperator.LOG_BASE, ...), test "isinstance(base, expr.Literal)" and raise NotImplementedError with a clear message (e.g., "LOG_BASE requires a literal base") referencing the symbol names expr.Literal and plc.binaryop.BinaryOperator.LOG_BASE so callers see a proper runtime error rather than an assert that can be disabled.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@python/cudf_polars/cudf_polars/dsl/translate.py`:
- Around line 800-807: Replace the runtime assertion with an explicit check and
raise NotImplementedError when the second child is not a literal: instead of
using "assert isinstance(base, expr.Literal)" in the block that returns
expr.BinOp(..., plc.binaryop.BinaryOperator.LOG_BASE, ...), test
"isinstance(base, expr.Literal)" and raise NotImplementedError with a clear
message (e.g., "LOG_BASE requires a literal base") referencing the symbol names
expr.Literal and plc.binaryop.BinaryOperator.LOG_BASE so callers see a proper
runtime error rather than an assert that can be disabled.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 522a6f3f-d638-4299-8b35-73b4d7801a1a
📒 Files selected for processing (7)
conda/environments/all_cuda-129_arch-aarch64.yamlconda/environments/all_cuda-129_arch-x86_64.yamlconda/environments/all_cuda-131_arch-aarch64.yamlconda/environments/all_cuda-131_arch-x86_64.yamldependencies.yamlpython/cudf_polars/cudf_polars/dsl/translate.pypython/cudf_polars/tests/expressions/test_rolling.py
✅ Files skipped from review due to trivial changes (3)
- conda/environments/all_cuda-129_arch-x86_64.yaml
- conda/environments/all_cuda-131_arch-aarch64.yaml
- conda/environments/all_cuda-131_arch-x86_64.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
- dependencies.yaml
- conda/environments/all_cuda-129_arch-aarch64.yaml
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
ci/test_wheel_cudf_polars.sh (1)
74-83:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winHandle timeout expiry explicitly so CI failures are diagnosable.
With the timeout set to 15m, timeouts become a realistic failure mode; those exits are currently reported as generic test failures. The GNU
timeoutcommand returns exit code 124 when the time limit is reached. Please branch on this exit code to log a timeout-specific message, improving CI diagnostics.Suggested patch
- timeout 15m ./ci/run_cudf_polars_pytests.sh \ + timeout 15m ./ci/run_cudf_polars_pytests.sh \ "${COVERAGE_ARGS[@]}" \ --numprocesses=8 \ --dist=worksteal \ --junitxml="${RAPIDS_TESTS_DIR}/junit-cudf-polars-${version}.xml" - if [ $? -ne 0 ]; then + test_exit=$? + if [ ${test_exit} -eq 124 ]; then + EXITCODE=1 + FAILED+=("${version}") + rapids-logger "Tests timed out after 15m for polars==${version}" + elif [ ${test_exit} -ne 0 ]; then EXITCODE=1 FAILED+=("${version}") rapids-logger "Tests failed for polars==${version}" else PASSED+=("${version}")Per the coding guideline: "Check for proper error handling and meaningful error messages."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@ci/test_wheel_cudf_polars.sh` around lines 74 - 83, The timeout invocation of ./ci/run_cudf_polars_pytests.sh needs explicit handling for GNU timeout's 124 exit so CI can report timeouts separately: after the timeout command (the block using timeout 15m ./ci/run_cudf_polars_pytests.sh) inspect the exit status ($?) and if it equals 124 call rapids-logger with a timeout-specific message (e.g., "Tests timed out for polars==${version}"), set EXITCODE=1 and add "${version}" to FAILED—otherwise retain the existing failure branch that logs generic test failures; reference the existing EXITCODE, FAILED, and rapids-logger symbols when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@ci/test_wheel_cudf_polars.sh`:
- Around line 74-83: The timeout invocation of ./ci/run_cudf_polars_pytests.sh
needs explicit handling for GNU timeout's 124 exit so CI can report timeouts
separately: after the timeout command (the block using timeout 15m
./ci/run_cudf_polars_pytests.sh) inspect the exit status ($?) and if it equals
124 call rapids-logger with a timeout-specific message (e.g., "Tests timed out
for polars==${version}"), set EXITCODE=1 and add "${version}" to
FAILED—otherwise retain the existing failure branch that logs generic test
failures; reference the existing EXITCODE, FAILED, and rapids-logger symbols
when making the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: ccffae54-d904-4eb3-a7c5-50238813513e
📒 Files selected for processing (1)
ci/test_wheel_cudf_polars.sh
|
/merge |
Broken off from NVIDIA#22048 Updates the minimum Polars version in cudf_polars based on the minimum supported Polars version in cloud environments NVIDIA#22048 (comment) Code changes are purely removals (with minor reorganizations). Commits are split by workarounds removed per version. Additionally, shortens the `timeout` of each test run per Polars version to 15 minutes each from 1 hour. A "normal" test run per Polars version in CI should complete in 2-3 minutes so 15 minutes should hopefully be OK Authors: - Matthew Roeschke (https://github.com/mroeschke) Approvers: - Tom Augspurger (https://github.com/TomAugspurger) - Matthew Murray (https://github.com/Matt711) - Bradley Dice (https://github.com/bdice) URL: NVIDIA#22459
Description
Broken off from #22048
Updates the minimum Polars version in cudf_polars based on the minimum supported Polars version in cloud environments #22048 (comment)
Code changes are purely removals (with minor reorganizations). Commits are split by workarounds removed per version.
Additionally, shortens the
timeoutof each test run per Polars version to 15 minutes each from 1 hour. A "normal" test run per Polars version in CI should complete in 2-3 minutes so 15 minutes should hopefully be OKChecklist