Skip to content

Fix NX class membership checks - #305

Open
CAOShurong wants to merge 1 commit into
scipp:mainfrom
CAOShurong:codex/241-class-membership
Open

CAOShurong wants to merge 1 commit into
scipp:mainfrom
CAOShurong:codex/241-class-membership

Conversation

@CAOShurong

Copy link
Copy Markdown

Summary

  • raise KeyError when an NX-class lookup has no matching direct children
  • make inherited mapping operations consistent: NXdata in group is false when absent, while group.get(NXdata, default) returns the default
  • preserve class lookup results when one or more matching children exist

Fixes #241.

Validation

  • baseline reproduction: an empty group reported NXdata in group as true and returned {} from both group[NXdata] and group.get(NXdata)
  • python -m pytest — 337 passed, 3 skipped
  • python -m mypy . — passed
  • changed-file pre-commit hooks — passed
  • sdist and wheel build — passed
  • isolated installed-wheel probe — missing/present membership, exact KeyError key, and Mapping.get default behavior passed

Implementation and validation were performed with OpenAI Codex assistance. I reviewed the change and take responsibility for it.

Signed-off-by: CAOShurong <170531907+CAOShurong@users.noreply.github.com>
@SimonHeybrock

Copy link
Copy Markdown
Member

Thanks! However, this will unfortunately break a number of our downstream uses, many callers rely on getting {} back:

  • essreduce, load_all_components: it runs parent[nx_class].items(), and the workflow uses it to load disk choppers. Any file without choppers would now fail with KeyError.
  • essreduce, _unique_child_group: the "Expected exactly one … got 0" ValueError becomes a KeyError. The test nexus_loader_test.py:484 checks for that ValueError.
  • essreduce, _contains_nx_class: it already has a KeyError branch "to future-proof", so it survives. workflow_test.py:239 asserts spec.filename['/entry'][snx.NXsample] == {}, which would fail.
  • essreflectometry, load.py:_unique_child_group: it returns None when there are 0 matches; that would now raise.
  • esslivedata, fake_detectors.py: instrument[snx.NXdetector_group] raises on instruments without detector groups. det[snx.NXevent_data] raises on dense detectors.
  • Other scripts: shrink_nexus.py (entry[snx.NXuser]) and the bifrost factories also do lookups that can come up empty.

That is, we likely need to think more how to approach this, or refactor all downstream uses first.

@SimonHeybrock

Copy link
Copy Markdown
Member

A less disruptive option from the issue would give the same user-facing fix without breaking callers: define Group.__contains__ (and get) to check for matching children, and leave __getitem__ alone. The cost is an inconsistency between __getitem__ and __contains__.

This branch has not been deployed

No deployments
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.

Group.__contains__ with nexus classes always returns True

2 participants