Skip to content

Commit 29d788b

Browse files
committed
Vector types: optimize error path
The pure-python implementations of `Vector.from_native` perform type checks. This patch makes the driver fail fast when passing incompatible types instead of scanning the whole Iterable parameter.
1 parent f7c0ce6 commit 29d788b

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

src/neo4j/vector.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -753,10 +753,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
753753
@classmethod
754754
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
755755
data = tuple(data)
756-
non_float = tuple(item for item in data if not isinstance(item, float))
756+
non_float_gen = (item for item in data if not isinstance(item, float))
757+
non_float = next(non_float_gen, None)
757758
if non_float:
758759
raise TypeError(
759-
f"Cannot build f64 vector from {type(non_float[0]).__name__}, "
760+
f"Cannot build f64 vector from {type(non_float).__name__}, "
760761
"expected float."
761762
)
762763
return cls(_np.fromiter(data, dtype=_np.dtype(">f8")).tobytes())
@@ -826,10 +827,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
826827
@classmethod
827828
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
828829
data = tuple(data)
829-
non_float = tuple(item for item in data if not isinstance(item, float))
830+
non_float_gen = (item for item in data if not isinstance(item, float))
831+
non_float = next(non_float_gen, None)
830832
if non_float:
831833
raise TypeError(
832-
f"Cannot build f32 vector from {type(non_float[0]).__name__}, "
834+
f"Cannot build f32 vector from {type(non_float).__name__}, "
833835
"expected float."
834836
)
835837
return cls(_np.fromiter(data, dtype=_np.dtype(">f4")).tobytes())
@@ -903,10 +905,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
903905
@classmethod
904906
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
905907
data = tuple(data)
906-
non_int = tuple(item for item in data if not isinstance(item, int))
908+
non_int_gen = (item for item in data if not isinstance(item, int))
909+
non_int = next(non_int_gen, None)
907910
if non_int:
908911
raise TypeError(
909-
f"Cannot build i64 vector from {type(non_int[0]).__name__}, "
912+
f"Cannot build i64 vector from {type(non_int).__name__}, "
910913
"expected int."
911914
)
912915
data = _t.cast(tuple[int, ...], data)
@@ -994,10 +997,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
994997
@classmethod
995998
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
996999
data = tuple(data)
997-
non_int = tuple(item for item in data if not isinstance(item, int))
1000+
non_int_gen = (item for item in data if not isinstance(item, int))
1001+
non_int = next(non_int_gen, None)
9981002
if non_int:
9991003
raise TypeError(
1000-
f"Cannot build i32 vector from {type(non_int[0]).__name__}, "
1004+
f"Cannot build i32 vector from {type(non_int).__name__}, "
10011005
"expected int."
10021006
)
10031007
data = _t.cast(tuple[int, ...], data)
@@ -1085,10 +1089,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
10851089
@classmethod
10861090
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
10871091
data = tuple(data)
1088-
non_int = tuple(item for item in data if not isinstance(item, int))
1092+
non_int_gen = (item for item in data if not isinstance(item, int))
1093+
non_int = next(non_int_gen, None)
10891094
if non_int:
10901095
raise TypeError(
1091-
f"Cannot build i16 vector from {type(non_int[0]).__name__}, "
1096+
f"Cannot build i16 vector from {type(non_int).__name__}, "
10921097
"expected int."
10931098
)
10941099
data = _t.cast(tuple[int, ...], data)
@@ -1176,10 +1181,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
11761181
@classmethod
11771182
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
11781183
data = tuple(data)
1179-
non_int = tuple(item for item in data if not isinstance(item, int))
1184+
non_int_gen = (item for item in data if not isinstance(item, int))
1185+
non_int = next(non_int_gen, None)
11801186
if non_int:
11811187
raise TypeError(
1182-
f"Cannot build i8 vector from {type(non_int[0]).__name__}, "
1188+
f"Cannot build i8 vector from {type(non_int).__name__}, "
11831189
"expected int."
11841190
)
11851191
data = _t.cast(tuple[int, ...], data)

0 commit comments

Comments
 (0)