Skip to content

Commit db2fbba

Browse files
authored
ADR 034: Unify vector string representation (#1238)
* Use Cypher constructor as Vector string representation * Align special float literals with Cypher
1 parent 17ccf09 commit db2fbba

File tree

2 files changed

+318
-31
lines changed

2 files changed

+318
-31
lines changed

src/neo4j/vector.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,9 @@ def __str__(self) -> str:
263263
return str(self._inner)
264264

265265
def __repr__(self) -> str:
266-
return f"{self.__class__.__name__}({self.raw()!r}, {self.dtype!r})"
266+
return (
267+
f"{self.__class__.__name__}({self.raw()!r}, {self.dtype.value!r})"
268+
)
267269

268270
@classmethod
269271
def from_bytes(
@@ -627,6 +629,7 @@ class _InnerVector(_abc.ABC):
627629

628630
dtype: _t.ClassVar[VectorDType]
629631
size: _t.ClassVar[int]
632+
cypher_inner_type_repr: _t.ClassVar[str]
630633
_data: bytes
631634
_data_le: bytes | None
632635

@@ -676,6 +679,8 @@ def data_le(self, data: bytes, /) -> None:
676679

677680
def __init_subclass__(cls) -> None:
678681
super().__init_subclass__()
682+
if _abc.ABC in cls.__bases__:
683+
return
679684
dtype = getattr(cls, "dtype", None)
680685
if not isinstance(dtype, VectorDType):
681686
raise TypeError(
@@ -703,7 +708,12 @@ def __len__(self) -> int:
703708

704709
def __str__(self) -> str:
705710
size = len(self)
706-
return f"Vec[{self.dtype}; {size}]"
711+
type_repr = self.cypher_inner_type_repr
712+
values_repr = self._cypher_values_repr()
713+
return f"vector({values_repr}, {size}, {type_repr})"
714+
715+
@_abc.abstractmethod
716+
def _cypher_values_repr(self) -> str: ...
707717

708718
def __repr__(self) -> str:
709719
cls_name = self.__class__.__name__
@@ -743,11 +753,20 @@ def from_pyarrow(cls, data: pyarrow.Array, /) -> _t.Self:
743753
def to_pyarrow(self) -> pyarrow.Array: ...
744754

745755

746-
class _VecF64(_InnerVector):
756+
class _InnerVectorFloat(_InnerVector, _abc.ABC):
757+
__slots__ = ()
758+
759+
def _cypher_values_repr(self) -> str:
760+
res = str(self.to_native())
761+
return res.replace("nan", "NaN").replace("inf", "Infinity")
762+
763+
764+
class _VecF64(_InnerVectorFloat):
747765
__slots__ = ()
748766

749767
dtype = VectorDType.F64
750768
size = 8
769+
cypher_inner_type_repr = "FLOAT NOT NULL"
751770

752771
@classmethod
753772
def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
@@ -817,11 +836,12 @@ def to_pyarrow(self) -> pyarrow.Array:
817836
)
818837

819838

820-
class _VecF32(_InnerVector):
839+
class _VecF32(_InnerVectorFloat):
821840
__slots__ = ()
822841

823842
dtype = VectorDType.F32
824843
size = 4
844+
cypher_inner_type_repr = "FLOAT32 NOT NULL"
825845

826846
@classmethod
827847
def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
@@ -891,15 +911,23 @@ def to_pyarrow(self) -> pyarrow.Array:
891911
)
892912

893913

914+
class _InnerVectorInt(_InnerVector, _abc.ABC):
915+
__slots__ = ()
916+
917+
def _cypher_values_repr(self) -> str:
918+
return str(self.to_native())
919+
920+
894921
_I64_MIN = -9_223_372_036_854_775_808
895922
_I64_MAX = 9_223_372_036_854_775_807
896923

897924

898-
class _VecI64(_InnerVector):
925+
class _VecI64(_InnerVectorInt):
899926
__slots__ = ()
900927

901928
dtype = VectorDType.I64
902929
size = 8
930+
cypher_inner_type_repr = "INTEGER NOT NULL"
903931

904932
@classmethod
905933
def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
@@ -987,11 +1015,12 @@ def to_pyarrow(self) -> pyarrow.Array:
9871015
_I32_MAX = 2_147_483_647
9881016

9891017

990-
class _VecI32(_InnerVector):
1018+
class _VecI32(_InnerVectorInt):
9911019
__slots__ = ()
9921020

9931021
dtype = VectorDType.I32
9941022
size = 4
1023+
cypher_inner_type_repr = "INTEGER32 NOT NULL"
9951024

9961025
@classmethod
9971026
def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
@@ -1079,11 +1108,12 @@ def to_pyarrow(self) -> pyarrow.Array:
10791108
_I16_MAX = 32_767
10801109

10811110

1082-
class _VecI16(_InnerVector):
1111+
class _VecI16(_InnerVectorInt):
10831112
__slots__ = ()
10841113

10851114
dtype = VectorDType.I16
10861115
size = 2
1116+
cypher_inner_type_repr = "INTEGER16 NOT NULL"
10871117

10881118
@classmethod
10891119
def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:
@@ -1171,11 +1201,12 @@ def to_pyarrow(self) -> pyarrow.Array:
11711201
_I8_MAX = 127
11721202

11731203

1174-
class _VecI8(_InnerVector):
1204+
class _VecI8(_InnerVectorInt):
11751205
__slots__ = ()
11761206

11771207
dtype = VectorDType.I8
11781208
size = 1
1209+
cypher_inner_type_repr = "INTEGER8 NOT NULL"
11791210

11801211
@classmethod
11811212
def _from_native_rust(cls, data: _t.Iterable[object], /) -> _t.Self:

0 commit comments

Comments
 (0)