diff --git a/python/python/lancedb/pydantic.py b/python/python/lancedb/pydantic.py index 8b1f991f9..c4dedc0e6 100644 --- a/python/python/lancedb/pydantic.py +++ b/python/python/lancedb/pydantic.py @@ -275,7 +275,18 @@ def _py_type_to_arrow_type(py_type: Type[Any], field: FieldInfo) -> pa.DataType: tz = get_extras(field, "tz") return pa.timestamp("us", tz=tz) elif getattr(py_type, "__origin__", None) in (list, tuple): - child = py_type.__args__[0] + # A bare, unparameterised ``typing.List`` / ``typing.Tuple`` matches this + # branch (its ``__origin__`` is ``list`` / ``tuple``) but has no + # ``__args__``, so we cannot infer the element type. Raise a clear + # ``TypeError`` instead of crashing with an opaque ``AttributeError``. + args = getattr(py_type, "__args__", None) + if not args: + raise TypeError( + "Converting Pydantic type to Arrow Type: unsupported type " + f"{py_type}. Specify the element type, e.g. List[int] instead " + "of a bare List." + ) + child = args[0] return _pydantic_list_child_to_arrow(child, field) raise TypeError( f"Converting Pydantic type to Arrow Type: unsupported type {py_type}." diff --git a/python/python/tests/test_pydantic.py b/python/python/tests/test_pydantic.py index 701bbef5a..e1d533784 100644 --- a/python/python/tests/test_pydantic.py +++ b/python/python/tests/test_pydantic.py @@ -188,6 +188,18 @@ def test_nested_struct_list(): assert schema == expect_schema +def test_bare_generic_raises_type_error(): + # A bare, unparameterised List/Tuple has no element type to map to Arrow. + # It should raise a clear TypeError, not crash with AttributeError: __args__. + for bare in (List, Tuple): + + class TestModel(pydantic.BaseModel): + items: bare + + with pytest.raises(TypeError, match="unsupported type"): + pydantic_to_schema(TestModel) + + def test_nested_struct_list_optional(): class SplitInfo(pydantic.BaseModel): start_frame: int