From 501276832056d86e096475876c21b029fa6fe120 Mon Sep 17 00:00:00 2001 From: artemkuzmenko2501-del Date: Fri, 13 Mar 2026 18:20:31 +0300 Subject: [PATCH 1/3] Add custom metric functions in Tester and linearization in Preprocessor - Tester now accepts metric_funcs dict mapping metric names to callables, enabling ratio and composite metrics without pre-computing columns - LinearizationTransformer added for ratio metrics (e.g. revenue/orders): linearized_i = numerator_i - ratio * denominator_i, where ratio is estimated on reference data passed to fit() - Preprocessor.linearize() integrates linearization into the existing chain pattern with full serialization/replay support - 8 new tests covering metric_funcs constructor/run/override behaviour and linearize formula, chaining, serialization Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 88 ++++++++++++++++ ambrosia/preprocessing/__init__.py | 3 +- ambrosia/preprocessing/preprocessor.py | 46 ++++++++- ambrosia/preprocessing/transformers.py | 133 ++++++++++++++++++++++++- ambrosia/tester/handlers.py | 19 +++- ambrosia/tester/tester.py | 20 +++- tests/test_preprocessor.py | 69 +++++++++++++ tests/test_tester.py | 58 +++++++++++ 8 files changed, 427 insertions(+), 9 deletions(-) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c322566 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,88 @@ +# Ambrosia + +A/B testing framework for experiment design, group splitting, and results evaluation. +Supports both pandas and Spark DataFrames. + +## Commands + +```bash +make install # create .venv via Poetry (poetry install --all-extras) +make test # run pytest with coverage +make lint # isort + black + pylint + flake8 (checks only) +make autoformat # isort + black (fix in place) +make clean # remove .venv, build artifacts, reports/ +``` + +Single test: `PYTHONPATH=. pytest tests/path/test_file.py::test_fn` + +Line length: **120**. + +## Architecture + +### Three-stage pipeline + +`Designer` → `Splitter` → `Tester` are independent, stateless-ish classes. +No shared state between stages; each takes a DataFrame and parameters. + +### Pandas/Spark dispatch + +Never subclass for pandas vs. Spark. Instead use `DataframeHandler` or the +free function `choose_on_table(alternatives, dataframe)` in +`ambrosia/tools/ab_abstract_component.py`: + +```python +choose_on_table([pandas_func, spark_func], dataframe) +``` + +`DataframeHandler._handle_cases` / `_handle_on_table` wrap this pattern for +method dispatch in handlers (e.g. `TheoryHandler`, `EmpiricHandler`). + +### ABMetaClass + +`ABMetaClass(ABCMeta, YAMLObjectMetaclass)` in `ab_abstract_component.py` +resolves the metaclass conflict between `ABCMeta` and PyYAML's +`YAMLObjectMetaclass`. Any class that inherits from `ABToolAbstract` **and** +needs YAML serialization must set `metaclass=ABMetaClass`. + +### ABToolAbstract._prepare_arguments() + +Constructor args are "saved" defaults; `run()` args can override them at +call time. `_prepare_arguments` resolves the priority: +run-time arg → constructor arg → `ValueError` if both are None. + +```python +chosen = _prepare_arguments({"alpha": [self._alpha, given_alpha]}) +``` + +### Stat criteria strategy pattern + +Hierarchy: `StatCriterion` (abstract, just `calculate_pvalue`) → +`ABStatCriterion` (adds `calculate_effect`, `calculate_conf_interval`, +`get_results`). + +Concrete implementations in `ambrosia/tools/stat_criteria.py`: +`TtestIndCriterion`, `TtestRelCriterion`, `MannWhitneyCriterion`, +`WilcoxonCriterion`. + +`Tester` dispatches by string alias via `AVAILABLE_AB_CRITERIA` dict — duck +typing, not isinstance checks. To add a criterion: subclass `ABStatCriterion`, +set `alias` and `implemented_effect_types` class attributes, register in the +dict. + +### Preprocessor chain + +`Preprocessor` (pandas only) uses method chaining — each method returns +`self`. Each step appends a fitted `AbstractFittableTransformer` to +`self.transformers`. The transformer list supports serialization +(`store_transformations` / `load_transformations` → JSON) and replay +(`apply_transformations`) for consistent train/test preprocessing. + +### Theoretical vs empirical design + +Two design philosophies plug into the same `SimpleDesigner` interface: + +- **Theoretical** (`TheoryHandler`): closed-form power/sample-size formulas +- **Empirical** (`EmpiricHandler`): bootstrap/simulation-based estimates + +Both implement `size_design`, `effect_design`, `power_design` and dispatch +pandas vs. Spark internally via `DataframeHandler`. diff --git a/ambrosia/preprocessing/__init__.py b/ambrosia/preprocessing/__init__.py index 82561ab..e6d33e8 100644 --- a/ambrosia/preprocessing/__init__.py +++ b/ambrosia/preprocessing/__init__.py @@ -21,7 +21,7 @@ from .ml_var_reducer import MLVarianceReducer from .preprocessor import Preprocessor from .robust import IQRPreprocessor, RobustPreprocessor -from .transformers import BoxCoxTransformer, LogTransformer +from .transformers import BoxCoxTransformer, LinearizationTransformer, LogTransformer __all__ = [ "AggregatePreprocessor", @@ -32,5 +32,6 @@ "RobustPreprocessor", "IQRPreprocessor", "BoxCoxTransformer", + "LinearizationTransformer", "LogTransformer", ] diff --git a/ambrosia/preprocessing/preprocessor.py b/ambrosia/preprocessing/preprocessor.py index c865008..6d7b205 100644 --- a/ambrosia/preprocessing/preprocessor.py +++ b/ambrosia/preprocessing/preprocessor.py @@ -34,7 +34,7 @@ from ambrosia.preprocessing.aggregate import AggregatePreprocessor from ambrosia.preprocessing.cuped import Cuped, MultiCuped from ambrosia.preprocessing.robust import IQRPreprocessor, RobustPreprocessor -from ambrosia.preprocessing.transformers import BoxCoxTransformer, LogTransformer +from ambrosia.preprocessing.transformers import BoxCoxTransformer, LinearizationTransformer, LogTransformer class Preprocessor: @@ -378,6 +378,50 @@ def multicuped( self.transformers.append(transformer) return self + def linearize( + self, + numerator: types.ColumnNameType, + denominator: types.ColumnNameType, + transformed_name: Optional[types.ColumnNameType] = None, + load_path: Optional[Path] = None, + ) -> Preprocessor: + """ + Linearize a ratio metric for use in A/B testing. + + Computes a per-unit linearized value that is approximately normally + distributed, enabling correct t-test usage for ratio metrics: + + linearized_i = numerator_i - ratio * denominator_i + + where ratio = mean(numerator) / mean(denominator) is estimated on + the data passed to this ``Preprocessor`` instance (reference / control data). + + Parameters + ---------- + numerator : ColumnNameType + Column name of the ratio numerator (e.g. ``"revenue"``). + denominator : ColumnNameType + Column name of the ratio denominator (e.g. ``"orders"``). + transformed_name : ColumnNameType, optional + Name for the new linearized column. Defaults to + ``"{numerator}_lin"``. + load_path : Path, optional + Path to a json file with pre-fitted parameters. + + Returns + ------- + self : Preprocessor + Instance object. + """ + transformer = LinearizationTransformer() + if load_path is None: + transformer.fit_transform(self.dataframe, numerator, denominator, transformed_name, inplace=True) + else: + transformer.load_params(load_path) + transformer.transform(self.dataframe, inplace=True) + self.transformers.append(transformer) + return self + def transformations(self) -> List: """ List of all transformations which were called. diff --git a/ambrosia/preprocessing/transformers.py b/ambrosia/preprocessing/transformers.py index 6397641..1649e86 100644 --- a/ambrosia/preprocessing/transformers.py +++ b/ambrosia/preprocessing/transformers.py @@ -16,7 +16,7 @@ Module contains tools for metrics transformations during a preprocessing task. """ -from typing import Dict, Union +from typing import Dict, Optional, Union import numpy as np import pandas as pd @@ -386,3 +386,134 @@ def inverse_transform(self, dataframe: pd.DataFrame, inplace: bool = False) -> U transformed: pd.DataFrame = dataframe if inplace else dataframe.copy() transformed[self.column_names] = np.exp(transformed[self.column_names].values) return None if inplace else transformed + + +class LinearizationTransformer(AbstractFittableTransformer): + """ + Linearization transformer for ratio metrics. + + Converts a ratio metric (numerator / denominator) into a per-unit linearized + metric that is approximately normally distributed, enabling correct t-test usage: + + linearized_i = numerator_i - ratio * denominator_i + + where ratio = mean(numerator) / mean(denominator), estimated on the reference + (control group / historical) data passed to fit(). + + Parameters + ---------- + numerator : str + Column name of the ratio numerator (e.g. "revenue"). + denominator : str + Column name of the ratio denominator (e.g. "orders"). + transformed_name : str, optional + Name for the new column. Defaults to ``"{numerator}_lin"``. + + Examples + -------- + >>> transformer = LinearizationTransformer() + >>> transformer.fit(control_df, "revenue", "orders", "arpu_lin") + >>> transformer.transform(experiment_df, inplace=True) + """ + + def __str__(self) -> str: + return "Linearization transformation" + + def __init__(self) -> None: + self.numerator: Optional[str] = None + self.denominator: Optional[str] = None + self.transformed_name: Optional[str] = None + self.ratio: Optional[float] = None + super().__init__() + + def get_params_dict(self) -> Dict: + self._check_fitted() + return { + "numerator": self.numerator, + "denominator": self.denominator, + "transformed_name": self.transformed_name, + "ratio": self.ratio, + } + + def load_params_dict(self, params: Dict) -> None: + for key in ("numerator", "denominator", "transformed_name", "ratio"): + if key not in params: + raise TypeError(f"params argument must contain: {key}") + setattr(self, key, params[key]) + self.fitted = True + + def fit( + self, + dataframe: pd.DataFrame, + numerator: str, + denominator: str, + transformed_name: Optional[str] = None, + ): + """ + Estimate ratio = mean(numerator) / mean(denominator) on reference data. + + Parameters + ---------- + dataframe : pd.DataFrame + Reference dataframe (typically control group or historical data). + numerator : str + Column name of the ratio numerator. + denominator : str + Column name of the ratio denominator. + transformed_name : str, optional + Name for the linearized column. Defaults to ``"{numerator}_lin"``. + """ + self._check_cols(dataframe, [numerator, denominator]) + denom_mean = dataframe[denominator].mean() + if denom_mean == 0: + raise ValueError(f"Mean of denominator column '{denominator}' is zero; cannot compute ratio.") + self.numerator = numerator + self.denominator = denominator + self.transformed_name = transformed_name if transformed_name is not None else f"{numerator}_lin" + self.ratio = dataframe[numerator].mean() / denom_mean + self.fitted = True + return self + + def transform(self, dataframe: pd.DataFrame, inplace: bool = False) -> Union[pd.DataFrame, None]: + """ + Apply linearization: transformed = numerator - ratio * denominator. + + Parameters + ---------- + dataframe : pd.DataFrame + Dataframe to transform. + inplace : bool, default: ``False`` + If ``True`` modifies dataframe in place, otherwise returns a copy. + """ + self._check_fitted() + self._check_cols(dataframe, [self.numerator, self.denominator]) + df = dataframe if inplace else dataframe.copy() + df[self.transformed_name] = df[self.numerator] - self.ratio * df[self.denominator] + return None if inplace else df + + def fit_transform( + self, + dataframe: pd.DataFrame, + numerator: str, + denominator: str, + transformed_name: Optional[str] = None, + inplace: bool = False, + ) -> Union[pd.DataFrame, None]: + """ + Fit and transform in one step. + + Parameters + ---------- + dataframe : pd.DataFrame + Reference dataframe for fitting and transformation. + numerator : str + Column name of the ratio numerator. + denominator : str + Column name of the ratio denominator. + transformed_name : str, optional + Name for the linearized column. + inplace : bool, default: ``False`` + If ``True`` modifies dataframe in place. + """ + self.fit(dataframe, numerator, denominator, transformed_name) + return self.transform(dataframe, inplace) diff --git a/ambrosia/tester/handlers.py b/ambrosia/tester/handlers.py index 7d65c35..5c97779 100644 --- a/ambrosia/tester/handlers.py +++ b/ambrosia/tester/handlers.py @@ -51,7 +51,15 @@ class SparkCriteria(enum.Enum): class TheoreticalTesterHandler: def __init__( - self, group_a, group_b, column: str, alpha: np.ndarray, effect_type: str, criterion: StatCriterion, **kwargs + self, + group_a, + group_b, + column: str, + alpha: np.ndarray, + effect_type: str, + criterion: StatCriterion, + metric_func=None, + **kwargs, ): self.group_a = group_a self.group_b = group_b @@ -59,6 +67,7 @@ def __init__( self.alpha = alpha self.effect_type = effect_type self.criterion = criterion + self.metric_func = metric_func self.kwargs = kwargs def _correct_criterion(self, criterion: tp.Any) -> bool: @@ -79,8 +88,12 @@ def get_criterion(self, criterion: str, data_example: types.SparkOrPandas): def _set_kwargs(self): if isinstance(self.group_a, pd.DataFrame): - self.group_a = self.group_a[self.column].values - self.group_b = self.group_b[self.column].values + if self.metric_func is not None: + self.group_a = np.asarray(self.metric_func(self.group_a)) + self.group_b = np.asarray(self.metric_func(self.group_b)) + else: + self.group_a = self.group_a[self.column].values + self.group_b = self.group_b[self.column].values elif isinstance(self.group_a, types.SparkDataFrame): self.kwargs["column"] = self.column self.kwargs["alpha"] = self.alpha diff --git a/ambrosia/tester/tester.py b/ambrosia/tester/tester.py index 386d6a5..304cdbe 100644 --- a/ambrosia/tester/tester.py +++ b/ambrosia/tester/tester.py @@ -29,7 +29,7 @@ """ import itertools from copy import deepcopy -from typing import Dict, List, Optional, Union +from typing import Callable, Dict, List, Optional, Union from warnings import warn import numpy as np @@ -241,6 +241,7 @@ def __init__( id_column: Optional[types.ColumnNameType] = None, first_type_errors: types.StatErrorType = 0.05, metrics: Optional[types.MetricNamesType] = None, + metric_funcs: Optional[Dict[str, Callable]] = None, ): """ Tester class constructor to initialize the object. @@ -257,6 +258,7 @@ def __init__( self.set_experiment_results(experiment_results=experiment_results) self.set_errors(first_type_errors) self.set_metrics(metrics) + self.__metric_funcs = metric_funcs or {} @staticmethod def __filter_data( @@ -372,9 +374,15 @@ def __pre_run(method: str, args: types._UsageArgumentsType, **kwargs) -> types.T if method not in accepted_methods: raise ValueError(f'Choose method from {", ".join(accepted_methods)}') result: types.TesterResult = {} + metric_funcs: Dict = args.get("metric_funcs", {}) for metric in args["metrics"]: - a_values: np.ndarray = args["data_a_group"][metric].values - b_values: np.ndarray = args["data_b_group"][metric].values + metric_func = metric_funcs.get(metric) + if metric_func is not None: + a_values: np.ndarray = np.asarray(metric_func(args["data_a_group"])) + b_values: np.ndarray = np.asarray(metric_func(args["data_b_group"])) + else: + a_values = args["data_a_group"][metric].values + b_values = args["data_b_group"][metric].values if method == "theory": # TODO: Make it SolverClass ~ method # solver = SolverClass(...) @@ -386,6 +394,7 @@ def __pre_run(method: str, args: types._UsageArgumentsType, **kwargs) -> types.T alpha=np.array(args["alpha"]), effect_type=args["effect_type"], criterion=args["criterion"], + metric_func=metric_func, **kwargs, ) sub_result = solver.solve() @@ -473,6 +482,7 @@ def run( criterion: Optional[ABStatCriterion] = None, correction_method: Union[str, None] = "bonferroni", as_table: bool = True, + metric_funcs: Optional[Dict[str, Callable]] = None, **kwargs, ) -> types.TesterResult: """ @@ -556,6 +566,8 @@ def run( chosen_args: types._UsageArgumentsType = Tester._prepare_arguments(arguments_choice) chosen_args["effect_type"] = effect_type chosen_args["criterion"] = criterion + effective_metric_funcs = {**self.__metric_funcs, **(metric_funcs or {})} + chosen_args["metric_funcs"] = effective_metric_funcs hypothesis_num: int = len(list(itertools.combinations(chosen_args["experiment_results"], 2))) * len( chosen_args["metrics"] @@ -602,6 +614,7 @@ def test( criterion: Optional[ABStatCriterion] = None, correction_method: Union[str, None] = "bonferroni", as_table: bool = True, + metric_funcs: Optional[Dict[str, Callable]] = None, **kwargs, ) -> types.TesterResult: """ @@ -673,5 +686,6 @@ def test( criterion=criterion, correction_method=correction_method, as_table=as_table, + metric_funcs=metric_funcs, **kwargs, ) diff --git a/tests/test_preprocessor.py b/tests/test_preprocessor.py index 9106336..e2954b9 100644 --- a/tests/test_preprocessor.py +++ b/tests/test_preprocessor.py @@ -1,5 +1,6 @@ import os +import numpy as np import pandas as pd import pytest @@ -117,3 +118,71 @@ def test_store_load_config(data_for_agg): transformed_by_config: pd.DataFrame = loaded_preprocessor.apply_transformations() os.remove(store_path) assert (transformed == transformed_by_config).all(None) + + +@pytest.mark.smoke() +def test_linearize_basic(data_nonlin_var): + """ + Test that linearize creates new column and returns self. + """ + preprocessor = Preprocessor(data_nonlin_var, verbose=False) + result = preprocessor.linearize("target", "feature_1", transformed_name="target_lin") + assert result is preprocessor # method chaining + assert "target_lin" in preprocessor.data().columns + + +@pytest.mark.unit() +def test_linearize_formula(data_nonlin_var): + """ + Test that linearized values satisfy: linearized = num - ratio * denom. + """ + preprocessor = Preprocessor(data_nonlin_var, verbose=False) + preprocessor.linearize("target", "feature_1", transformed_name="target_lin") + df = preprocessor.data() + transformer = preprocessor.transformations()[-1] + ratio = transformer.ratio + expected = data_nonlin_var["target"] - ratio * data_nonlin_var["feature_1"] + np.testing.assert_allclose(df["target_lin"].values, expected.values, rtol=1e-10) + + +@pytest.mark.unit() +def test_linearize_in_chain(data_nonlin_var): + """ + Test linearize as part of a preprocessing chain. + """ + preprocessor = Preprocessor(data_nonlin_var, verbose=False) + result = ( + preprocessor.robust("feature_1", alpha=0.01) + .linearize("target", "feature_1", transformed_name="target_lin") + .data() + ) + assert "target_lin" in result.columns + + +@pytest.mark.unit() +def test_linearize_load_store(data_nonlin_var): + """ + Test that linearization transformer can be serialized and replayed. + """ + store_path = "tests/configs/linearize_config.json" + preprocessor = Preprocessor(data_nonlin_var, verbose=False) + preprocessor.linearize("target", "feature_1", transformed_name="target_lin") + preprocessor.store_transformations(store_path) + + loaded_preprocessor = Preprocessor(data_nonlin_var, verbose=False) + loaded_preprocessor.load_transformations(store_path) + + os.remove(store_path) + + for t, lt in zip(preprocessor.transformations(), loaded_preprocessor.transformations()): + assert t.get_params_dict() == lt.get_params_dict() + + +@pytest.mark.unit() +def test_linearize_default_name(data_nonlin_var): + """ + Test that default transformed_name is '{numerator}_lin'. + """ + preprocessor = Preprocessor(data_nonlin_var, verbose=False) + preprocessor.linearize("target", "feature_1") + assert "target_lin" in preprocessor.data().columns diff --git a/tests/test_tester.py b/tests/test_tester.py index c4ba892..a1597e8 100644 --- a/tests/test_tester.py +++ b/tests/test_tester.py @@ -384,3 +384,61 @@ def test_paired_bootstrap(effect_type, alternative): ) assert test_results_dep[0]["pvalue"] < test_results_ind[0]["pvalue"] assert test_results_dep[0]["confidence_interval"][0] > test_results_ind[0]["confidence_interval"][0] + + +@pytest.mark.unit +def test_metric_func_constructor(results_ltv_retention_conversions): + """ + Test that metric_funcs passed to constructor are used when metric name matches. + """ + # ratio metric: ltv / retention (arbitrary, just to test callable path) + ratio_func = lambda df: (df["ltv"] / (df["retention"] + 1e-6)).values + tester = Tester( + dataframe=results_ltv_retention_conversions, + column_groups="group", + metrics=["ratio_metric"], + metric_funcs={"ratio_metric": ratio_func}, + ) + result = tester.run(as_table=False) + assert len(result) == 1 + assert "pvalue" in result[0] + + +@pytest.mark.unit +@pytest.mark.parametrize("method", ["theory", "empiric"]) +def test_metric_func_run(method, results_ltv_retention_conversions): + """ + Test that metric_funcs passed to run() work for theory and empiric methods. + """ + double_ltv = lambda df: (df["ltv"] * 2).values + tester = Tester( + dataframe=results_ltv_retention_conversions, + column_groups="group", + metrics=["ltv"], + ) + result_normal = tester.run(method=method, metrics=["ltv"], as_table=False) + result_func = tester.run( + method=method, + metrics=["custom"], + metric_funcs={"custom": double_ltv}, + as_table=False, + ) + # Doubling values doesn't change pvalue for ttest (same scale), but effect should be doubled + assert abs(result_func[0]["effect"]) == pytest.approx(abs(result_normal[0]["effect"]) * 2, rel=1e-4) + + +@pytest.mark.unit +def test_metric_func_overrides_constructor(results_ltv_retention_conversions): + """ + Test that metric_funcs in run() override those set in constructor. + """ + func_a = lambda df: df["ltv"].values + func_b = lambda df: (df["ltv"] * 3).values + tester = Tester( + dataframe=results_ltv_retention_conversions, + column_groups="group", + metric_funcs={"my_metric": func_a}, + ) + result_a = tester.run(metrics=["my_metric"], as_table=False) + result_b = tester.run(metrics=["my_metric"], metric_funcs={"my_metric": func_b}, as_table=False) + assert abs(result_b[0]["effect"]) == pytest.approx(abs(result_a[0]["effect"]) * 3, rel=1e-4) From c83f93d0d74f5e70203696b62f1fec40aa4b4392 Mon Sep 17 00:00:00 2001 From: artemkuzmenko2501-del Date: Fri, 13 Mar 2026 19:17:07 +0300 Subject: [PATCH 2/3] Fix CI: remove EOL Python 3.7, make nmslib optional - Remove Python 3.7 from CI matrix (GitHub Actions dropped it, EOL) - Replace Python 3.10 with 3.11/3.12 (nmslib has unfixable C++ build failures on modern gcc; 3.11+ already passes in scheduled runs) - Make nmslib an optional dependency so missing it doesn't break install - Lazy-import nmslib in knn.py with a clear ImportError message Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/test.yaml | 2 +- ambrosia/tools/knn.py | 11 ++++++++++- pyproject.toml | 3 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 54c2785..0fb1eac 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -36,7 +36,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.11", "3.12"] steps: - uses: actions/checkout@v2 diff --git a/ambrosia/tools/knn.py b/ambrosia/tools/knn.py index 3a90129..c6a8131 100644 --- a/ambrosia/tools/knn.py +++ b/ambrosia/tools/knn.py @@ -14,9 +14,13 @@ from typing import Any, List -import nmslib import numpy as np +try: + import nmslib +except ImportError as _nmslib_import_error: + nmslib = None # type: ignore[assignment] + class NMTree: """ @@ -24,6 +28,11 @@ class NMTree: """ def __init__(self, points: np.ndarray, payload: np.ndarray, ef_search: int): + if nmslib is None: + raise ImportError( + "nmslib is required for KNN-based group matching. " + "Install it with: pip install nmslib" + ) self.__was = set() self.__index = nmslib.init(space="l2") self.__index.addDataPointBatch(points) diff --git a/pyproject.toml b/pyproject.toml index 2512ef5..323e7a6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -42,7 +42,7 @@ packages = [ python = ">=3.7.2, <3.11.0" jinja2 = "^3.0.0" joblib = "^1.1.0" -nmslib = "^2.0.4" +nmslib = { version = "^2.0.4", optional = true } numpy = ">=1.19.5, <2.0.0" pandas = ">=0.25.3, <2.0.0" pyspark = { version = "^3.2", optional = true } @@ -67,6 +67,7 @@ pytest-lazy-fixture = "0.6.3" [tool.poetry.extras] spark = ["pyspark"] +knn = ["nmslib"] [tool.black] line-length = 120 From 7dbac31face6aedb165182e29914bde7a4109f77 Mon Sep 17 00:00:00 2001 From: artemkuzmenko2501-del Date: Fri, 13 Mar 2026 19:34:51 +0300 Subject: [PATCH 3/3] Fix poetry.lock and python version constraint - Extend python constraint to >=3.8, <3.13 to support 3.11/3.12 in CI - Restrict nmslib optional dep to python <3.11 (build fails on newer gcc) - Regenerate poetry.lock to fix 'Extra [knn] is not specified' error Co-Authored-By: Claude Sonnet 4.6 --- poetry.lock | 277 +++++++++++++++---------------------------------- pyproject.toml | 4 +- 2 files changed, 86 insertions(+), 195 deletions(-) diff --git a/poetry.lock b/poetry.lock index a40864f..3760b59 100644 --- a/poetry.lock +++ b/poetry.lock @@ -15,7 +15,6 @@ files = [ [package.dependencies] lazy-object-proxy = ">=1.4.0" setuptools = ">=20.0" -typed-ast = {version = ">=1.4.0,<2.0", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} wrapt = ">=1.11,<2" @@ -42,9 +41,6 @@ files = [ {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, ] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] dev = ["attrs[docs,tests]", "pre-commit"] @@ -107,7 +103,6 @@ mypy-extensions = ">=0.4.3" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} -typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] @@ -164,7 +159,6 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "cloudpickle" @@ -297,7 +291,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = "<4.3", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.8.0,<2.9.0" pyflakes = ">=2.4.0,<2.5.0" @@ -400,26 +393,6 @@ dev = ["black", "nose", "pre-commit", "pytest"] mongotrials = ["pymongo"] sparktrials = ["pyspark"] -[[package]] -name = "importlib-metadata" -version = "4.2.0" -description = "Read metadata from Python packages" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"}, - {file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"}, -] - -[package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} -zipp = ">=0.5" - -[package.extras] -docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] - [[package]] name = "iniconfig" version = "2.0.0" @@ -558,9 +531,6 @@ files = [ {file = "kiwisolver-1.4.4.tar.gz", hash = "sha256:d41997519fcba4a1e46eb4a2fe31bc12f0ff957b2b81bac28db24744f333e955"}, ] -[package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - [[package]] name = "lazy-object-proxy" version = "1.9.0" @@ -721,7 +691,6 @@ packaging = ">=20.0" pillow = ">=6.2.0" pyparsing = ">=2.2.1" python-dateutil = ">=2.7" -setuptools_scm = ">=4,<7" [[package]] name = "mccabe" @@ -771,7 +740,7 @@ name = "nmslib" version = "2.1.1" description = "Non-Metric Space Library (NMSLIB)" category = "main" -optional = false +optional = true python-versions = "*" files = [ {file = "nmslib-2.1.1-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:495ace1146bb1e89ef585a490fa65de19a87fa0d5bb029f3156402a431fc3558"}, @@ -818,43 +787,40 @@ pybind11 = "<2.6.2" [[package]] name = "numpy" -version = "1.21.6" -description = "NumPy is the fundamental package for array computing with Python." +version = "1.24.4" +description = "Fundamental package for array computing in Python" category = "main" optional = false -python-versions = ">=3.7,<3.11" -files = [ - {file = "numpy-1.21.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8737609c3bbdd48e380d463134a35ffad3b22dc56295eff6f79fd85bd0eeeb25"}, - {file = "numpy-1.21.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fdffbfb6832cd0b300995a2b08b8f6fa9f6e856d562800fea9182316d99c4e8e"}, - {file = "numpy-1.21.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3820724272f9913b597ccd13a467cc492a0da6b05df26ea09e78b171a0bb9da6"}, - {file = "numpy-1.21.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f17e562de9edf691a42ddb1eb4a5541c20dd3f9e65b09ded2beb0799c0cf29bb"}, - {file = "numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f30427731561ce75d7048ac254dbe47a2ba576229250fb60f0fb74db96501a1"}, - {file = "numpy-1.21.6-cp310-cp310-win32.whl", hash = "sha256:d4bf4d43077db55589ffc9009c0ba0a94fa4908b9586d6ccce2e0b164c86303c"}, - {file = "numpy-1.21.6-cp310-cp310-win_amd64.whl", hash = "sha256:d136337ae3cc69aa5e447e78d8e1514be8c3ec9b54264e680cf0b4bd9011574f"}, - {file = "numpy-1.21.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6aaf96c7f8cebc220cdfc03f1d5a31952f027dda050e5a703a0d1c396075e3e7"}, - {file = "numpy-1.21.6-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:67c261d6c0a9981820c3a149d255a76918278a6b03b6a036800359aba1256d46"}, - {file = "numpy-1.21.6-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a6be4cb0ef3b8c9250c19cc122267263093eee7edd4e3fa75395dfda8c17a8e2"}, - {file = "numpy-1.21.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c4068a8c44014b2d55f3c3f574c376b2494ca9cc73d2f1bd692382b6dffe3db"}, - {file = "numpy-1.21.6-cp37-cp37m-win32.whl", hash = "sha256:7c7e5fa88d9ff656e067876e4736379cc962d185d5cd808014a8a928d529ef4e"}, - {file = "numpy-1.21.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bcb238c9c96c00d3085b264e5c1a1207672577b93fa666c3b14a45240b14123a"}, - {file = "numpy-1.21.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:82691fda7c3f77c90e62da69ae60b5ac08e87e775b09813559f8901a88266552"}, - {file = "numpy-1.21.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:643843bcc1c50526b3a71cd2ee561cf0d8773f062c8cbaf9ffac9fdf573f83ab"}, - {file = "numpy-1.21.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:357768c2e4451ac241465157a3e929b265dfac85d9214074985b1786244f2ef3"}, - {file = "numpy-1.21.6-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9f411b2c3f3d76bba0865b35a425157c5dcf54937f82bbeb3d3c180789dd66a6"}, - {file = "numpy-1.21.6-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4aa48afdce4660b0076a00d80afa54e8a97cd49f457d68a4342d188a09451c1a"}, - {file = "numpy-1.21.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a96eef20f639e6a97d23e57dd0c1b1069a7b4fd7027482a4c5c451cd7732f4"}, - {file = "numpy-1.21.6-cp38-cp38-win32.whl", hash = "sha256:5c3c8def4230e1b959671eb959083661b4a0d2e9af93ee339c7dada6759a9470"}, - {file = "numpy-1.21.6-cp38-cp38-win_amd64.whl", hash = "sha256:bf2ec4b75d0e9356edea834d1de42b31fe11f726a81dfb2c2112bc1eaa508fcf"}, - {file = "numpy-1.21.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4391bd07606be175aafd267ef9bea87cf1b8210c787666ce82073b05f202add1"}, - {file = "numpy-1.21.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:67f21981ba2f9d7ba9ade60c9e8cbaa8cf8e9ae51673934480e45cf55e953673"}, - {file = "numpy-1.21.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee5ec40fdd06d62fe5d4084bef4fd50fd4bb6bfd2bf519365f569dc470163ab0"}, - {file = "numpy-1.21.6-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1dbe1c91269f880e364526649a52eff93ac30035507ae980d2fed33aaee633ac"}, - {file = "numpy-1.21.6-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d9caa9d5e682102453d96a0ee10c7241b72859b01a941a397fd965f23b3e016b"}, - {file = "numpy-1.21.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58459d3bad03343ac4b1b42ed14d571b8743dc80ccbf27444f266729df1d6f5b"}, - {file = "numpy-1.21.6-cp39-cp39-win32.whl", hash = "sha256:7f5ae4f304257569ef3b948810816bc87c9146e8c446053539947eedeaa32786"}, - {file = "numpy-1.21.6-cp39-cp39-win_amd64.whl", hash = "sha256:e31f0bb5928b793169b87e3d1e070f2342b22d5245c755e2b81caa29756246c3"}, - {file = "numpy-1.21.6-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd1c8f6bd65d07d3810b90d02eba7997e32abbdf1277a481d698969e921a3be0"}, - {file = "numpy-1.21.6.zip", hash = "sha256:ecb55251139706669fdec2ff073c98ef8e9a84473e51e716211b41aa0f18e656"}, +python-versions = ">=3.8" +files = [ + {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, + {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, + {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, + {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, + {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, + {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, + {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, + {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, + {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, + {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, ] [[package]] @@ -1040,9 +1006,6 @@ files = [ {file = "platformdirs-3.2.0.tar.gz", hash = "sha256:d5b638ca397f25f979350ff789db335903d7ea010ab28903f57b27e1b16c2b08"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""} - [package.extras] docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] @@ -1075,9 +1038,6 @@ files = [ {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] @@ -1087,7 +1047,7 @@ name = "psutil" version = "5.9.4" description = "Cross-platform lib for process and system monitoring in Python." category = "main" -optional = false +optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "psutil-5.9.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8"}, @@ -1138,7 +1098,7 @@ name = "pybind11" version = "2.6.1" description = "Seamless operability between C++11 and Python" category = "main" -optional = false +optional = true python-versions = "!=3.0,!=3.1,!=3.2,!=3.3,!=3.4,>=2.7" files = [ {file = "pybind11-2.6.1-py2.py3-none-any.whl", hash = "sha256:c3691da74b670a4850dec30c1145a0dad53a50eeca78b7e7cdc855b5c98fd32d"}, @@ -1173,7 +1133,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = ">=2.0.0,<5.0.0", markers = "python_version < \"3.8\""} snowballstemmer = ">=2.2.0" [package.extras] @@ -1270,7 +1229,6 @@ files = [ atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" @@ -1356,6 +1314,13 @@ files = [ {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, @@ -1440,51 +1405,48 @@ tests = ["black (>=21.6b0)", "flake8 (>=3.8.2)", "matplotlib (>=2.2.3)", "mypy ( [[package]] name = "scipy" -version = "1.7.3" -description = "SciPy: Scientific Library for Python" +version = "1.9.3" +description = "Fundamental algorithms for scientific computing in Python" category = "main" optional = false -python-versions = ">=3.7,<3.11" -files = [ - {file = "scipy-1.7.3-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17"}, - {file = "scipy-1.7.3-1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:b0e0aeb061a1d7dcd2ed59ea57ee56c9b23dd60100825f98238c06ee5cc4467e"}, - {file = "scipy-1.7.3-1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:b78a35c5c74d336f42f44106174b9851c783184a85a3fe3e68857259b37b9ffb"}, - {file = "scipy-1.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:173308efba2270dcd61cd45a30dfded6ec0085b4b6eb33b5eb11ab443005e088"}, - {file = "scipy-1.7.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:21b66200cf44b1c3e86495e3a436fc7a26608f92b8d43d344457c54f1c024cbc"}, - {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceebc3c4f6a109777c0053dfa0282fddb8893eddfb0d598574acfb734a926168"}, - {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7eaea089345a35130bc9a39b89ec1ff69c208efa97b3f8b25ea5d4c41d88094"}, - {file = "scipy-1.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:304dfaa7146cffdb75fbf6bb7c190fd7688795389ad060b970269c8576d038e9"}, - {file = "scipy-1.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:033ce76ed4e9f62923e1f8124f7e2b0800db533828c853b402c7eec6e9465d80"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4d242d13206ca4302d83d8a6388c9dfce49fc48fdd3c20efad89ba12f785bf9e"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8499d9dd1459dc0d0fe68db0832c3d5fc1361ae8e13d05e6849b358dc3f2c279"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca36e7d9430f7481fc7d11e015ae16fbd5575615a8e9060538104778be84addf"}, - {file = "scipy-1.7.3-cp37-cp37m-win32.whl", hash = "sha256:e2c036492e673aad1b7b0d0ccdc0cb30a968353d2c4bf92ac8e73509e1bf212c"}, - {file = "scipy-1.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:866ada14a95b083dd727a845a764cf95dd13ba3dc69a16b99038001b05439709"}, - {file = "scipy-1.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:65bd52bf55f9a1071398557394203d881384d27b9c2cad7df9a027170aeaef93"}, - {file = "scipy-1.7.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:f99d206db1f1ae735a8192ab93bd6028f3a42f6fa08467d37a14eb96c9dd34a3"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5f2cfc359379c56b3a41b17ebd024109b2049f878badc1e454f31418c3a18436"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb7ae2c4dbdb3c9247e07acc532f91077ae6dbc40ad5bd5dca0bb5a176ee9bda"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c2d250074cfa76715d58830579c64dff7354484b284c2b8b87e5a38321672c"}, - {file = "scipy-1.7.3-cp38-cp38-win32.whl", hash = "sha256:87069cf875f0262a6e3187ab0f419f5b4280d3dcf4811ef9613c605f6e4dca95"}, - {file = "scipy-1.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:7edd9a311299a61e9919ea4192dd477395b50c014cdc1a1ac572d7c27e2207fa"}, - {file = "scipy-1.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eef93a446114ac0193a7b714ce67659db80caf940f3232bad63f4c7a81bc18df"}, - {file = "scipy-1.7.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:eb326658f9b73c07081300daba90a8746543b5ea177184daed26528273157294"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:93378f3d14fff07572392ce6a6a2ceb3a1f237733bd6dcb9eb6a2b29b0d19085"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edad1cf5b2ce1912c4d8ddad20e11d333165552aba262c882e28c78bbc09dbf6"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d1cc2c19afe3b5a546ede7e6a44ce1ff52e443d12b231823268019f608b9b12"}, - {file = "scipy-1.7.3-cp39-cp39-win32.whl", hash = "sha256:2c56b820d304dffcadbbb6cbfbc2e2c79ee46ea291db17e288e73cd3c64fefa9"}, - {file = "scipy-1.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f78181a153fa21c018d346f595edd648344751d7f03ab94b398be2ad083ed3e"}, - {file = "scipy-1.7.3.tar.gz", hash = "sha256:ab5875facfdef77e0a47d5fd39ea178b58e60e454a4c85aa1e52fcb80db7babf"}, +python-versions = ">=3.8" +files = [ + {file = "scipy-1.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1884b66a54887e21addf9c16fb588720a8309a57b2e258ae1c7986d4444d3bc0"}, + {file = "scipy-1.9.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:83b89e9586c62e787f5012e8475fbb12185bafb996a03257e9675cd73d3736dd"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a72d885fa44247f92743fc20732ae55564ff2a519e8302fb7e18717c5355a8b"}, + {file = "scipy-1.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d01e1dd7b15bd2449c8bfc6b7cc67d630700ed655654f0dfcf121600bad205c9"}, + {file = "scipy-1.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:68239b6aa6f9c593da8be1509a05cb7f9efe98b80f43a5861cd24c7557e98523"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b41bc822679ad1c9a5f023bc93f6d0543129ca0f37c1ce294dd9d386f0a21096"}, + {file = "scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:90453d2b93ea82a9f434e4e1cba043e779ff67b92f7a0e85d05d286a3625df3c"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c06e62a390a9167da60bedd4575a14c1f58ca9dfde59830fc42e5197283dab"}, + {file = "scipy-1.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abaf921531b5aeaafced90157db505e10345e45038c39e5d9b6c7922d68085cb"}, + {file = "scipy-1.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:06d2e1b4c491dc7d8eacea139a1b0b295f74e1a1a0f704c375028f8320d16e31"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5a04cd7d0d3eff6ea4719371cbc44df31411862b9646db617c99718ff68d4840"}, + {file = "scipy-1.9.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:545c83ffb518094d8c9d83cce216c0c32f8c04aaf28b92cc8283eda0685162d5"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d54222d7a3ba6022fdf5773931b5d7c56efe41ede7f7128c7b1637700409108"}, + {file = "scipy-1.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cff3a5295234037e39500d35316a4c5794739433528310e117b8a9a0c76d20fc"}, + {file = "scipy-1.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:2318bef588acc7a574f5bfdff9c172d0b1bf2c8143d9582e05f878e580a3781e"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d644a64e174c16cb4b2e41dfea6af722053e83d066da7343f333a54dae9bc31c"}, + {file = "scipy-1.9.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:da8245491d73ed0a994ed9c2e380fd058ce2fa8a18da204681f2fe1f57f98f95"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4db5b30849606a95dcf519763dd3ab6fe9bd91df49eba517359e450a7d80ce2e"}, + {file = "scipy-1.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c68db6b290cbd4049012990d7fe71a2abd9ffbe82c0056ebe0f01df8be5436b0"}, + {file = "scipy-1.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:5b88e6d91ad9d59478fafe92a7c757d00c59e3bdc3331be8ada76a4f8d683f58"}, + {file = "scipy-1.9.3.tar.gz", hash = "sha256:fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027"}, ] [package.dependencies] -numpy = ">=1.16.5,<1.23.0" +numpy = ">=1.18.5,<1.26.0" + +[package.extras] +dev = ["flake8", "mypy", "pycodestyle", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-panels (>=0.5.2)", "sphinx-tabs"] +test = ["asv", "gmpy2", "mpmath", "pytest", "pytest-cov", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "setuptools" version = "67.6.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1497,27 +1459,6 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] -[[package]] -name = "setuptools-scm" -version = "6.4.2" -description = "the blessed package to manage your versions by scm tags" -category = "main" -optional = false -python-versions = ">=3.6" -files = [ - {file = "setuptools_scm-6.4.2-py3-none-any.whl", hash = "sha256:acea13255093849de7ccb11af9e1fb8bde7067783450cee9ef7a93139bddf6d4"}, - {file = "setuptools_scm-6.4.2.tar.gz", hash = "sha256:6833ac65c6ed9711a4d5d2266f8024cfa07c533a0e55f4c12f6eff280a5a9e30"}, -] - -[package.dependencies] -packaging = ">=20.0" -setuptools = "*" -tomli = ">=1.0.0" - -[package.extras] -test = ["pytest (>=6.2)", "virtualenv (>20)"] -toml = ["setuptools (>=42)"] - [[package]] name = "six" version = "1.16.0" @@ -1623,15 +1564,14 @@ files = [ ] [package.dependencies] -numpy = {version = ">=1.17", markers = "python_version != \"3.10\" or platform_system != \"Windows\" or platform_python_implementation == \"PyPy\""} +numpy = [ + {version = ">=1.17", markers = "python_version != \"3.10\" or platform_system != \"Windows\" or platform_python_implementation == \"PyPy\""}, + {version = ">=1.22.3", markers = "python_version == \"3.10\" and platform_system == \"Windows\" and platform_python_implementation != \"PyPy\""}, +] packaging = ">=21.3" pandas = ">=0.25" patsy = ">=0.5.2" -scipy = [ - {version = ">=1.3", markers = "(python_version > \"3.9\" or platform_system != \"Windows\" or platform_machine != \"x86\") and python_version < \"3.12\""}, - {version = ">=1.3,<1.8", markers = "python_version == \"3.7\""}, - {version = ">=1.3,<1.9", markers = "python_version == \"3.8\" and platform_system == \"Windows\" and platform_machine == \"x86\" or python_version == \"3.9\" and platform_system == \"Windows\" and platform_machine == \"x86\""}, -] +scipy = {version = ">=1.3", markers = "(python_version > \"3.9\" or platform_system != \"Windows\" or platform_machine != \"x86\") and python_version < \"3.12\""} [package.extras] build = ["cython (>=0.29.32)"] @@ -1681,7 +1621,7 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1722,45 +1662,11 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] -[[package]] -name = "typed-ast" -version = "1.5.4" -description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, -] - [[package]] name = "typing-extensions" version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1853,26 +1759,11 @@ files = [ {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] -[[package]] -name = "zipp" -version = "3.15.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] - [extras] +knn = ["nmslib"] spark = ["pyspark"] [metadata] lock-version = "2.0" -python-versions = ">=3.7.2, <3.11.0" -content-hash = "02758672434b7dd88b696da7545793eec9ead1eff5357161c3afabedd76b9f7c" +python-versions = ">=3.8, <3.13" +content-hash = "6e9ca734137c93abc80756be23ebc670efb11c122c4fc3ddfef26e5c07db963f" diff --git a/pyproject.toml b/pyproject.toml index 323e7a6..6675646 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,10 +39,10 @@ packages = [ ] [tool.poetry.dependencies] -python = ">=3.7.2, <3.11.0" +python = ">=3.8, <3.13" jinja2 = "^3.0.0" joblib = "^1.1.0" -nmslib = { version = "^2.0.4", optional = true } +nmslib = { version = "^2.0.4", optional = true, python = "<3.11" } numpy = ">=1.19.5, <2.0.0" pandas = ">=0.25.3, <2.0.0" pyspark = { version = "^3.2", optional = true }