___________________ test_knn_forcing_backend[ball_tree-loky] ___________________
[gw0] linux -- Python 3.14.6 /home/runner/miniconda3/envs/testvenv/bin/python
joblib.externals.loky.process_executor._RemoteTraceback:
"""
Traceback (most recent call last):
File "/home/runner/miniconda3/envs/testvenv/lib/python3.14/site-packages/joblib/externals/loky/process_executor.py", line 453, in _process_worker
call_item = call_queue.get(block=True, timeout=timeout)
File "/home/runner/miniconda3/envs/testvenv/lib/python3.14/multiprocessing/queues.py", line 120, in get
return _ForkingPickler.loads(res)
~~~~~~~~~~~~~~~~~~~~~^^^^^
AttributeError: 'dict' object has no attribute '__annotate__'. Did you mean: '__getstate__'?
"""
The above exception was the direct cause of the following exception:
backend = 'loky', algorithm = 'ball_tree'
@pytest.mark.thread_unsafe
@pytest.mark.parametrize("backend", ["threading", "loky"])
@pytest.mark.parametrize("algorithm", ALGORITHMS)
def test_knn_forcing_backend(backend, algorithm):
# Non-regression test which ensures the knn methods are properly working
# even when forcing the global joblib backend.
with joblib.parallel_backend(backend):
X, y = datasets.make_classification(
n_samples=30, n_features=5, n_redundant=0, random_state=0
)
X_train, X_test, y_train, y_test = train_test_split(X, y)
clf = neighbors.KNeighborsClassifier(
n_neighbors=3, algorithm=algorithm, n_jobs=2
)
clf.fit(X_train, y_train)
> clf.predict(X_test)
X = array([[-0.86122569, 1.91006495, -0.26800337, 2.55614791, -3.17228221],
[ 0.61407937, 0.92220667, 0.3764255...865, -0.43782004, 1.17588368, 0.69480084],
[ 1.84926373, 0.67229476, 0.40746184, -0.5832139 , 1.00757175]])
X_test = array([[ 0.1666735 , 0.63503144, 2.38314477, -0.96222905, 0.90976274],
[ 1.84926373, 0.67229476, 0.4074618...481, 1.92294203, -0.2894503 , 1.3125179 ],
[-1.31590741, -0.4615846 , -0.06824161, 0.36759048, 1.74228521]])
X_train = array([[-0.87079715, -0.57884966, -0.31155253, -2.41378509, -1.86490941],
[-0.76991607, 0.53924919, -0.6743326...829, 1.12663592, 0.31816612, 2.05477441],
[-1.09306151, -1.49125759, 0.4393917 , 2.06061532, 1.21697419]])
algorithm = 'ball_tree'
backend = 'loky'
clf = KNeighborsClassifier(algorithm='ball_tree', n_jobs=2, n_neighbors=3)
y = array([1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1,
0, 0, 0, 1, 0, 0, 1, 0])
y_test = array([0, 0, 0, 0, 1, 1, 1, 1])
y_train = array([0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0])
../sklearn/neighbors/tests/test_neighbors.py:2120:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../sklearn/neighbors/_classification.py:278: in predict
neigh_ind = self.kneighbors(X, return_distance=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
X = array([[ 0.1666735 , 0.63503144, 2.38314477, -0.96222905, 0.90976274],
[ 1.84926373, 0.67229476, 0.4074618...481, 1.92294203, -0.2894503 , 1.3125179 ],
[-1.31590741, -0.4615846 , -0.06824161, 0.36759048, 1.74228521]])
self = KNeighborsClassifier(algorithm='ball_tree', n_jobs=2, n_neighbors=3)
../sklearn/neighbors/_base.py:916: in kneighbors
chunked_results = Parallel(n_jobs, prefer="threads")(
X = array([[ 0.1666735 , 0.63503144, 2.38314477, -0.96222905, 0.90976274],
[ 1.84926373, 0.67229476, 0.4074618...481, 1.92294203, -0.2894503 , 1.3125179 ],
[-1.31590741, -0.4615846 , -0.06824161, 0.36759048, 1.74228521]])
chunked_results = None
ensure_all_finite = True
n_jobs = 2
n_neighbors = 3
n_samples_fit = 22
query_is_train = False
return_distance = False
self = KNeighborsClassifier(algorithm='ball_tree', n_jobs=2, n_neighbors=3)
use_pairwise_distances_reductions = False
../sklearn/utils/parallel.py:91: in __call__
return super().__call__(iterable_with_config_and_warning_filters)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
__class__ = <class 'sklearn.utils.parallel.Parallel'>
config = {'assume_finite': False, 'working_memory': 1024, 'print_changed_only': True, 'display': 'diagram', ...}
filters_func = <function _get_filters at 0x7f9e42d93a00>
iterable = <generator object KNeighborsMixin.kneighbors.<locals>.<genexpr> at 0x7f9de05a17a0>
iterable_with_config_and_warning_filters = <generator object Parallel.__call__.<locals>.<genexpr> at 0x7f9de05a3de0>
self = Parallel(n_jobs=2)
warning_filters = [('ignore', re.compile('Class PassiveAggressive.+is deprecated', re.IGNORECASE), <class 'FutureWarning'>, None, 0), ('... shape on a NumPy array has been deprecated in NumPy 2.5', re.IGNORECASE), <class 'DeprecationWarning'>, None, 0), ...]
../../../../miniconda3/envs/testvenv/lib/python3.14/site-packages/joblib/parallel.py:2098: in __call__
return output if self.return_generator else list(output)
^^^^^^^^^^^^
_batched_calls_reducer_callback = <function Parallel.__call__.<locals>._batched_calls_reducer_callback at 0x7f9dd0da3530>
backend_name = 'LokyBackend'
iterable = <generator object Parallel.__call__.<locals>.<genexpr> at 0x7f9de05a3de0>
iterator = <itertools.islice object at 0x7f9dd04ef470>
n_jobs = 2
output = <generator object Parallel._get_outputs at 0x7f9de0959340>
pre_dispatch = 4
self = Parallel(n_jobs=2)
../../../../miniconda3/envs/testvenv/lib/python3.14/site-packages/joblib/parallel.py:1704: in _get_outputs
yield from self._retrieve()
_remaining_outputs = []
detach_generator_exit = False
dispatch_thread_id = 140317712021312
iterator = <itertools.islice object at 0x7f9dd04ef470>
pre_dispatch = 4
self = Parallel(n_jobs=2)
../../../../miniconda3/envs/testvenv/lib/python3.14/site-packages/joblib/parallel.py:1806: in _retrieve
self._raise_error_fast()
nb_jobs = 2
self = Parallel(n_jobs=2)
timeout_control_job = None
../../../../miniconda3/envs/testvenv/lib/python3.14/site-packages/joblib/parallel.py:1885: in _raise_error_fast
error_job.get_result(self.timeout)
error_job = <joblib.parallel.BatchCompletionCallBack object at 0x7f9dd035e600>
self = Parallel(n_jobs=2)
../../../../miniconda3/envs/testvenv/lib/python3.14/site-packages/joblib/parallel.py:780: in get_result
return self._return_or_raise()
^^^^^^^^^^^^^^^^^^^^^^^
backend = <joblib._parallel_backends.LokyBackend object at 0x7f9dd02edcd0>
self = <joblib.parallel.BatchCompletionCallBack object at 0x7f9dd035e600>
timeout = None
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <joblib.parallel.BatchCompletionCallBack object at 0x7f9dd035e600>
def _return_or_raise(self):
try:
if self.status == TASK_ERROR:
> raise self._result
E joblib.externals.loky.process_executor.BrokenProcessPool: A task has failed to un-serialize. Please ensure that the arguments of the function are all picklable.
self = <joblib.parallel.BatchCompletionCallBack object at 0x7f9dd035e600>
../../../../miniconda3/envs/testvenv/lib/python3.14/site-packages/joblib/parallel.py:795: BrokenProcessPool
Warning
This issue is not yet ready for a PR. If you are interested in contributing to scikit-learn, please have a look at our contributing guidelines, and in particular the sections for new contributors and the "Needs triage" label.
scipy-dev failure build log
A few related things:
main
We would need to figure out the source of the issue and report it to Cython
From #34344 (comment)
One of the argument of the parallel call of kneighbors (at
sklearn/neighbors/_base.py:916) raisesAttributeError: 'dict' object has no attribute '__annotate__'. Did you mean: '__getstate__'?when unpickling it in the worker.For the record, here is the traceback of the first failure:
Here are the failing tests: