#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.

#1135062#12
Date:
2026-08-19 08:26:59 UTC
From:
To:
Hello,

Bug #1135062 in python-pynndescent reported by you has been fixed in the
Git repository and is awaiting an upload. You can see the commit
message below and you can check the diff of the fix at:

https://salsa.debian.org/python-team/packages/python-pynndescent/-/commit/41402c06084d8a91de6888225c931966a4eef7ae
------------------------------------------------------------------------
Cherry-pick from an upstream commit to fix the sokalmichener removal.

Closes: #1135062
------------------------------------------------------------------------

(this message was generated automatically)
-- 
Greetings

https://bugs.debian.org/1135062

#1135062#19
Date:
2026-08-19 08:49:12 UTC
From:
To:
We believe that the bug you reported is fixed in the latest version of
python-pynndescent, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 1135062@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Michael R. Crusoe <crusoe@debian.org> (supplier of updated python-pynndescent package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@ftp-master.debian.org)
Format: 1.8
Date: Wed, 19 Aug 2026 10:14:28 +0300
Source: python-pynndescent
Architecture: source
Version: 0.6.0-2
Distribution: unstable
Urgency: medium
Maintainer: Debian Python Team <team+python@tracker.debian.org>
Changed-By: Michael R. Crusoe <crusoe@debian.org>
Closes: 1135062
Changes:
 python-pynndescent (0.6.0-2) unstable; urgency=medium
 .
   * Team upload.
   * Cherry-pick from an upstream commit to fix the sokalmichener
     removal. Closes: #1135062
   * d/control: build using pyproject (PEP-517).
   * Install the tests, and use them as autopkgtests.
   * Reflow Uploaders field (cme)
Checksums-Sha1:
 030034d5655abe108aca6019807bf605eb5b5859 2491 python-pynndescent_0.6.0-2.dsc
 a7a856be25e02174d65c41e98acb466bf775c00c 5392 python-pynndescent_0.6.0-2.debian.tar.xz
 238ad019f5a2d6807df74ab45f612394d10db33f 10097 python-pynndescent_0.6.0-2_source.buildinfo
Checksums-Sha256:
 e0f6839e0a14167bcd271d391cec14cae59e8534d3323691327b5cc48486a805 2491 python-pynndescent_0.6.0-2.dsc
 451b2e51f736ed9b25be9f6fbc2dd550527c5a4eacd43a8bdeb827f8662c7e47 5392 python-pynndescent_0.6.0-2.debian.tar.xz
 9e686eb8320b0845fbca289ae6a05ff4d8c1cae9becb922b38e3fefeb87c8229 10097 python-pynndescent_0.6.0-2_source.buildinfo
Files:
 b174299e461432fd163359ca30a9650c 2491 python optional python-pynndescent_0.6.0-2.dsc
 c8e963c42be32f2117de2c7ffe163164 5392 python optional python-pynndescent_0.6.0-2.debian.tar.xz
 bd5d8042fe799ea3c2fba440ccf768f4 10097 python optional python-pynndescent_0.6.0-2_source.buildinfo
-----BEGIN PGP SIGNATURE-----

iQJGBAEBCgAwFiEEck1gkzcRPHEFUNdHPCZ2P2xn5uIFAmqFaKoSHGNydXNvZUBk
ZWJpYW4ub3JnAAoJEDwmdj9sZ+biu6UP/1BM8HhqMnwYhMYK9LF2H0QUyX04YPXu
7O894jWgk/jsVh4itiZchZXAcqppgJiFGENtwHHkXN2bFq1ov0WP0fL6U9f0h5Ox
XT7BzdLtJQpGsug6LK+fkIsiRwEOJZ2xXfTdgRvRFsSN2N8VUV+hVk65mVxQ4U3V
LbFI8UdG13pqj5M5Iv56HjWyep2xqU/KYriDnLAs7aoWZgYJixQogjqtrS5aOT6d
xR17lQBnZ3kFD7SMIEgru37Rb+hr8NkFN+IoFyFkXTrV/QTA7iiIBrxQGdDGnAmg
9wUOuj5ADSkh86/huGdj0eT+JJSXTZ1iEMwfvGN/yFEJUbA3KD302BWnSE8gMJ70
NwcOugBdMFrGmgxXC8ZvDs55v0Zd5IoTbYZDzEIs7Ow/0d6BSfXriXICqaxqZtar
j+SIj5GEVJHrhtcUEeqKzlicb62EK6fjhaJZM0u05xEQsHcE3OEIkz8dEAoCFqNX
ancUZevLoNbKD9bfbuv/iBBeYVKOz0vDdbDvI2LBSNA3q1ARP0W65tMiTlRWYXKv
k2TAu9bzOmUn+oLcjGd+PSYnFrVJzsw/Wj1XK7FagOLzjIeae05+KengW7pHUZZ7
5DX5eKSGjMO1dntVpKC2h6IBxoVL2Curr+FI5/BOnkaleN4n3ukTG+DZ5w8pFoEN
ViM4cvck6G4F
=GeVP
-----END PGP SIGNATURE-----