Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
817ca9d
Friendly warning for unsupported time units
benrutter Aug 18, 2025
93e3107
Merge branch 'main' into time-units-warning
benrutter Aug 18, 2025
fd21b46
Merge branch 'main' into time-units-warning
benrutter Aug 20, 2025
e6f80e3
Merge branch 'main' into time-units-warning
benrutter Aug 21, 2025
de72076
Merge branch 'main' into time-units-warning
benrutter Aug 30, 2025
c5738fc
Warning applied when converting time-units for pre-v2 pandas
benrutter Sep 5, 2025
6dea8cc
Merge branch 'main' into time-units-warning
benrutter Sep 5, 2025
98db669
Merge branch 'main' into time-units-warning
dangotbanned Sep 6, 2025
4ea9f12
test: Move more conditions into marks
dangotbanned Sep 6, 2025
36dc224
test: parametrize over dtype
dangotbanned Sep 6, 2025
4b2af0b
test: fix coverage?
dangotbanned Sep 6, 2025
30e7e34
test: Move to `dtypes_test` and rename
dangotbanned Sep 6, 2025
0f4c8c4
remove stray whitespace
dangotbanned Sep 6, 2025
e96bac7
ci: Temporarily remove warning filter
dangotbanned Sep 6, 2025
0c6c8e1
fix: Don't warn when `"ns"` was specified
dangotbanned Sep 6, 2025
4630474
Merge branch 'main' into time-units-warning
dangotbanned Sep 6, 2025
e4d0a9f
Typo fix
benrutter Sep 7, 2025
85c660c
Merge remote-tracking branch 'upstream/main' into pr/benrutter/3007
dangotbanned Sep 7, 2025
f33edbf
docs(suggestion): Tweaks to warning message
dangotbanned Sep 7, 2025
2f773d2
fix: Add missing underscore
dangotbanned Sep 7, 2025
cdb21ce
test: add missing underscore there as well
dangotbanned Sep 7, 2025
f9712d4
Merge branch 'main' into time-units-warning
benrutter Sep 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion narwhals/_pandas_like/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
SECONDS_PER_DAY,
US_PER_SECOND,
)
from narwhals._exceptions import issue_warning
from narwhals._utils import (
Implementation,
Version,
_DeferredIterable,
check_columns_exist,
isinstance_or_issubclass,
requires,
)
from narwhals.exceptions import ShapeError

Expand Down Expand Up @@ -493,10 +495,21 @@ def narwhals_to_native_dtype( # noqa: C901, PLR0912
if into_pd_type := NW_TO_PD_DTYPES_BACKEND.get(base_type):
return into_pd_type[dtype_backend]
if isinstance_or_issubclass(dtype, dtypes.Datetime):
# Pandas does not support "ms" or "us" time units before version 2.0
if is_pandas_or_modin(implementation) and PANDAS_VERSION < (
2,
): # pragma: no cover
if isinstance(dtype, dtypes.Datetime) and dtype.time_unit != "ns":
found = requires._unparse_version(PANDAS_VERSION)
available = f"available in 'pandas>=2.0', found version {found!r}."
changelog_url = "https://pandas.pydata.org/docs/dev/whatsnew/v2.0.0.html#construction-with-datetime64-or-timedelta64-dtype-with-unsupported-resolution"
msg = (
f"`nw.Datetime(time_unit={dtype.time_unit!r})` is only {available}\n"
"Narwhals has fallen back to using `time_unit='ns'` to avoid an error.\n\n"
"Hint: to avoid this warning, consider either:\n"
f"- Upgrading pandas: {changelog_url}\n"
f"- Using a bare `nw.Datetime`, if this precision is not important"
)
issue_warning(msg, UserWarning)
dt_time_unit = "ns"
else:
dt_time_unit = dtype.time_unit
Expand Down
26 changes: 25 additions & 1 deletion tests/dtypes_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import enum
from contextlib import AbstractContextManager, nullcontext as does_not_warn
from datetime import datetime, timedelta, timezone
from typing import TYPE_CHECKING, Any, Literal

Expand All @@ -17,7 +18,7 @@
from collections.abc import Iterable

from narwhals.typing import IntoSeries, NonNestedDType
from tests.utils import Constructor
from tests.utils import Constructor, ConstructorPandasLike


@pytest.mark.parametrize("time_unit", ["us", "ns", "ms"])
Expand Down Expand Up @@ -558,3 +559,26 @@ def test_dtype_base_type_nested() -> None:
assert nw.Array.base_type() is nw.Array(nw.String, 2).base_type()
assert nw.Struct.base_type() is nw.Struct({"a": nw.Boolean}).base_type()
assert nw.Enum.base_type() is nw.Enum(["beluga", "narwhal"]).base_type()


@pytest.mark.parametrize(
("dtype", "context"),
[
(nw.Datetime("ns"), does_not_warn()),
(nw.Datetime, does_not_warn()),
(nw.Datetime(), pytest.warns(UserWarning, match="time_unit")),
(nw.Datetime("us"), pytest.warns(UserWarning, match="time_unit='us'")),
(nw.Datetime("s"), pytest.warns(UserWarning, match="time_unit='s'")),
],
)
def test_pandas_datetime_ignored_time_unit_warns(
constructor_pandas_like: ConstructorPandasLike,
dtype: nw.Datetime | type[nw.Datetime],
context: AbstractContextManager[Any],
) -> None:
data = {"a": [datetime(2001, 1, 1), None, datetime(2001, 1, 3)]}
expr = nw.col("a").cast(dtype)
df = nw.from_native(constructor_pandas_like(data))
ctx = does_not_warn() if PANDAS_VERSION >= (2,) else context
with ctx:
df.select(expr)
Loading