pgvector 0.5.0__tar.gz → 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. {pgvector-0.5.0 → pgvector-0.5.1}/PKG-INFO +1 -1
  2. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/bit.py +6 -7
  3. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sparsevec.py +16 -3
  4. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector.egg-info/PKG-INFO +1 -1
  5. {pgvector-0.5.0 → pgvector-0.5.1}/pyproject.toml +1 -1
  6. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_sparse_vector.py +11 -1
  7. {pgvector-0.5.0 → pgvector-0.5.1}/LICENSE.txt +0 -0
  8. {pgvector-0.5.0 → pgvector-0.5.1}/README.md +0 -0
  9. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/__init__.py +0 -0
  10. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/_utils.py +0 -0
  11. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/asyncpg/__init__.py +0 -0
  12. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/asyncpg/register.py +0 -0
  13. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/__init__.py +0 -0
  14. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/bit.py +0 -0
  15. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/extensions.py +0 -0
  16. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/functions.py +0 -0
  17. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/halfvec.py +0 -0
  18. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/indexes.py +0 -0
  19. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/sparsevec.py +0 -0
  20. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/django/vector.py +0 -0
  21. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/halfvec.py +0 -0
  22. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/__init__.py +0 -0
  23. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/bit.py +0 -0
  24. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/halfvec.py +0 -0
  25. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/sparsevec.py +0 -0
  26. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/peewee/vector.py +0 -0
  27. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/pg8000/__init__.py +0 -0
  28. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/pg8000/register.py +0 -0
  29. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/__init__.py +0 -0
  30. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/bit.py +0 -0
  31. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/halfvec.py +0 -0
  32. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/register.py +0 -0
  33. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/sparsevec.py +0 -0
  34. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg/vector.py +0 -0
  35. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/__init__.py +0 -0
  36. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/halfvec.py +0 -0
  37. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/register.py +0 -0
  38. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/sparsevec.py +0 -0
  39. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/psycopg2/vector.py +0 -0
  40. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/py.typed +0 -0
  41. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/__init__.py +0 -0
  42. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/bit.py +0 -0
  43. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/functions.py +0 -0
  44. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/halfvec.py +0 -0
  45. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/sparsevec.py +0 -0
  46. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/sqlalchemy/vector.py +0 -0
  47. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector/vector.py +0 -0
  48. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector.egg-info/SOURCES.txt +0 -0
  49. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector.egg-info/dependency_links.txt +0 -0
  50. {pgvector-0.5.0 → pgvector-0.5.1}/pgvector.egg-info/top_level.txt +0 -0
  51. {pgvector-0.5.0 → pgvector-0.5.1}/setup.cfg +0 -0
  52. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_asyncpg.py +0 -0
  53. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_bit.py +0 -0
  54. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_django.py +0 -0
  55. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_half_vector.py +0 -0
  56. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_peewee.py +0 -0
  57. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_pg8000.py +0 -0
  58. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_psycopg.py +0 -0
  59. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_psycopg2.py +0 -0
  60. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_sqlalchemy.py +0 -0
  61. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_sqlmodel.py +0 -0
  62. {pgvector-0.5.0 → pgvector-0.5.1}/tests/test_vector.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pgvector
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: pgvector support for Python
5
5
  Author-email: Andrew Kane <andrew@ankane.org>
6
6
  License-Expression: MIT
@@ -13,7 +13,7 @@ class Bit:
13
13
 
14
14
  def __init__(
15
15
  self,
16
- value: bytes | str | list[bool] | np.ndarray[tuple[int, ...], np.dtype[np.bool | np.uint8]],
16
+ value: bytes | str | list[bool] | np.ndarray[tuple[int, ...], np.dtype[np.bool_ | np.uint8]],
17
17
  /
18
18
  ) -> None:
19
19
  if isinstance(value, bytes):
@@ -26,20 +26,19 @@ class Bit:
26
26
  value = ''.join([bits[v] for v in value])
27
27
  except (KeyError, TypeError):
28
28
  raise ValueError('expected list[bool]')
29
+ elif not set(value).issubset({'0', '1'}):
30
+ raise ValueError('expected bit string')
29
31
 
30
32
  length = len(value)
31
33
  if length % 8 != 0:
32
34
  value += '0' * (8 - (length % 8))
33
35
 
34
36
  self._length = length
