fix(core): write use_polars_sort to Ray DatasetContext#355
Conversation
…afni#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>
Ray <2.50 does not expose `DatasetContext.use_polars_sort`, so writing it would silently create an unread attribute and drop the user's setting. Probe for the new attribute and fall back to `use_polars` on older Ray. Since `pyproject.toml` pins `ray>=2.7.0`, we need to support both. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| warnings.warn( | ||
| "`use_polars` is deprecated; use `use_polars_sort` instead. " | ||
| "The value has been forwarded to `use_polars_sort`.", | ||
| DeprecationWarning, | ||
| stacklevel=2, | ||
| ) |
There was a problem hiding this comment.
Use deprecated on the old field instead
Edit: just noticed you already did it, why duplicate the warning in this case?
| # Ray >=2.50 renamed `use_polars` to `use_polars_sort`; set the new name when | ||
| # available to avoid Ray's own DeprecationWarning, and fall back on older Ray. | ||
| if hasattr(ctx, "use_polars_sort"): | ||
| ctx.use_polars_sort = self.use_polars_sort | ||
| else: | ||
| ctx.use_polars = self.use_polars_sort |
There was a problem hiding this comment.
this has to be an explicit Ray version check, that's cleaner to read
It also has to check the legacy self.use_polars variant
|
also, let's add a validator to ensure that the two attributes are not set to contradicting values ( |
…ng values Use packaging.Version to decide between `use_polars` and `use_polars_sort` on Ray's DatasetContext, and raise when callers set the deprecated and new fields to different values instead of silently forwarding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| # `use_polars_sort`; read the effective value (the legacy field wins when | ||
| # both are set only because the validator has already unified them). |
There was a problem hiding this comment.
can you explain this comment? I am seeing the opposite in the validator: use_polars can easily be unset
in general the new parameter should be preferred - even tho we did explicitly forbid conflicts
There was a problem hiding this comment.
Good catch — the comment was wrong. Fixed in 5dc380d: dropped the confusing comment
| ## Unreleased | ||
|
|
||
| ### :bug: Bug Fixes | ||
|
|
||
| - 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)) | ||
|
|
||
| ### :hammer_and_wrench: Other Improvements | ||
|
|
||
| - add `RayDataExecutionOptions.use_polars_sort`; keep `use_polars` as a deprecated alias that forwards its value and emits a `DeprecationWarning` | ||
|
|
There was a problem hiding this comment.
do not edit the changelog, it's auto-generated by git-cliff from conventional commits history.
You can add a ## Changelog section to the PR description for a more verbose changeling entry.
There was a problem hiding this comment.
Reverted in 5dc380d — the ## Unreleased block is removed. I'll add a ## Changelog section to the PR description instead.
| ) | ||
| use_polars: bool | None = Field( | ||
| default=None, | ||
| description="Deprecated. Use `use_polars_sort` instead. Ray 2.55 renamed the underlying `DatasetContext` attribute to `use_polars_sort`.", |
There was a problem hiding this comment.
No need to change the description, we have the deprecated parameter for the deprecation message
There was a problem hiding this comment.
Done in 5dc380d — removed the custom description; relying on the deprecated parameter alone.
| use_polars: bool | None = Field( | ||
| default=None, | ||
| description="Deprecated. Use `use_polars_sort` instead. Ray 2.55 renamed the underlying `DatasetContext` attribute to `use_polars_sort`.", | ||
| deprecated="`use_polars` is deprecated; use `use_polars_sort` instead.", |
There was a problem hiding this comment.
please add "is deprecated and will be removed in dagster-ray 0.5.0"
There was a problem hiding this comment.
Updated in 5dc380d: ``use_polarsis deprecated and will be removed in dagster-ray 0.5.0; useuse_polars_sort` instead.`
- revert changelog edit (auto-generated by git-cliff from commit history) - drop duplicate `description` on deprecated `use_polars` field; pydantic `deprecated=` message is the single source of truth - expand deprecation message to state removal in dagster-ray 0.5.0 - simplify `apply()` to read `self.use_polars_sort` directly — the validator already unifies the legacy field into it Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
danielgafni
left a comment
There was a problem hiding this comment.
It's mostly ok now but I believe there will be a bug if use_polars is set to False: param merging logic doesn't correctly handle this case because it always also checks whether use_polars_sort is set to None (which can't happen due to it being non-optional bool).
It's really surprising how this wasn't caught by one of these May tests added...
Please fix param merging logic and it should be good to go.
| f"({legacy!r} vs {new!r}). `use_polars` is deprecated; set only " | ||
| "`use_polars_sort`." | ||
| ) | ||
| if legacy is not None and new is None: |
There was a problem hiding this comment.
This line is dead code because new can never be None
There was a problem hiding this comment.
Refactored in a735002 to use explicit "use_polars" in data / "use_polars_sort" in data key-presence checks, which removes the ambiguity you called out.
Replace ambiguous `data.get(...) is None` checks with explicit `"key" in data` checks. In `mode="before"` the validator receives the raw input dict, so `None` was overloaded to mean both "key missing" and "value is None"; key-presence is unambiguous and easier to verify at a glance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Pushed a735002 reworking the validator to use key-presence checks instead of |
The retry in RayClusterClient.wait_until_ready only caught
urllib3.exceptions.ProtocolError, so transient apiserver
unavailability that surfaced as MaxRetryError (wrapping
NewConnectionError with "Connection refused") aborted the wait
instead of retrying.
Seen in CI when minikube briefly drops its apiserver mid-test:
Failed to wait for RayCluster ray/dg-dev-... readiness
...
urllib3.exceptions.NewConnectionError: Failed to establish a
new connection: [Errno 111] Connection refused
Catch both ProtocolError and MaxRetryError so the existing
30 x 2s retry budget covers apiserver blips as well as mid-
response network drops.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@danielgafni can you re-run the timeout/failing minicube test? |
Summary
Closes #354
Changelog
RayDataExecutionOptions.use_polarshas been deprecated in favor ofRayDataExecutionOptions.use_polars_sort