Skip to content

Commit d848869

Browse files
geoHeilclaude
andcommitted
fix(core): write use_polars_sort to Ray DatasetContext (fixes #354)
Ray 2.55 deprecated `DatasetContext.use_polars` in favor of `use_polars_sort`. Writing the old attribute on every `RayDataExecutionOptions.apply()` / `apply_remote()` emitted a DeprecationWarning on every materialization. Add `use_polars_sort` as the canonical field and keep `use_polars` as a deprecated alias that forwards its value and warns once at construction, preserving the existing API. `apply()` now writes `ctx.use_polars_sort` only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 59c90d5 commit d848869

3 files changed

Lines changed: 75 additions & 3 deletions

File tree

docs/changelog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88

9+
## Unreleased
10+
11+
### :bug: Bug Fixes
12+
13+
- avoid Ray 2.55 `DatasetContext.use_polars` DeprecationWarning on every `RayDataExecutionOptions.apply()` by writing to `use_polars_sort` ([#354](https://github.com/danielgafni/dagster-ray/issues/354))
14+
15+
### :hammer_and_wrench: Other Improvements
16+
17+
- add `RayDataExecutionOptions.use_polars_sort`; keep `use_polars` as a deprecated alias that forwards its value and emits a `DeprecationWarning`
18+
919
## v0.4.4 (26-03-2026)
1020

1121
### :sparkles: Features

src/dagster_ray/configs.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
from __future__ import annotations
22

3+
import warnings
34
from collections.abc import Mapping
45
from typing import Any, Literal
56

67
import dagster as dg
7-
from pydantic import Field
8+
from pydantic import Field, model_validator
89

910
USER_DEFINED_RAY_KEY = "dagster-ray/config"
1011
DAGSTER_RAY_NAMESPACES_ENV_VAR = "DAGSTER_RAY_NAMESPACES"
@@ -77,7 +78,31 @@ class RayDataExecutionOptions(dg.Config):
7778
cpu_limit: int = 5000
7879
gpu_limit: int = 0
7980
verbose_progress: bool = True
80-
use_polars: bool = True
81+
use_polars_sort: bool = Field(
82+
default=True,
83+
description="Whether to use Polars for sort operations in Ray Data. Forwarded to `ray.data.DatasetContext.use_polars_sort`.",
84+
)
85+
use_polars: bool | None = Field(
86+
default=None,
87+
description="Deprecated. Use `use_polars_sort` instead. Ray 2.55 renamed the underlying `DatasetContext` attribute to `use_polars_sort`.",
88+
deprecated="`use_polars` is deprecated; use `use_polars_sort` instead.",
89+
)
90+
91+
@model_validator(mode="before")
92+
@classmethod
93+
def _forward_deprecated_use_polars(cls, data: Any) -> Any:
94+
if not isinstance(data, dict) or data.get("use_polars") is None:
95+
return data
96+
warnings.warn(
97+
"`use_polars` is deprecated; use `use_polars_sort` instead. "
98+
"The value has been forwarded to `use_polars_sort`.",
99+
DeprecationWarning,
100+
stacklevel=2,
101+
)
102+
# Prefer an explicit `use_polars_sort`; otherwise forward the deprecated value.
103+
# Keep `use_polars` on the instance so existing read access keeps working.
104+
data = {**data, "use_polars_sort": data.get("use_polars_sort", data["use_polars"])}
105+
return data
81106

82107
def apply(self):
83108
import ray
@@ -92,7 +117,7 @@ def apply(self):
92117
)
93118

94119
ctx.verbose_progress = self.verbose_progress
95-
ctx.use_polars = self.use_polars
120+
ctx.use_polars_sort = self.use_polars_sort
96121

97122
def apply_remote(self):
98123
import ray

tests/test_configs.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from __future__ import annotations
2+
3+
import warnings
4+
5+
import pytest
6+
7+
from dagster_ray.configs import RayDataExecutionOptions
8+
9+
10+
def test_use_polars_sort_defaults_to_true():
11+
opts = RayDataExecutionOptions()
12+
assert opts.use_polars_sort is True
13+
assert opts.use_polars is None
14+
15+
16+
def test_deprecated_use_polars_is_forwarded_to_use_polars_sort():
17+
with pytest.warns(DeprecationWarning, match="use_polars_sort"):
18+
opts = RayDataExecutionOptions(use_polars=False)
19+
assert opts.use_polars_sort is False
20+
# read-back of the deprecated attribute is preserved for backward compatibility
21+
assert opts.use_polars is False
22+
23+
24+
def test_explicit_use_polars_sort_wins_over_deprecated_alias():
25+
with pytest.warns(DeprecationWarning):
26+
opts = RayDataExecutionOptions(use_polars=True, use_polars_sort=False)
27+
assert opts.use_polars_sort is False
28+
29+
30+
def test_use_polars_sort_alone_does_not_warn_on_construction():
31+
# Construction with only the new field must not emit our deprecation warning.
32+
with warnings.catch_warnings(record=True) as caught:
33+
warnings.simplefilter("always")
34+
opts = RayDataExecutionOptions(use_polars_sort=False)
35+
ours = [w for w in caught if "use_polars_sort" in str(w.message) and "deprecated" in str(w.message).lower()]
36+
assert ours == []
37+
assert opts.use_polars_sort is False

0 commit comments

Comments
 (0)