Skip to content

Commit 54466d8

Browse files
author
gabriel
committed
fix: Ignore valid dype in cast
1 parent 378f7c1 commit 54466d8

2 files changed

Lines changed: 28 additions & 6 deletions

File tree

dataframely/schema.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
ParquetStorageBackend,
3939
)
4040
from ._typing import DataFrame, LazyFrame, Validation
41-
from .columns import Any as AnyColumn
4241
from .columns import Column, column_from_dict
4342
from .config import Config
4443
from .exc import (
@@ -814,11 +813,19 @@ def cast(
814813
the lazy frame's schema but also means that a call to :meth:`polars.LazyFrame.collect`
815814
further down the line might fail because of the cast and/or missing columns.
816815
"""
817-
lf = df.lazy().select(
818-
# Skip casting for Any columns since they accept any type
819-
pl.col(name) if isinstance(col, AnyColumn) else pl.col(name).cast(col.dtype)
820-
for name, col in cls.columns().items()
821-
)
816+
817+
def _cast_to_schema(
818+
lf: pl.LazyFrame, schema: dict[str, pl.DataType]
819+
) -> pl.LazyFrame:
820+
return lf.select(cls.column_names()).cast(
821+
{
822+
name: col.dtype
823+
for name, col in cls.columns().items()
824+
if name in schema and not col.validate_dtype(schema[name])
825+
}
826+
)
827+
828+
lf = df.lazy().pipe_with_schema(_cast_to_schema)
822829
if isinstance(df, pl.DataFrame):
823830
return lf.collect() # type: ignore
824831
return lf # type: ignore

tests/schema/test_cast.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,18 @@ def test_cast_invalid_schema_lazy() -> None:
4343
lf = MySchema.cast(lf)
4444
with pytest.raises(plexc.ColumnNotFoundError):
4545
lf.collect()
46+
47+
48+
class IntegerSchema(dy.Schema):
49+
a = dy.Integer()
50+
51+
52+
@pytest.mark.parametrize("df_type", [pl.DataFrame, pl.LazyFrame])
53+
def test_cast_preserves_valid_dtype(
54+
df_type: type[pl.DataFrame] | type[pl.LazyFrame],
55+
) -> None:
56+
"""Test that cast doesn't change already valid dtypes (issue #318)."""
57+
df = df_type({"a": [1, 2, 3]}, schema={"a": pl.Int32})
58+
result = IntegerSchema.cast(df)
59+
# Int32 is valid for dy.Integer, so it should NOT be cast to Int64
60+
assert result.lazy().collect_schema()["a"] == pl.Int32

0 commit comments

Comments
 (0)