Skip to content

Support pl.Expr.dt.millennium - #23154

Merged
rapids-bot[bot] merged 2 commits into
NVIDIA:mainfrom
mroeschke:cudf_polars/enh/dt_millennium
Jul 8, 2026
Merged

Support pl.Expr.dt.millennium#23154
rapids-bot[bot] merged 2 commits into
NVIDIA:mainfrom
mroeschke:cudf_polars/enh/dt_millennium

Conversation

@mroeschke

Copy link
Copy Markdown
Contributor

Description

xref #23151

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

@mroeschke mroeschke self-assigned this Jul 7, 2026
@mroeschke
mroeschke requested a review from a team as a code owner July 7, 2026 22:31
@mroeschke mroeschke added the improvement Improvement / enhancement to an existing function label Jul 7, 2026
@mroeschke
mroeschke requested a review from wence- July 7, 2026 22:31
@mroeschke mroeschke added the non-breaking Non-breaking change label Jul 7, 2026
@github-actions github-actions Bot added Python Affects Python cuDF API. cudf-polars Issues specific to cudf-polars labels Jul 7, 2026
@GPUtester GPUtester moved this to In Progress in cuDF Python Jul 7, 2026
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7a820a68-fb43-444e-9bbf-5fd6dfe35500

📥 Commits

Reviewing files that changed from the base of the PR and between 912c45d and 29f1149.

📒 Files selected for processing (2)
  • python/cudf_polars/cudf_polars/dsl/expressions/datetime.py
  • python/cudf_polars/tests/expressions/test_datetime_basic.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • python/cudf_polars/cudf_polars/dsl/expressions/datetime.py

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added support for millennium calculations on date and datetime values.
    • Updated century/millennium computation so results are consistent across supported calendar inputs, including boundary and negative offsets.
  • Tests
    • Expanded test coverage to validate both century and millennium behaviors on GPU for multiple date/time resolutions.
    • Added/extended checks for extreme year inputs to confirm correct results in boundary cases.

Walkthrough

Adds millennium support to TemporalFunction for datetime year-derived calculations and extends the existing datetime tests to exercise both century and millennium cases.

Changes

Millennium/Century Computation

Layer / File(s) Summary
Divisor mapping and op registration
python/cudf_polars/cudf_polars/dsl/expressions/datetime.py
Adds Millennium to the century/millennium divisor mapping, updates valid-op registration to include the mapping keys, and adjusts a nearby evaluation comment.
Datetime millennium coverage
python/cudf_polars/tests/expressions/test_datetime_basic.py
Expands the existing century parametrizations to include millennium for standard and extreme-year date cases.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: vyasr

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding pl.Expr.dt.millennium support.
Description check ✅ Passed The description is related to the change by referencing the linked issue and checklist for the millennium support work.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
python/cudf_polars/cudf_polars/dsl/expressions/datetime.py (1)

136-140: 🎯 Functional Correctness | 🔵 Trivial | 🏗️ Heavy lift

"Century" is named/documented but not actually supported.

The mapping is named _CENTURY_MILLENNIUM_DIVISOR and its comment describes deriving "century/millennium", Name.Century exists in the enum, and Polars exposes pl.Expr.dt.century() (returning Int32, e.g. year 2000 → 20, 2001 → 21). However only Name.Millennium is registered here and in _valid_ops, so .dt.century() on the GPU engine raises NotImplementedError and silently falls back to CPU.

Given the arithmetic branch is already generic over the divisor, enabling century is low effort. Have you considered wiring it in now, or otherwise narrowing the naming/comments to millennium only to avoid implying support that isn't there?

♻️ Enable century alongside millennium
     _CENTURY_MILLENNIUM_DIVISOR: ClassVar[dict[Name, int]] = {
+        Name.Century: 100,
         Name.Millennium: 1_000,
     }

and register it:

         Name.Truncate,
+        Name.Century,
         Name.Millennium,

Confirm translate.py does not require Name.Century in its needs_cast set (it currently omits both Century and Millennium, which is correct only if libcudf returns INT32 matching Polars).

Also applies to: 153-153

🤖 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/expressions/datetime.py` around lines 136
- 140, The datetime extraction mapping currently advertises century/millennium
support but only registers Millennium, so dt.century() still falls back. Update
the datetime expression handling in datetime.py by adding Name.Century to the
divisor mapping and the valid ops registration, reusing the same arithmetic
branch as Millennium; if you choose not to support it, rename the
mapping/comment to millennium-only and remove Century references so the API
contract matches behavior. Also verify translate.py still does not need a cast
entry for Name.Century or Name.Millennium.
python/cudf_polars/tests/expressions/test_datetime_basic.py (1)

216-234: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Good edge coverage; single-value parametrize is a smell.

The tests cover null handling and the century/millennium boundary years (1900/1901, 2000/2001), which is solid. However @pytest.mark.parametrize("method", ["millennium"]) with a single value adds no coverage and suggests "century" was intended to be included. Once century is supported (see the datetime.py comment), extend the list; otherwise drop the parametrize.

♻️ Once century is supported
-@pytest.mark.parametrize("method", ["millennium"])
+@pytest.mark.parametrize("method", ["century", "millennium"])

Also applies to: 237-252

🤖 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_datetime_basic.py` around lines 216
- 234, The test_century_millennium parametrization is a no-op with only
"millennium", so either remove the single-value
pytest.mark.parametrize("method", ...) if only millennium should be tested, or
expand it to include "century" once supported. Update the
test_century_millennium case to cover the intended dt accessor methods
consistently and avoid redundant parametrization.
🤖 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/expressions/datetime.py`:
- Around line 136-140: The datetime extraction mapping currently advertises
century/millennium support but only registers Millennium, so dt.century() still
falls back. Update the datetime expression handling in datetime.py by adding
Name.Century to the divisor mapping and the valid ops registration, reusing the
same arithmetic branch as Millennium; if you choose not to support it, rename
the mapping/comment to millennium-only and remove Century references so the API
contract matches behavior. Also verify translate.py still does not need a cast
entry for Name.Century or Name.Millennium.

In `@python/cudf_polars/tests/expressions/test_datetime_basic.py`:
- Around line 216-234: The test_century_millennium parametrization is a no-op
with only "millennium", so either remove the single-value
pytest.mark.parametrize("method", ...) if only millennium should be tested, or
expand it to include "century" once supported. Update the
test_century_millennium case to cover the intended dt accessor methods
consistently and avoid redundant parametrization.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a9fab8d4-3a29-462f-8411-aa9257a61429

📥 Commits

Reviewing files that changed from the base of the PR and between 4cce29f and 912c45d.

📒 Files selected for processing (2)
  • python/cudf_polars/cudf_polars/dsl/expressions/datetime.py
  • python/cudf_polars/tests/expressions/test_datetime_basic.py

@mroeschke

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit ebdf4ab into NVIDIA:main Jul 8, 2026
108 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in cuDF Python Jul 8, 2026
@mroeschke
mroeschke deleted the cudf_polars/enh/dt_millennium branch July 8, 2026 21:58
@coderabbitai coderabbitai Bot mentioned this pull request Jul 9, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cudf-polars Issues specific to cudf-polars improvement Improvement / enhancement to an existing function non-breaking Non-breaking change Python Affects Python cuDF API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants