Skip to content

feat: move hashsolo to sc.pp - #4303

Merged
flying-sheep merged 12 commits into
mainfrom
hashsolo
Aug 21, 2026
Merged

feat: move hashsolo to sc.pp#4303
flying-sheep merged 12 commits into
mainfrom
hashsolo

Conversation

@flying-sheep

@flying-sheep flying-sheep commented Aug 18, 2026

Copy link
Copy Markdown
Member

Basically just moving the code over and adding an anndata.acc based version of the API on top.

People had issues with our old API since it only supported obs columns:

The new API of course supports everything! Yay accessors!

@flying-sheep flying-sheep changed the title feat: vendor hashsolo feat: move hashsolo to sc.pp Aug 18, 2026
@flying-sheep flying-sheep added this to the 1.13.0 milestone Aug 18, 2026
@codecov

codecov Bot commented Aug 18, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
2934 1 2933 206
View the top 1 failed test(s) by shortest run time
tests/test_datasets.py::test_ebi_expression_atlas
Stack Traces | 104s run time
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f5b97aa2c80>

    #x1B[0m#x1B[37m@pytest#x1B[39;49;00m.mark.internet#x1B[90m#x1B[39;49;00m
    #x1B[94mdef#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[92mtest_ebi_expression_atlas#x1B[39;49;00m(monkeypatch: pytest.MonkeyPatch):#x1B[90m#x1B[39;49;00m
        #x1B[94mfrom#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[04m#x1B[96mscanpy#x1B[39;49;00m#x1B[04m#x1B[96m.#x1B[39;49;00m#x1B[04m#x1B[96mdatasets#x1B[39;49;00m#x1B[90m #x1B[39;49;00m#x1B[94mimport#x1B[39;49;00m _ebi_expression_atlas #x1B[94mas#x1B[39;49;00m ea_mod#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
        #x1B[90m# make sure we use chunks when testing.#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[90m# This dataset has <8M entries, so 4M entries/chunk = 2 chunks#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
        #x1B[94massert#x1B[39;49;00m #x1B[96mhasattr#x1B[39;49;00m(ea_mod, #x1B[33m"#x1B[39;49;00m#x1B[33mCHUNK_SIZE#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
        monkeypatch.setattr(ea_mod, #x1B[33m"#x1B[39;49;00m#x1B[33mCHUNK_SIZE#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, #x1B[96mint#x1B[39;49;00m(#x1B[94m4e6#x1B[39;49;00m))#x1B[90m#x1B[39;49;00m
    #x1B[90m#x1B[39;49;00m
>       adata = sc.datasets.ebi_expression_atlas(#x1B[33m"#x1B[39;49;00m#x1B[33mE-MTAB-4888#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m

#x1B[1m#x1B[31mtests/test_datasets.py#x1B[0m:88: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
#x1B[1m#x1B[.../scanpy/datasets/_ebi_expression_atlas.py#x1B[0m:165: in ebi_expression_atlas
    #x1B[0mobs = pd.read_csv(experiment_dir / #x1B[33m"#x1B[39;49;00m#x1B[33mexperimental_design.tsv#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, sep=#x1B[33m"#x1B[39;49;00m#x1B[33m\t#x1B[39;49;00m#x1B[33m"#x1B[39;49;00m, index_col=#x1B[94m0#x1B[39;49;00m)#x1B[90m#x1B[39;49;00m
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31m../../../..../scanpy/B9PcT7QG/hatch-test.stable/lib/python3.14.../io/parsers/readers.py#x1B[0m:873: in read_csv
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m _read(filepath_or_buffer, kwds)#x1B[90m#x1B[39;49;00m
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31m../../../..../scanpy/B9PcT7QG/hatch-test.stable/lib/python3.14.../io/parsers/readers.py#x1B[0m:306: in _read
    #x1B[0m#x1B[94mreturn#x1B[39;49;00m parser.read(nrows)#x1B[90m#x1B[39;49;00m
           ^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31m../../../..../scanpy/B9PcT7QG/hatch-test.stable/lib/python3.14.../io/parsers/readers.py#x1B[0m:1947: in read
    #x1B[0m) = #x1B[96mself#x1B[39;49;00m._engine.read(  #x1B[90m# type: ignore[attr-defined]#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31m../../../..../scanpy/B9PcT7QG/hatch-test.stable/lib/python3.14.../io/parsers/c_parser_wrapper.py#x1B[0m:215: in read
    #x1B[0mchunks = #x1B[96mself#x1B[39;49;00m._reader.read_low_memory(nrows)#x1B[90m#x1B[39;49;00m
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mpandas/_libs/parsers.pyx#x1B[0m:832: in pandas._libs.parsers.TextReader.read_low_memory
    #x1B[0m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mpandas/_libs/parsers.pyx#x1B[0m:897: in pandas._libs.parsers.TextReader._read_rows
    #x1B[0m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mpandas/_libs/parsers.pyx#x1B[0m:868: in pandas._libs.parsers.TextReader._tokenize_rows
    #x1B[0m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mpandas/_libs/parsers.pyx#x1B[0m:885: in pandas._libs.parsers.TextReader._check_tokenize_status
    #x1B[0m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

>   #x1B[0m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[04m#x1B[91m?#x1B[39;49;00m#x1B[90m#x1B[39;49;00m
#x1B[1m#x1B[31mE   pandas.errors.ParserError: Error tokenizing data. C error: Expected 27 fields in line 2669, saw 31#x1B[0m

#x1B[1m#x1B[31mpandas/_libs/parsers.pyx#x1B[0m:2084: ParserError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@flying-sheep
flying-sheep marked this pull request as ready for review August 18, 2026 11:15
Comment thread src/scanpy/external/pp/_hashsolo.py Outdated
Comment thread docs/conf.py
Comment thread src/scanpy/preprocessing/_hashsolo.py Outdated
Comment thread src/scanpy/preprocessing/_hashsolo.py Outdated
Comment thread tests/test_hashsolo.py

@selmanozleyen selmanozleyen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some edge cases inherited from main and one new behaviour with the pd.unique and loc usage instead of the old np.unique. Plus one nitpick on dead return variables. But the rest seems good

@selmanozleyen selmanozleyen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, all looks very modern now also!

@flying-sheep
flying-sheep merged commit 9e259ff into main Aug 21, 2026
8 of 12 checks passed
@flying-sheep
flying-sheep deleted the hashsolo branch August 21, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

move sc.external.pp.hashsolo into sc.pp

2 participants