diff --git a/pinecone/async_client/async_index.py b/pinecone/async_client/async_index.py index a19db0d6..ecce9209 100644 --- a/pinecone/async_client/async_index.py +++ b/pinecone/async_client/async_index.py @@ -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"} diff --git a/pinecone/index/__init__.py b/pinecone/index/__init__.py index 43abb09a..102c4a9b 100644 --- a/pinecone/index/__init__.py +++ b/pinecone/index/__init__.py @@ -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"} diff --git a/tests/unit/test_async_query_namespaces.py b/tests/unit/test_async_query_namespaces.py index 38cf7241..7a4d8d0c 100644 --- a/tests/unit/test_async_query_namespaces.py +++ b/tests/unit/test_async_query_namespaces.py @@ -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") @@ -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() diff --git a/tests/unit/test_query_namespaces.py b/tests/unit/test_query_namespaces.py index 6e642ead..7265bec3 100644 --- a/tests/unit/test_query_namespaces.py +++ b/tests/unit/test_query_namespaces.py @@ -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") @@ -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(