mirror of
https://github.com/qdrant/qdrant-client.git
synced 2026-10-02 02:47:43 -05:00
* fix: validate sparse vectors with raises instead of asserts
validate_sparse_vector checks user input, but does so with `assert`.
python -O strips assert statements, so under -O the checks disappear
entirely and a malformed sparse vector is accepted into a local
collection:
$ python -O
>>> client.upsert("t", [PointStruct(id=1, vector={"s": SparseVector(
... indices=[1, 1, 1], values=[1.0, 1.0, 1.0])})])
# accepted
The damage surfaces later rather than at the point of the mistake. A
vector whose indices and values have different lengths is stored, and a
subsequent query raises from deep inside the search path:
>>> client.query_points("t", query=SparseVector(indices=[3], values=[1.0]), using="s")
IndexError: list index out of range
Raise ValueError instead. This also stops user input being reported as
an AssertionError, which is inconsistent with the rest of the client.
* refactor: replace assert error with value error
* fix: validate vectors before write
* fix: add validation for update vectors and batch update points
* fix: validate vector dimensions and batch arguments before write
---------
Co-authored-by: George Panchuk <george.panchuk@qdrant.tech>
26 lines
999 B
Python
26 lines
999 B
Python
import pytest
|
|
|
|
from qdrant_client.http.models import SparseVector
|
|
from qdrant_client.local.sparse import validate_sparse_vector
|
|
|
|
|
|
def test_validate_sparse_vector_accepts_valid() -> None:
|
|
validate_sparse_vector(SparseVector(indices=[], values=[]))
|
|
validate_sparse_vector(SparseVector(indices=[1, 2, 3], values=[0.1, 0.2, 0.3]))
|
|
# indices do not have to be sorted to be valid
|
|
validate_sparse_vector(SparseVector(indices=[3, 1], values=[0.1, 0.2]))
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("vector", "message"),
|
|
[
|
|
(SparseVector(indices=[1, 2], values=[0.1]), "same length"),
|
|
(SparseVector(indices=[1], values=[float("nan")]), "NaN"),
|
|
(SparseVector(indices=[1, 1], values=[0.1, 0.2]), "unique"),
|
|
],
|
|
)
|
|
def test_validate_sparse_vector_rejects_invalid(vector: SparseVector, message: str) -> None:
|
|
# ValueError rather than AssertionError, so the check survives `python -O`
|
|
with pytest.raises(ValueError, match=message):
|
|
validate_sparse_vector(vector)
|