Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ee9caf3

Browse files
Vector types: optimize error path (#1226)
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 a4d3f30 commit ee9caf3

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

‎src/neo4j/vector.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
]
5454

5555

56+
_DEFAULT = object()
57+
58+
5659
class Vector:
5760
r"""
5861
A class representing a Neo4j vector.
@@ -753,10 +756,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
753756
@classmethod
754757
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
755758
data = tuple(data)
756-
non_float = tuple(item for item in data if not isinstance(item, float))
757-
if non_float:
759+
non_float_gen = (item for item in data if not isinstance(item, float))
760+
non_float = next(non_float_gen, _DEFAULT)
761+
if non_float is not _DEFAULT:
758762
raise TypeError(
759-
f"Cannot build f64 vector from {type(non_float[0]).__name__}, "
763+
f"Cannot build f64 vector from {type(non_float).__name__}, "
760764
"expected float."
761765
)
762766
return cls(_np.fromiter(data, dtype=_np.dtype(">f8")).tobytes())
@@ -826,10 +830,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
826830
@classmethod
827831
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
828832
data = tuple(data)
829-
non_float = tuple(item for item in data if not isinstance(item, float))
830-
if non_float:
833+
non_float_gen = (item for item in data if not isinstance(item, float))
834+
non_float = next(non_float_gen, _DEFAULT)
835+
if non_float is not _DEFAULT:
831836
raise TypeError(
832-
f"Cannot build f32 vector from {type(non_float[0]).__name__}, "
837+
f"Cannot build f32 vector from {type(non_float).__name__}, "
833838
"expected float."
834839
)
835840
return cls(_np.fromiter(data, dtype=_np.dtype(">f4")).tobytes())
@@ -903,10 +908,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
903908
@classmethod
904909
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
905910
data = tuple(data)
906-
non_int = tuple(item for item in data if not isinstance(item, int))
907-
if non_int:
911+
non_int_gen = (item for item in data if not isinstance(item, int))
912+
non_int = next(non_int_gen, _DEFAULT)
913+
if non_int is not _DEFAULT:
908914
raise TypeError(
909-
f"Cannot build i64 vector from {type(non_int[0]).__name__}, "
915+
f"Cannot build i64 vector from {type(non_int).__name__}, "
910916
"expected int."
911917
)
912918
data = _t.cast(tuple[int, ...], data)
@@ -994,10 +1000,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
9941000
@classmethod
9951001
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
9961002
data = tuple(data)
997-
non_int = tuple(item for item in data if not isinstance(item, int))
998-
if non_int:
1003+
non_int_gen = (item for item in data if not isinstance(item, int))
1004+
non_int = next(non_int_gen, _DEFAULT)
1005+
if non_int is not _DEFAULT:
9991006
raise TypeError(
1000-
f"Cannot build i32 vector from {type(non_int[0]).__name__}, "
1007+
f"Cannot build i32 vector from {type(non_int).__name__}, "
10011008
"expected int."
10021009
)
10031010
data = _t.cast(tuple[int, ...], data)
@@ -1085,10 +1092,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
10851092
@classmethod
10861093
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
10871094
data = tuple(data)
1088-
non_int = tuple(item for item in data if not isinstance(item, int))
1089-
if non_int:
1095+
non_int_gen = (item for item in data if not isinstance(item, int))
1096+
non_int = next(non_int_gen, _DEFAULT)
1097+
if non_int is not _DEFAULT:
10901098
raise TypeError(
1091-
f"Cannot build i16 vector from {type(non_int[0]).__name__}, "
1099+
f"Cannot build i16 vector from {type(non_int).__name__}, "
10921100
"expected int."
10931101
)
10941102
data = _t.cast(tuple[int, ...], data)
@@ -1176,10 +1184,11 @@ def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
11761184
@classmethod
11771185
def _from_native_np(cls, data: _t.Iterable[object], /) -> _t.Self:
11781186
data = tuple(data)
1179-
non_int = tuple(item for item in data if not isinstance(item, int))
1180-
if non_int:
1187+
non_int_gen = (item for item in data if not isinstance(item, int))
1188+
non_int = next(non_int_gen, _DEFAULT)
1189+
if non_int is not _DEFAULT:
11811190
raise TypeError(
1182-
f"Cannot build i8 vector from {type(non_int[0]).__name__}, "
1191+
f"Cannot build i8 vector from {type(non_int).__name__}, "
11831192
"expected int."
11841193
)
11851194
data = _t.cast(tuple[int, ...], data)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /