Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pinecone/async_client/async_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ async def query_namespaces(
"""
if not namespaces:
raise ValidationError("namespaces must be a non-empty list")
if not vector and not sparse_vector:
if (vector is None or len(vector) == 0) and not sparse_vector:
raise ValidationError("at least one of 'vector' or 'sparse_vector' must be provided")

valid_metrics = {"cosine", "euclidean", "dotproduct"}
Expand Down
2 changes: 1 addition & 1 deletion pinecone/index/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ def query_namespaces(
"""
if not namespaces:
raise ValidationError("namespaces must be a non-empty list")
if not vector and not sparse_vector:
if (vector is None or len(vector) == 0) and not sparse_vector:
raise ValidationError("at least one of 'vector' or 'sparse_vector' must be provided")

valid_metrics = {"cosine", "euclidean", "dotproduct"}
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/test_async_query_namespaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@
INDEX_HOST = "test-index-abc1234.svc.us-east1-gcp.pinecone.io"


class _BoolAmbiguousVector:
def __init__(self, values: list[float]) -> None:
self._values = values

def __len__(self) -> int:
return len(self._values)

def __getitem__(self, index: int) -> float:
return self._values[index]

def __bool__(self) -> bool:
raise ValueError("truth value is ambiguous")


def _make_index() -> AsyncIndex:
return AsyncIndex(host=INDEX_HOST, api_key="test-key")

Expand Down Expand Up @@ -103,6 +117,23 @@ async def test_query_namespaces_empty_vector_raises(self) -> None:
metric="cosine",
)

@pytest.mark.asyncio
async def test_query_namespaces_does_not_bool_check_vector(self) -> None:
idx = _make_index()
response = _make_query_response([_scored("v1", 0.9)])
vector = _BoolAmbiguousVector([0.1, 0.2])

mock_query = AsyncMock(return_value=response)
with patch.object(idx, "query", mock_query):
await idx.query_namespaces(
vector=vector,
namespaces=["ns1"],
metric="cosine",
)

assert mock_query.await_count == 1
assert mock_query.call_args.kwargs["vector"] is vector

@pytest.mark.asyncio
async def test_query_namespaces_invalid_metric_raises(self) -> None:
idx = _make_index()
Expand Down
29 changes: 29 additions & 0 deletions tests/unit/test_query_namespaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@
INDEX_HOST = "test-index-abc1234.svc.us-east1-gcp.pinecone.io"


class _BoolAmbiguousVector:
def __init__(self, values: list[float]) -> None:
self._values = values

def __len__(self) -> int:
return len(self._values)

def __getitem__(self, index: int) -> float:
return self._values[index]

def __bool__(self) -> bool:
raise ValueError("truth value is ambiguous")


def _make_index() -> Index:
return Index(host=INDEX_HOST, api_key="test-key")

Expand Down Expand Up @@ -137,6 +151,21 @@ def test_query_namespaces_empty_vector_raises(self) -> None:
metric="cosine",
)

def test_query_namespaces_does_not_bool_check_vector(self) -> None:
idx = _make_index()
response = _make_query_response([_scored("v1", 0.9)])
vector = _BoolAmbiguousVector([0.1, 0.2])

with patch.object(idx, "query", return_value=response) as mock_query:
idx.query_namespaces(
vector=vector,
namespaces=["ns1"],
metric="cosine",
)

assert mock_query.call_count == 1
assert mock_query.call_args.kwargs["vector"] is vector

def test_query_namespaces_no_vector_no_sparse_raises(self) -> None:
idx = _make_index()
with pytest.raises(
Expand Down
Loading