FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat: write support for keys that aren’t file names by flying-sheep · Pull Request #2662 · scverse/anndata · GitHub

Repository navigation

feat: write support for keys that aren’t file names - #2662

Open
flying-sheep wants to merge 3 commits into
feat/json-iofrom
feat/escape-keys
Open

flying-sheep wants to merge 3 commits into
feat/json-iofrom
feat/escape-keys

Conversation

flying-sheep commented Sep 25, 2026 •
edited
Loading

Copy link
Copy Markdown
Member

This and the two PRs below it are I need in 0.14 (for scanpy 2.0 preview), except for .uns accessors.

See also zarr-developers/zarr-specs#128

  • Release note not necessary because:

codecov Bot commented Sep 25, 2026 •
edited
Loading

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.98%. Comparing base (c5678b0) to head (4a53beb).
⚠️ Report is 1 commits behind head on feat/json-io.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@                Coverage Diff                @@
##           feat/json-io    #2662       +/-   ##
=================================================
+ Coverage         48.07%   85.98%   +37.91%     
=================================================
  Files                50       50               
  Lines              8329     8356       +27     
=================================================
+ Hits               4004     7185     +3181     
+ Misses             4325     1171     -3154     
Files with missing lines Coverage Δ
src/anndata/_io/h5ad.py 92.88% <100.00%> (+42.66%) ⬆️
src/anndata/_io/specs/methods.py 92.33% <100.00%> (+24.78%) ⬆️
src/anndata/_io/specs/registry.py 95.02% <100.00%> (+19.00%) ⬆️
src/anndata/_io/utils.py 80.44% <100.00%> (+42.94%) ⬆️
src/anndata/_write_compat.py 96.66% <100.00%> (+12.18%) ⬆️

... and 29 files with indirect coverage changes

Comment thread docs/fileformat-prose.md
Comment thread docs/fileformat-prose.md Outdated
flying-sheep changed the title feat: escape unsafe keys in 0.14 compat profile feat: write support for keys/columns that aren’t file names Sep 25, 2026

ilan-gold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Discussion is a bit mangled now, but scverse/zarr-convention-dataframe#1 is quite a strong suggestion that seems simpler to implement. Maybe let's discuss there and then I will implement there (and you here) whatever mechanism we settle on (your implementation here of other data frame things does not have to match mine otherwise)

Comment thread docs/fileformat-prose.md
flying-sheep force-pushed the feat/escape-keys branch 2 times, most recently from 622fd5a to 20b6199 Compare October 14, 2026 11:31
flying-sheep force-pushed the feat/escape-keys branch 2 times, most recently from 0428361 to ed0ed9c Compare October 20, 2026 15:15
flying-sheep changed the title feat: write support for keys/columns that aren’t file names feat: write support for keys that aren’t file names Oct 27, 2026

Copy link
Copy Markdown
Member

compat needs to be passed through write_use.

Otherwise these fail:

@pytest.mark.parametrize(
    "existing", ["x", "x/y"], ids=["unescaped-group", "escaped-group"]
)
@pytest.mark.parametrize("key", ["a/b", "100%"])
@pytest.mark.parametrize(
    "use", [lambda k: A.obsm[k], lambda _: A.obsm], ids=["single-key", "mapping"]
)
def test_use_escapes_keys(
    diskfmt_store: Path | MemoryStore,
    diskfmt: Literal["h5ad", "zarr"],
    existing: str,
    key: str,
    use: Callable[[str], object],
) -> None:
    """`use=` escapes keys like a full write with the same `compat` does.

    `100%` into an already escaped group is the silent case:
    written literally, it would be read back as an escape sequence.
    """
    adata = ad.AnnData(np.zeros((2, 3)), obsm={existing: np.zeros((2, 2))})
    getattr(adata, f"write_{diskfmt}")(diskfmt_store, compat="0.14")

    adata.obsm[key] = np.ones((2, 2))
    getattr(adata, f"write_{diskfmt}")(diskfmt_store, use=use(key), compat="0.14")
    back = getattr(ad, f"read_{diskfmt}")(diskfmt_store)

    assert set(back.obsm) == {existing, key}
    np.testing.assert_array_equal(back.obsm[key], np.ones((2, 2)))

ilan-gold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

disallow_forward_slash_in_h5ad: bool = True
should be removed wholesale (and maybe a deprecation cycle kicked off)

Unrelated, going to suggest taking a page out of Davis' Bennet's book, and having Claude do an adversarial test of this. Can Claude come up with use-cases where this breaks?

Comment thread docs/fileformat-prose.md
* The group's metadata MUST contain the encoding metadata `"encoding-type": "dict"`, `"encoding-version": "0.1.0"`

(mapping-escaped)=
### Mapping specifications (v0.2.0)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Why only mapping? #2039 seems to be for data frames

This branch has not been deployed

No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow any unicode incl. / and \ in obsm keys, obs columns, uns keys, …

3 participants


Back | FazBrowse Home | New Git URL