`ingest` fails with pynndescent 0.7
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 68/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- numpy, python
- Domain
- data, machine-learning
Research direction
Start in scanpy/tools/_ingest.py, especially Ingest._init_pynndescent, and trace how it passes NNDescent.n_search_trees to make_forest. Reproduce with the provided minimal script using pynndescent 0.7.0, then check that sc.tl.ingest succeeds and existing ingest tests still pass.
Written by the indexing model from the issue text.
Description
Please make sure these conditions are met
- I have checked that this issue has not already been reported.
- I have confirmed this bug exists on the latest version of scanpy.
- (optional) I have confirmed this bug exists on the main branch of scanpy.
What happened?
pynndescent 0.7.0 deprecated NNDescent.n_search_trees (now None), and the make_forest workaround in Ingest._init_pynndescent passes it on. Works with pynndescent 0.6.0. Related: #4444
Minimal code sample
# /// script
# requires-python = ">=3.13"
# dependencies = [
# "scanpy@git+https://github.com/scverse/scanpy.git@main",
# ]
# ///
#
# This script automatically imports the development branch of scanpy to check for issues
import anndata as ad
import numpy as np
import scanpy as sc
adata = ad.AnnData(np.random.default_rng(0).normal(size=(300, 20)).astype(np.float32))
adata_ref, adata_new = adata[:200].copy(), adata[200:].copy()
sc.pp.pca(adata_ref)
sc.pp.neighbors(adata_ref)
sc.tl.umap(adata_ref)
sc.tl.ingest(adata_new, adata_ref)
Error output
Traceback (most recent call last):
File "issue_repro.py", line 19, in <module>
sc.tl.ingest(adata_new, adata_ref)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File ".../site-packages/scanpy/tools/_ingest.py", line 139, in ingest
ing = Ingest(adata_ref, neighbors_key)
File ".../site-packages/scanpy/tools/_ingest.py", line 376, in __init__
self._init_neighbors(adata, neighbors_key)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File ".../site-packages/scanpy/tools/_ingest.py", line 323, in _init_neighbors
self._init_pynndescent(
~~~~~~~~~~~~~~~~~~~~~~^
neighbors["distances"], rng=self._get_rng(neighbors["params"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File ".../site-packages/scanpy/tools/_ingest.py", line 290, in _init_pynndescent
self._nnd_idx._rp_forest = make_forest(
~~~~~~~~~~~^
self._nnd_idx._raw_data,
^^^^^^^^^^^^^^^^^^^^^^^^
...<6 lines>...
self._nnd_idx._angular_trees,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File ".../site-packages/pynndescent/rp_trees.py", line 3020, in make_forest
rng_states = random_state.randint(INT32_MIN, INT32_MAX, size=(n_trees, 3)).astype(
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "numpy/random/mtrand.pyx", line 801, in numpy.random.mtrand.RandomState.randint
File "numpy/random/_bounded_integers.pyx", line 1315, in numpy.random._bounded_integers._rand_int64
File ".../site-packages/numpy/_core/fromnumeric.py", line 3442, in prod
return _wrapreduction(a, np.multiply, 'prod', axis, dtype, out,
keepdims=keepdims, initial=initial, where=where)
File ".../site-packages/numpy/_core/fromnumeric.py", line 83, in _wrapreduction
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported operand type(s) for *: 'NoneType' and 'int'
Versions
pynndescent 0.7.0, umap-learn 0.5.12 (not listed by print_versions)
scanpy 1.14.0.dev35+g6f523e64e
---- ----
pandas 3.1.0
cloudpickle 3.1.2
python-dateutil 3.0.0
pydantic_core 2.50.1
llvmlite 0.50.0
scikit-learn 1.9.1
fast-array-utils 1.5.1
anndata 0.13.4
msgspec 0.22.0
narwhals 2.28.0
scipy 1.18.1
joblib 1.6.0
zarr 3.4.2
packaging 26.3
matplotlib 3.11.2
PyYAML 6.0.3
scverse-misc 0.1.7
cycler 0.12.1
numcodecs 0.17.1
annotated-types 0.8.0
pydantic-settings 2.16.1
charset-normalizer 3.5.2
typing-inspection 0.4.4
donfig 0.8.1.post1
pyparsing 3.3.3
pillow 13.0.0
python-dotenv 1.2.4
numba 0.68.1
typing_extensions 4.16.0
google-crc32c 1.9.0
fonttools 4.68.0
pydantic 2.14.1
natsort 8.4.0
h5py 3.16.0
session-info2 0.4.2
legacy-api-wrap 1.5
threadpoolctl 3.7.0
six 1.17.0
numpy 2.5.4
kiwisolver 1.5.1
---- ----
Python 3.14.3 (main, Mar 10 2026, 18:18:50) [Clang 21.1.4 ]
OS Linux-6.12.0-211.47.1.el10_2.x86_64-x86_64-with-glibc2.39
CPU 8/96 logical CPU cores
GPU No GPU found
Updated 2026-10-28 08:57
- Dominant language
- Python
- Stars
- 2.6k
- Forks
- 808
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 17
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from scverse/scanpy
-
`neighbors` fails with pynndescent 0.7: `'csr_array' object has no attribute 'getnnz'`Possibly taken @eroell claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
`highly_variable_genes(flavor="cell_ranger", n_top_genes=n)` selects 0 genes when the top genes have infinite normalized dispersionPossibly taken @jorgoose claimed this 15 days ago. OpenTriage 🩺
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
`downsample_counts(total_counts=...)` silently does nothing for Fortran-ordered dense `X`Possibly taken @entity-0-0-2 claimed this 20 days ago. OpenTriage 🩺
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Maintainers usually reply within 1 day
-
Multi-column `groupby` crashes on non-string observations in dotplot/matrixplot/heatmapPossibly taken @barlowa124 claimed this 31 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Graphify-Labs/graphify#4860 · 1 comment ·
Maintainers usually reply within 1 day
-
:bug: Bug
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
scikit-image/scikit-image#8377 ·
Maintainers usually reply within 1 day
-
Ingredient import validation accepts negative nutrient values and NaNPossibly taken @LukeSekai claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
wger-project/wger#2564 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
apache/ponymail-foal#351 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 68/100
Maintainers usually reply within 4 days