#1135062 python-pynndescent: tests fail with scipy 1.17: sklearn: InvalidParameterError

#1135062#5
Date:
2026-04-27 08:25:43 UTC
From:
To:
python-pynndescent debci tests are failing with scipy 1.17,
currently available in experimental

e.g. https://ci.debian.net/packages/p/python-pynndescent/unstable/amd64/70512939/

365s _______________________ test_binary_check[sokalmichener] _______________________
365s
365s binary_data = array([[False, False, False, False,  True, False, False,  True, False,
365s         False, False, False, False, False, Fals...se, False, False, False,
365s         False, False, False, False, False, False, False, False, False,
365s         False, False]])
365s metric = 'sokalmichener'
365s
365s     @pytest.mark.parametrize(
365s         "metric",
365s         [
365s             "jaccard",
365s             "matching",
365s             "dice",
365s             "rogerstanimoto",
365s             "russellrao",
365s             "sokalmichener",
365s             "sokalsneath",
365s             "yule",
365s         ],
365s     )
365s     def test_binary_check(binary_data, metric):
365s >       dist_matrix = pairwise_distances(binary_data, metric=metric)
365s                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
365s
365s ../build.Ulb/src/pynndescent/tests/test_distances.py:70:
365s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
365s /usr/lib/python3/dist-packages/sklearn/utils/_param_validation.py:208: in wrapper
365s     validate_parameter_constraints(
365s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
365s
365s parameter_constraints = {'X': ['array-like', 'sparse matrix'], 'Y': ['array-like', 'sparse matrix', None], 'ensure_all_finite': ['boolean', <s..., 'metric': [<sklearn.utils._param_validation.StrOptions object at 0x7fa6a0b007c0>, <built-in function callable>], ...}
365s params = {'X': array([[False, False, False, False,  True, False, False,  True, False,
365s         False, False, False, False, False...se, False, False, False,
365s         False, False]]), 'Y': None, 'ensure_all_finite': True, 'metric': 'sokalmichener', ...}
365s caller_name = 'pairwise_distances'
365s
365s     def validate_parameter_constraints(parameter_constraints, params, caller_name):
365s         """Validate types and values of given parameters.
365s
365s         Parameters
365s         ----------
365s         parameter_constraints : dict or {"no_validation"}
365s             If "no_validation", validation is skipped for this parameter.
365s
365s             If a dict, it must be a dictionary `param_name: list of constraints`.
365s             A parameter is valid if it satisfies one of the constraints from the list.
365s             Constraints can be:
365s             - an Interval object, representing a continuous or discrete range of numbers
365s             - the string "array-like"
365s             - the string "sparse matrix"
365s             - the string "random_state"
365s             - callable
365s             - None, meaning that None is a valid value for the parameter
365s             - any type, meaning that any instance of this type is valid
365s             - an Options object, representing a set of elements of a given type
365s             - a StrOptions object, representing a set of strings
365s             - the string "boolean"
365s             - the string "verbose"
365s             - the string "cv_object"
365s             - the string "nan"
365s             - a MissingValues object representing markers for missing values
365s             - a HasMethods object, representing method(s) an object must have
365s             - a Hidden object, representing a constraint not meant to be exposed to the user
365s
365s         params : dict
365s             A dictionary `param_name: param_value`. The parameters to validate against the
365s             constraints.
365s
365s         caller_name : str
365s             The name of the estimator or function or method that called this function.
365s         """
365s         for param_name, param_val in params.items():
365s             # We allow parameters to not have a constraint so that third party estimators
365s             # can inherit from sklearn estimators without having to necessarily use the
365s             # validation tools.
365s             if param_name not in parameter_constraints:
365s                 continue
365s
365s             constraints = parameter_constraints[param_name]
365s
365s             if constraints == "no_validation":
365s                 continue
365s
365s             constraints = [make_constraint(constraint) for constraint in constraints]
365s
365s             for constraint in constraints:
365s                 if constraint.is_satisfied_by(param_val):
365s                     # this constraint is satisfied, no need to check further.
365s                     break
365s             else:
365s                 # No constraint is satisfied, raise with an informative message.
365s
365s                 # Ignore constraints that we don't want to expose in the error message,
365s                 # i.e. options that are for internal purpose or not officially supported.
365s                 constraints = [
365s                     constraint for constraint in constraints if not constraint.hidden
365s                 ]
365s
365s                 if len(constraints) == 1:
365s                     constraints_str = f"{constraints[0]}"
365s                 else:
365s                     constraints_str = (
365s                         f"{', '.join([str(c) for c in constraints[:-1]])} or"
365s                         f" {constraints[-1]}"
365s                     )
365s
365s >               raise InvalidParameterError(
365s                     f"The {param_name!r} parameter of {caller_name} must be"
365s                     f" {constraints_str}. Got {param_val!r} instead."
365s                 )
365s E               sklearn.utils._param_validation.InvalidParameterError: The 'metric' parameter of pairwise_distances must be a str among {'wminkowski', 'haversine', 'euclidean', 'mahalanobis', 'canberra', 'matching', 'l2', 'nan_euclidean', 'precomputed', 'cosine', 'jaccard', 'seuclidean', 'sqeuclidean', 'sokalsneath', 'dice', 'l1', 'braycurtis', 'correlation', 'manhattan', 'yule', 'minkowski', 'cityblock', 'russellrao', 'hamming', 'chebyshev', 'rogerstanimoto'} or a callable. Got 'sokalmichener' instead.
365s
365s /usr/lib/python3/dist-packages/sklearn/utils/_param_validation.py:98: InvalidParameterError


This bug will later become RC severity: serious once scipy 1.17 is
uploaded to unstable.