35
- try:
36
- self._data = int(value, 2).to_bytes(len(value) // 8, byteorder='big')
37
- except ValueError:
38
- raise ValueError('expected bit string')
37
+ self._data = int(value, 2).to_bytes(len(value) // 8, byteorder='big')
39
38
  elif is_ndarray(value):
40
39
  import numpy as np
41
40
 
42
- if value.dtype != np.bool:
41
+ if value.dtype != np.bool_:
43
42
  # skip error for result of np.unpackbits
44
43
  if value.dtype != np.uint8 or np.any(value > 1):
45
44
  raise ValueError('expected elements to be boolean')
@@ -65,7 +64,7 @@ class Bit:
65
64
  # TODO improve
66
65
  return [v != '0' for v in self.to_text()]
67
66
 
68
- def to_numpy(self) -> np.ndarray[tuple[int, ...], np.dtype[np.bool]]:
67
+ def to_numpy(self) -> np.ndarray[tuple[int, ...], np.dtype[np.bool_]]:
69
68
  import numpy as np
70
69
 
71
70
  return np.unpackbits(np.frombuffer(self._data, dtype=np.uint8), count=self._length).astype(bool)
@@ -105,6 +105,11 @@ class SparseVector:
105
105
  def _from_sparse(self, arr: sparray | spmatrix, /) -> None:
106
106
  value: coo_array | coo_matrix = arr.tocoo(copy=False) # type: ignore
107
107
 
108
+ # has_canonical_format added in scipy 1.12+
109
+ if not hasattr(value, 'has_canonical_format') or not value.has_canonical_format:
110
+ value = value.copy()
111
+ value.sum_duplicates()
112
+
108
113
  shape = cast(tuple[int, ...], value.shape)
109
114
  if len(shape) == 1:
110
115
  self._dim = shape[0]
@@ -115,10 +120,18 @@ class SparseVector:
115
120
 
116
121
  if hasattr(value, 'coords'):
117
122
  # scipy 1.13+
118
- self._indices = value.coords[-1].tolist()
123
+ indices = value.coords[-1].tolist()
119
124
  else:
120
- self._indices = value.col.tolist()
121
- self._values = [float(v) for v in value.data]
125
+ indices = value.col.tolist()
126
+
127
+ elements = [(i, v) for i, v in zip(indices, value.data) if v != 0]
128
+
129
+ # has_canonical_format added in scipy 1.12+
130
+ if not hasattr(value, 'has_canonical_format') or not value.has_canonical_format:
131
+ elements.sort()
132
+
133
+ self._indices = [v[0] for v in elements]
134
+ self._values = [float(v[1]) for v in elements]
122
135
 
123
136
  def _from_dense(self, value: list[float] | ndarray, /) -> None:
124
137
  self._dim = len(value)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pgvector
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: pgvector support for Python
5
5
  Author-email: Andrew Kane <andrew@ankane.org>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pgvector"
7
- version = "0.5.0"
7
+ version = "0.5.1"
8
8
  description = "pgvector support for Python"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -54,12 +54,22 @@ class TestSparseVector:
54
54
  if np is None or sparse is None:
55
55
  pytest.skip('NumPy and SciPy required')
56
56
 
57
- arr = sparse.coo_array(np.array([1, 0, 2, 0, 3, 0]))
57
+ arr = sparse.coo_array(([2, 3, 1, 0], ([2, 4, 0, 3],)), shape=(6,))
58
58
  vec = SparseVector(arr)
59
59
  assert vec.to_list() == [1, 0, 2, 0, 3, 0]
60
60
  assert vec.indices() == [0, 2, 4]
61
61
  assert isinstance(vec.values()[0], float)
62
62
 
63
+ def test_coo_array_duplicates(self) -> None:
64
+ if np is None or sparse is None:
65
+ pytest.skip('NumPy and SciPy required')
66
+
67
+ arr = sparse.coo_array(([1, 2], ([1, 1],)), shape=(3,))
68
+ assert arr.todense().tolist() == [0, 3, 0]
69
+ vec = SparseVector(arr)
70
+ assert vec.to_list() == [0, 3, 0]
71
+ assert vec.indices() == [1]
72
+
63
73
  def test_coo_array_dimensions(self) -> None:
64
74
  if np is None or sparse is None:
65
75
  pytest.skip('NumPy and SciPy required')
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes