Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion narwhals/_polars/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ def from_dicts(
if not data:
native = pl.DataFrame(schema=pl_schema)
elif FROM_DICTS_ACCEPTS_MAPPINGS or isinstance(data[0], dict):
native = pl.from_dicts(data, pl_schema) # type: ignore[arg-type]
native = pl.from_dicts(data, pl_schema)
else: # pragma: no cover
columns = pl_schema or tuple(data[0])
native = pl.DataFrame(
Expand Down
32 changes: 20 additions & 12 deletions narwhals/_polars/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,23 @@
BACKEND_VERSION = Implementation.POLARS._backend_version()
"""Static backend version for `polars`."""

SERIES_ACCEPTS_PD_INDEX: Final[bool] = BACKEND_VERSION >= (0, 20, 7)
"""`pl.Series(values: pd.Index)` fixed in https://github.com/pola-rs/polars/pull/14087"""

SERIES_RESPECTS_DTYPE: Final[bool] = BACKEND_VERSION >= (0, 20, 26)
"""`pl.Series(dtype=...)` fixed in https://github.com/pola-rs/polars/pull/15962

Includes `SERIES_ACCEPTS_PD_INDEX`.
"""

SERIES_ACCEPTS_PD_INDEX: Final[bool] = BACKEND_VERSION >= (0, 20, 7)
"""`pl.Series(values: pd.Index)` fixed in https://github.com/pola-rs/polars/pull/14087"""
HAS_INT_128 = BACKEND_VERSION >= (1, 18, 0)
"""https://github.com/pola-rs/polars/pull/20232"""

FROM_DICTS_ACCEPTS_MAPPINGS: Final[bool] = BACKEND_VERSION >= (1, 30, 0)
"""`pl.from_dicts(data: Iterable[Mapping[str, Any]])` since https://github.com/pola-rs/polars/pull/22638
"""`pl.from_dicts(data: Iterable[Mapping[str, Any]])` since https://github.com/pola-rs/polars/pull/22638"""

Typing fix in https://github.com/pola-rs/polars/pull/24584
"""
HAS_UINT_128 = BACKEND_VERSION >= (1, 34, 0)
"""https://github.com/pola-rs/polars/pull/24346"""


@overload
Expand Down Expand Up @@ -99,8 +102,7 @@ def native_to_narwhals_dtype( # noqa: C901, PLR0912
return dtypes.Float64()
if dtype == pl.Float32:
return dtypes.Float32()
if hasattr(pl, "Int128") and dtype == pl.Int128: # pragma: no cover
# Not available for Polars pre 1.8.0
if HAS_INT_128 and dtype == pl.Int128:
return dtypes.Int128()
if dtype == pl.Int64:
return dtypes.Int64()
Expand All @@ -110,8 +112,7 @@ def native_to_narwhals_dtype( # noqa: C901, PLR0912
return dtypes.Int16()
if dtype == pl.Int8:
return dtypes.Int8()
if hasattr(pl, "UInt128") and dtype == pl.UInt128: # pyright: ignore[reportAttributeAccessIssue] # pragma: no cover
# Not available for Polars pre 1.8.0
if HAS_UINT_128 and dtype == pl.UInt128:
return dtypes.UInt128()
if dtype == pl.UInt64:
return dtypes.UInt64()
Expand Down Expand Up @@ -169,6 +170,15 @@ def native_to_narwhals_dtype( # noqa: C901, PLR0912


dtypes = Version.MAIN.dtypes


def _version_dependent_dtypes() -> dict[type[DType], pl.DataType]:
if not HAS_INT_128: # pragma: no cover
return {}
nw_to_pl: dict[type[DType], pl.DataType] = {dtypes.Int128: pl.Int128()}
return nw_to_pl | {dtypes.UInt128: pl.UInt128()} if HAS_UINT_128 else nw_to_pl


NW_TO_PL_DTYPES: Mapping[type[DType], pl.DataType] = {
dtypes.Float64: pl.Float64(),
dtypes.Float32: pl.Float32(),
Expand All @@ -188,6 +198,7 @@ def native_to_narwhals_dtype( # noqa: C901, PLR0912
dtypes.UInt64: pl.UInt64(),
dtypes.Object: pl.Object(),
dtypes.Unknown: pl.Unknown(),
**_version_dependent_dtypes(),
}
UNSUPPORTED_DTYPES = (dtypes.Decimal,)

Expand All @@ -199,9 +210,6 @@ def narwhals_to_native_dtype( # noqa: C901
base_type = dtype.base_type()
if pl_type := NW_TO_PL_DTYPES.get(base_type):
return pl_type
if dtype == dtypes.Int128 and hasattr(pl, "Int128"):
# Not available for Polars pre 1.8.0
return pl.Int128()
if isinstance_or_issubclass(dtype, dtypes.Enum):
if version is Version.V1:
msg = "Converting to Enum is not supported in narwhals.stable.v1"
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ typing = [ # keep some of these pinned and bump periodically so there's fewer s
"pyright",
"pyarrow-stubs==19.2",
"sqlframe",
"polars==1.32.2",
"polars==1.34.0",
"uv",
"narwhals[ibis]",
]
Expand Down
17 changes: 14 additions & 3 deletions tests/dtypes_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
if TYPE_CHECKING:
from collections.abc import Iterable

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


Expand Down Expand Up @@ -235,6 +235,10 @@ def test_pandas_fixed_offset_1302() -> None:
pass


def from_native_collect_schema(native: IntoFrame) -> nw.Schema:
return nw.from_native(native).collect_schema()


def test_huge_int() -> None:
pytest.importorskip("duckdb")
pytest.importorskip("polars")
Expand All @@ -245,11 +249,18 @@ def test_huge_int() -> None:
df = pl.DataFrame({"a": [1, 2, 3]})

if POLARS_VERSION >= (1, 18):
result = nw.from_native(df.select(pl.col("a").cast(pl.Int128))).collect_schema()
result = from_native_collect_schema(df.select(pl.col("a").cast(pl.Int128)))
assert result["a"] == nw.Int128
assert result.to_polars()["a"] == pl.Int128
else: # pragma: no cover
# Int128 was not available yet
pass
if POLARS_VERSION >= (1, 34):
result = from_native_collect_schema(df.select(pl.col("a").cast(pl.UInt128)))
assert result["a"] == nw.UInt128
assert result.to_polars()["a"] == pl.UInt128
else: # pragma: no cover
pass

rel = duckdb.sql("""
select cast(a as int128) as a
Expand All @@ -263,7 +274,7 @@ def test_huge_int() -> None:
select cast(a as uint128) as a
from df
""")
result = nw.from_native(rel).collect_schema()
result = from_native_collect_schema(rel)
assert result["a"] == nw.UInt128

# TODO(unassigned): once other libraries support Int128/UInt128,
Expand Down
Loading