Repository navigation
Record the actual NWB Inspector version in validation results - #1966
Merged
Merged
Conversation
`_get_nwb_inspector_version()` cached the version in a module global that started out as "" but was guarded with `is not None`, so it always returned "" without ever looking the version up. As a result every NWB Inspector validation result carried an empty `origin.validator_version`, and the etelemetry check warning about an outdated NWB Inspector never ran. Use a `None` sentinel (typed as `packaging.version.Version | None`, which is what `nwbinspector.utils.get_package_version()` returns), and hold a lock while looking the version up, since `dandi upload` validates assets concurrently, so that the lookup and the etelemetry check happen only once per process. The etelemetry query is moved into a small helper, which also skips the check quietly when etelemetry is disabled via `NO_ET` (in which case `etelemetry.get_project()` returns `None`) instead of warning about a `TypeError`. In tests, an autouse fixture stubs out that helper so that validating NWB files never queries etelemetry over the network or emits "please upgrade" warnings. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011mgA1x4jnEavPHXQkyrnEk
Use the module global directly instead of a local copy (as the code did before), so that CodeQL no longer reports the assignment to it as unused. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_011mgA1x4jnEavPHXQkyrnEk
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1966 +/- ##
==========================================
+ Coverage 90.76% 90.89% +0.13%
==========================================
Files 92 92
Lines 14159 14190 +31
==========================================
+ Hits 12851 12898 +47
+ Misses 1308 1292 -16
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
CodyCBakerPhD
marked this pull request as ready for review
October 16, 2026 02:20
yarikoptic
approved these changes
Oct 16, 2026
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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User-visible effect
dandi validate(and from validation duringdandi upload) now hasorigin.validator_versionset to the installed nwbinspector version, e.g."0.7.2". Before this change it was always"". The archive can now match these records to the nwbinspector version that produced them.dandi validatelogs the existing "NWB Inspector version X is installed - please use the latest release…" warning once per process. Before this change that code never ran.Failed to retrieve NWB Inspector version due to …warning is now logged once per process.NO_ET(etelemetry's own opt-out) skips the check silently.The bug
_get_nwb_inspector_version()indandi/files/bases.pycached the version in a module global that started as"", but the cache check wasis not None. Since"" is not None, the function always returned""right away: the version was never looked up and the etelemetry check below it never ran.Changes
dandi/files/bases.pyNone, typed asVersion | None. That matches whatnwbinspector.utils.get_package_version()returns (packaging.version.Version), so the existing< max_versioncomparison still works._get_nwb_inspector_version()is annotated-> Version, and the caller still doesstr(...).Lock.dandi uploadvalidates assets in up to 5 threads at once, and without the lock several threads could each run the etelemetry lookup and log duplicate warnings. Most of this diff is re-indentation from the lock; it reads best with whitespace ignored._get_latest_nwb_inspector_version(). It returnsNonewhenetelemetry.get_project()does, which happens whenNO_ETis set (as in our CI). Without that, users withNO_ETset (and CI) would get a confusingTypeError: 'NoneType' object is not subscriptablewarning. The existing try/except around the check is unchanged.dandi/tests/fixtures.py: new autouse fixtureno_nwbinspector_etelemetrythat stubs out the helper. Tests that validate NWB files then never query etelemetry over the network and never log "please upgrade" or "failed to retrieve" warnings. It patches only this dandi-private helper, notetelemetryorNO_ETglobally, so other projects that load the dandi pytest plugin aren't affected.dandi/tests/test_files.py: new tests, all marked@pytest.mark.ai_generated:test_validate_nwb_records_nwbinspector_version: validates the realsimple4_nwbfixture and checks that every NWB Inspector result'sorigin.validator_versionequals the installed nwbinspector version. Both sides are normalized withpackaging.version.Version.test_get_nwb_inspector_version_cached[...]: runs in a fresh interpreter, so the cache starts in the same state as fordandi validate, withetelemetry.get_projectreplaced by a counting fake (no network). It checks that two calls return the same installed version and etelemetry is queried exactly once. It is parametrized over theNO_ETcase (no warning) and a newer upstream release (exactly one outdated warning). Resetting the cache in-process wouldn't catch this bug, because the bug was in the initial value.The synthetic
validator_version=""placeholders indandi/cli/tests/test_cmd_validate.py(formatter tests) are deliberately left alone.Testing
master({''} == {'0.7.2'}and['', ''] == ['0.7.2', '0.7.2']) and pass with the fix.dandi/cli/tests/test_cmd_validate.py,dandi/tests/test_files.py, anddandi/validate/: 134 passed, 3 skipped.mypy dandi: no issues. pre-commit (black, isort, codespell, flake8, reuse): all passed.dandi validate -f json_lineson an NWB file with best-practice violations now shows"validator_version": "0.7.2"on theNWBI.*records.🤖 Generated with Claude Code
https://claude.ai/code/session_011mgA1x4jnEavPHXQkyrnEk
Generated by Claude Code