Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(datatypes): give a more useful error message when trying to cast structs with different fields #10214

Merged
merged 2 commits into from
Sep 25, 2024
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
3 changes: 2 additions & 1 deletion ibis/expr/datatypes/cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ def castable(source: dt.DataType, target: dt.DataType, value: Any = None) -> boo
)
elif target.is_struct():
return source.is_struct() and all(
castable(source[field], target[field]) for field in target.names
field in source and castable(source[field], target[field])
for field in target.names
)
elif target.is_geospatial():
return source.is_geospatial() or source.is_array()
Expand Down
18 changes: 18 additions & 0 deletions ibis/expr/datatypes/tests/test_cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,21 @@ def test_implicitly_castable_int_to_bool(value):
)
def test_implicitly_uncastable_values(source, target, value):
assert not source.castable(target, value=value)


def test_struct_different_fields():
x = dt.Struct({"x": dt.int32})
x2 = dt.Struct({"x": dt.int64})
y = dt.Struct({"y": dt.int32})
xy = dt.Struct({"x": dt.int32, "y": dt.int32})

# Can upcast int32 to int64, but not other way
assert x.castable(x2)
assert not x2.castable(x)
# Can remove a field, but not add one
assert xy.castable(x)
assert not x.castable(xy)

# Missing fields entirely from each other
assert not x.castable(y)
assert not y.castable(x)