fix(python): install the _zvec extension inside the zvec package (#511)

This commit is contained in:
Cuiys 2026-06-24 11:23:52 +08:00 committed by GitHub
parent 22744f2c81
commit d25f3a4552
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 57 additions and 47 deletions

View File

@ -174,7 +174,10 @@ if(BUILD_PYTHON_BINDINGS)
# COMPONENT python: only these runtime artifacts are pulled into the wheel
# (see install.components in pyproject.toml). The cc_library(PACKED) SDK
# install rules use the default component and are excluded from the wheel.
install(TARGETS _zvec LIBRARY DESTINATION ${ZVEC_PY_INSTALL_DIR}
# Install the extension inside the zvec package (zvec/_zvec*.so) rather than
# at the site-packages root, so it does not pollute the top-level namespace.
# The Python code imports it as `zvec._zvec` accordingly.
install(TARGETS _zvec LIBRARY DESTINATION ${ZVEC_PY_INSTALL_DIR}/zvec
COMPONENT python)
# DiskAnn ships as a runtime-loaded shared module
@ -182,7 +185,8 @@ if(BUILD_PYTHON_BINDINGS)
# first time a DiskAnn index is created users never call any load
# function. The Python extension resolves the module next to _zvec.so
# (see the $ORIGIN rpath in src/binding/python/CMakeLists.txt); the
# module must therefore be installed alongside _zvec.so in the wheel.
# module must therefore be installed alongside _zvec.so, i.e. inside the
# zvec package directory as well.
#
# Gate on DISKANN_SUPPORTED, not on the target's existence: on unsupported
# platforms (e.g. macOS / ARM64) the core_knn_diskann target is still
@ -191,7 +195,7 @@ if(BUILD_PYTHON_BINDINGS)
# (#if DISKANN_SUPPORTED). Shipping that stub is pure dead weight, so it is
# only packaged where DiskAnn is real currently Linux x86_64 with libaio.
if(DISKANN_SUPPORTED)
install(TARGETS core_knn_diskann LIBRARY DESTINATION ${ZVEC_PY_INSTALL_DIR}
install(TARGETS core_knn_diskann LIBRARY DESTINATION ${ZVEC_PY_INSTALL_DIR}/zvec
COMPONENT python)
endif()
# Bundle cppjieba's dictionary files so the `jieba` FTS tokenizer works

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import math
import pytest
from _zvec import _Doc
from zvec._zvec import _Doc
from zvec.model.convert import convert_to_py_doc, convert_to_cpp_doc
from zvec import Doc, CollectionSchema, DataType, FieldSchema, VectorSchema

View File

@ -17,7 +17,7 @@ import math
import pytest
from _zvec import _Doc
from zvec._zvec import _Doc
from zvec import FieldSchema, VectorSchema, Doc, DataType

View File

@ -79,7 +79,7 @@ class TestFtsQueryBinding:
def test_import_fts_query(self):
"""_Fts should be importable from _zvec.param."""
from _zvec.param import _Fts
from zvec._zvec.param import _Fts
fts = _Fts()
assert fts.query_string == ""
@ -87,7 +87,7 @@ class TestFtsQueryBinding:
def test_fts_query_set_fields(self):
"""Setting fields on _Fts should work."""
from _zvec.param import _Fts
from zvec._zvec.param import _Fts
fts = _Fts()
fts.query_string = "+hello -world"
@ -99,7 +99,7 @@ class TestFtsQueryBinding:
def test_fts_query_pickle(self):
"""_Fts should support pickling."""
from _zvec.param import _Fts
from zvec._zvec.param import _Fts
fts = _Fts()
fts.query_string = "+vector search"
@ -112,7 +112,7 @@ class TestFtsQueryBinding:
def test_search_query_fts_field(self):
"""_SearchQuery should have fts field."""
from _zvec.param import _Fts, _SearchQuery
from zvec._zvec.param import _Fts, _SearchQuery
vq = _SearchQuery()
# fts should be None by default (optional)
@ -127,7 +127,7 @@ class TestFtsQueryBinding:
def test_search_query_pickle_with_fts(self):
"""_SearchQuery with fts should survive pickling."""
from _zvec.param import _Fts, _SearchQuery
from zvec._zvec.param import _Fts, _SearchQuery
vq = _SearchQuery()
vq.topk = 10
@ -145,7 +145,7 @@ class TestFtsQueryBinding:
def test_search_query_pickle_without_fts(self):
"""_SearchQuery without fts should survive pickling."""
from _zvec.param import _SearchQuery
from zvec._zvec.param import _SearchQuery
vq = _SearchQuery()
vq.topk = 5

View File

@ -40,7 +40,7 @@ from zvec import (
VectorSchema,
)
from _zvec.param import _SearchQuery
from zvec._zvec.param import _SearchQuery
# ----------------------------
# Invert Index Param Test Case

View File

@ -18,7 +18,7 @@ from unittest.mock import MagicMock, patch
import numpy as np
import math
from _zvec.param import _SearchQuery
from zvec._zvec.param import _SearchQuery
import pytest
from zvec.executor.query_executor import (

View File

@ -28,7 +28,7 @@ if TYPE_CHECKING:
try:
from importlib.resources import files as _resource_files
from _zvec import (
from zvec._zvec import (
get_default_jieba_dict_dir,
set_default_jieba_dict_dir,
)
@ -48,7 +48,7 @@ except Exception:
# DiskAnn normally auto-loads on first use; these APIs let tests and
# diagnostic tools preload the plugin and get a clear error if libaio is
# missing or the plugin shared object cannot be located.
from _zvec import (
from zvec._zvec import (
DISKANN_PLUGIN_DLOPEN_FAILED,
DISKANN_PLUGIN_LIBAIO_MISSING,
DISKANN_PLUGIN_OK,

View File

@ -16,8 +16,9 @@ from __future__ import annotations
from typing import Optional, Union
import numpy as np
from _zvec import _Collection, _MultiQuery
from _zvec.param import _Fts, _SearchQuery, _SubQuery
from zvec._zvec import _Collection, _MultiQuery
from zvec._zvec.param import _Fts, _SearchQuery, _SubQuery
from ..extension import CallbackReRanker, ReRanker, RrfReRanker, WeightedReRanker
from ..model.convert import convert_to_py_doc

View File

@ -16,7 +16,13 @@ from __future__ import annotations
from collections.abc import Callable
from typing import TYPE_CHECKING
from _zvec import _CallbackParams, _Doc, _reranker_rerank, _RrfParams, _WeightedParams
from zvec._zvec import (
_CallbackParams,
_Doc,
_reranker_rerank,
_RrfParams,
_WeightedParams,
)
from ..model.doc import Doc, DocList
from .rerank_function import RerankFunction

View File

@ -16,7 +16,7 @@ from __future__ import annotations
import warnings
from typing import Optional, Union, overload
from _zvec import _Collection
from zvec._zvec import _Collection
from ..executor import QueryContext, QueryExecutor
from ..extension import ReRanker

View File

@ -11,7 +11,7 @@
# limitations under the License.
from __future__ import annotations
from _zvec import _Doc
from zvec._zvec import _Doc
from .doc import Doc
from .schema import CollectionSchema

View File

@ -13,7 +13,7 @@
# limitations under the License.
from __future__ import annotations
from _zvec.param import (
from zvec._zvec.param import (
AddColumnOption,
AlterColumnOption,
CollectionOption,

View File

@ -7,7 +7,7 @@ from __future__ import annotations
import collections
import typing
import _zvec.typing
import zvec._zvec.typing
__all__: list[str] = [
"AddColumnOption",
@ -161,8 +161,8 @@ class FlatIndexParam(VectorIndexParam):
def __getstate__(self) -> tuple: ...
def __init__(
self,
metric_type: _zvec.typing.MetricType = ...,
quantize_type: _zvec.typing.QuantizeType = ...,
metric_type: zvec._zvec.typing.MetricType = ...,
quantize_type: zvec._zvec.typing.QuantizeType = ...,
) -> None:
"""
Constructs a FlatIndexParam instance.
@ -221,10 +221,10 @@ class HnswIndexParam(VectorIndexParam):
def __getstate__(self) -> tuple: ...
def __init__(
self,
metric_type: _zvec.typing.MetricType = ...,
metric_type: zvec._zvec.typing.MetricType = ...,
m: typing.SupportsInt = 50,
ef_construction: typing.SupportsInt = 500,
quantize_type: _zvec.typing.QuantizeType = ...,
quantize_type: zvec._zvec.typing.QuantizeType = ...,
use_contiguous_memory: bool = False,
) -> None: ...
def __repr__(self) -> str: ...
@ -365,7 +365,7 @@ class HnswRabitqIndexParam(VectorIndexParam):
def __getstate__(self) -> tuple: ...
def __init__(
self,
metric_type: _zvec.typing.MetricType = ...,
metric_type: zvec._zvec.typing.MetricType = ...,
total_bits: typing.SupportsInt = 7,
num_clusters: typing.SupportsInt = 16,
m: typing.SupportsInt = 50,
@ -493,11 +493,11 @@ class IVFIndexParam(VectorIndexParam):
def __getstate__(self) -> tuple: ...
def __init__(
self,
metric_type: _zvec.typing.MetricType = ...,
metric_type: zvec._zvec.typing.MetricType = ...,
n_list: typing.SupportsInt = 10,
n_iters: typing.SupportsInt = 10,
use_soar: bool = False,
quantize_type: _zvec.typing.QuantizeType = ...,
quantize_type: zvec._zvec.typing.QuantizeType = ...,
) -> None:
"""
Constructs an IVFIndexParam instance.
@ -595,14 +595,14 @@ class VamanaIndexParam(VectorIndexParam):
def __getstate__(self) -> tuple: ...
def __init__(
self,
metric_type: _zvec.typing.MetricType = ...,
metric_type: zvec._zvec.typing.MetricType = ...,
max_degree: typing.SupportsInt = 64,
search_list_size: typing.SupportsInt = 100,
alpha: typing.SupportsFloat = 1.2,
saturate_graph: bool = False,
use_contiguous_memory: bool = False,
use_id_map: bool = False,
quantize_type: _zvec.typing.QuantizeType = ...,
quantize_type: zvec._zvec.typing.QuantizeType = ...,
) -> None: ...
def __repr__(self) -> str: ...
def __setstate__(self, arg0: tuple) -> None: ...
@ -837,7 +837,7 @@ class IndexParam:
"""
@property
def type(self) -> _zvec.typing.IndexType:
def type(self) -> zvec._zvec.typing.IndexType:
"""
IndexType: The type of the index.
"""
@ -966,7 +966,7 @@ class QueryParam:
IndexType: The type of index this query targets.
"""
@property
def type(self) -> _zvec.typing.IndexType:
def type(self) -> zvec._zvec.typing.IndexType:
"""
IndexType: The type of index this query targets.
"""
@ -1036,13 +1036,13 @@ class VectorIndexParam(IndexParam):
"""
@property
def metric_type(self) -> _zvec.typing.MetricType:
def metric_type(self) -> zvec._zvec.typing.MetricType:
"""
MetricType: Distance metric (e.g., IP, COSINE, L2).
"""
@property
def quantize_type(self) -> _zvec.typing.QuantizeType:
def quantize_type(self) -> zvec._zvec.typing.QuantizeType:
"""
QuantizeType: Vector quantization type (e.g., FP16, INT8).
"""

View File

@ -13,7 +13,7 @@
# limitations under the License.
from __future__ import annotations
from _zvec.schema import CollectionStats
from zvec._zvec.schema import CollectionStats
from .collection_schema import CollectionSchema
from .field_schema import FieldSchema, VectorSchema

View File

@ -7,8 +7,8 @@ from __future__ import annotations
import collections.abc
import typing
import _zvec.param
import _zvec.typing
import zvec._zvec.param
import zvec._zvec.typing
from .collection_schema import CollectionSchema
from .field_schema import FieldSchema, VectorSchema
@ -85,20 +85,20 @@ class _FieldSchema:
def __init__(
self,
name: str,
data_type: _zvec.typing.DataType,
data_type: zvec._zvec.typing.DataType,
nullable: bool = False,
dimension: typing.SupportsInt = 0,
index_param: _zvec.param.IndexParam = None,
index_param: zvec._zvec.param.IndexParam = None,
) -> None: ...
def __ne__(self, arg0: _FieldSchema) -> bool: ...
@property
def data_type(self) -> _zvec.typing.DataType: ...
def data_type(self) -> zvec._zvec.typing.DataType: ...
@property
def dimension(self) -> int: ...
@property
def index_param(self) -> typing.Any: ...
@property
def index_type(self) -> _zvec.typing.IndexType: ...
def index_type(self) -> zvec._zvec.typing.IndexType: ...
@property
def is_dense_vector(self) -> bool: ...
@property

View File

@ -16,7 +16,7 @@ from __future__ import annotations
import json
from typing import Optional, Union
from _zvec.schema import _CollectionSchema, _FieldSchema
from zvec._zvec.schema import _CollectionSchema, _FieldSchema
from .field_schema import FieldSchema, VectorSchema

View File

@ -16,8 +16,7 @@ from __future__ import annotations
import json
from typing import Any, Optional, Union
from _zvec.schema import _FieldSchema
from zvec._zvec.schema import _FieldSchema
from zvec.model.param import (
FlatIndexParam,
FtsIndexParam,

View File

@ -13,7 +13,7 @@
# limitations under the License.
from __future__ import annotations
from _zvec.typing import (
from zvec._zvec.typing import (
DataType,
IndexType,
MetricType,

View File

@ -15,7 +15,7 @@ from __future__ import annotations
from typing import Optional
from _zvec import Initialize, _Collection
from zvec._zvec import Initialize, _Collection
from .model import Collection
from .model.param import CollectionOption