Refactor validator return type to support warnings via ValidationResult wrapper (#1479)#1480
Refactor validator return type to support warnings via ValidationResult wrapper (#1479)#1480sejalpunwatkar wants to merge 11 commits into
Conversation
for more information, see https://pre-commit.ci
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## dev #1480 +/- ##
==========================================
- Coverage 93.21% 93.09% -0.13%
==========================================
Files 41 41
Lines 10182 10233 +51
Branches 2104 2106 +2
==========================================
+ Hits 9491 9526 +35
- Misses 414 430 +16
Partials 277 277 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Thanks! Looks good overall. Could you please add some basic tests of
Could you please also add a changelog entry that points to this PR? |
3a072bb to
669261e
Compare
9d3ea64 to
88bb8e9
Compare
|
@sejalpunwatkar Thanks for your work on this. Let me know when it is ready for re-review. |
|
Hi @rly, the PR is now ready for your re-review! I have fully addressed your feedback from the initial code review:
|
| Returns: | ||
| ValidationResult: A ValidationResult object containing the errors and warnings found. |
There was a problem hiding this comment.
It's unconventional, but the return docstring is encoded in the returns argument in the @docval above, so this should be removed here.
| Returns: | |
| ValidationResult: A ValidationResult object containing the errors and warnings found. |
| - Deprecated `BaseStorageSpec.add_attribute`, `GroupSpec.add_group`, `GroupSpec.add_dataset`, and `GroupSpec.add_link`. Use `set_attribute`, `set_group`, `set_dataset`, and `set_link` instead. @rly [#1333](https://github.com/hdmf-dev/hdmf/pull/1333) | ||
| - Deprecated unused `BaseStorageSpec.get_data_type_spec` and `BaseStorageSpec.get_namespace_spec`. @rly [#1333](https://github.com/hdmf-dev/hdmf/pull/1333) | ||
| - Moved `test`, `docs`, and `min-reqs` from `[project.optional-dependencies]` to `[dependency-groups]` (PEP 735). `min-reqs` was renamed to `test-min-deps`. @rly [#1395](https://github.com/hdmf-dev/hdmf/pull/1395) | ||
| - Refactored validator return type to `ValidationResult` to support upcoming validation warnings. @sejalpunwatkar [#1480](https://github.com/hdmf-dev/hdmf/pull/1480) |
There was a problem hiding this comment.
The changelog has been updated since you started this work. Please add this entry to a new section at the top of the file
## HDMF 6.1.0 (Upcoming)
| self.assertIsInstance(results[0], DtypeError) | ||
| self.assertEqual("Foo/data (my_foo/data): incorrect type - expected 'bytes', got 'utf'", str(results[0])) | ||
|
|
||
|
|
There was a problem hiding this comment.
This test class was inserted in the middle of TestVlenStringData so the tests after your additions here have been added to TestValidationResultWrapper which is not correct.
| self.assertEqual("Foo/data (my_foo/data): incorrect type - expected 'bytes', got 'utf'", str(results[0])) | ||
|
|
||
|
|
||
| class TestValidationResultWrapper: |
There was a problem hiding this comment.
| class TestValidationResultWrapper: | |
| class TestValidationResultWrapper(TestCase): |
By convention, all test classes should subclass hdmf.testing.TestCase
| assert empty_result.warnings == [] | ||
|
|
||
| def test_validate_method_returns_empty_warnings(self): | ||
| pass |
| from hdmf.validate import ValidatorMap | ||
| from hdmf.validate.errors import (DtypeError, MissingError, ExpectedArrayError, MissingDataType, | ||
| IncorrectQuantityError, IllegalLinkError, ShapeError, IncorrectDataType) | ||
| IncorrectQuantityError, IllegalLinkError, ShapeError,IncorrectDataType, |
There was a problem hiding this comment.
| IncorrectQuantityError, IllegalLinkError, ShapeError,IncorrectDataType, | |
| IncorrectQuantityError, IllegalLinkError, ShapeError, IncorrectDataType, |
| return hash(self) == hash(other) | ||
|
|
||
|
|
||
| class ValidationWarning: |
There was a problem hiding this comment.
Since ValidationWarning is almost entirely identical to Error, it would be better to create a shared base class ValidationIssue that both extend from and that contains all the shared code. Downstream code will still be able to differentiate between Error and ValidationWarning because they are different classes.
One minor thing is that because __eq__ is defined based on the hash and I believe the hash of a ValidationWarning and the hash of an identical Error object will be the same, then Error("name", "reason") == ValidationWarning("name", "reason") will be True. This might become an issue if/when errors and warnings are placed in a dict together.
To address this, I would change __eq__ to:
def __eq__(self, other):
return type(self) is type(other) and hash(self) == hash(other)|
Thanks @sejalpunwatkar . This is looking much better. I have a few more comments and suggestions above |
5e33150 to
964acbf
Compare
|
Hi @rly, I've addressed all your feedback: fixed the changelog section, updated the docstrings, corrected the test indentation, implemented the missing test, and updated the ValidationWarning.eq check. Ready for review! |
Motivation
Addresses #1479
This PR implements Phase 1 (the foundational plumbing) to introduce
ValidationWarninginfrastructure without breaking the existing error reporting model. This change ensures that downstream packages (like PyNWB and NWB Inspector) can eventually consume warning-level messages without modifying their immediate logic or incorrectly marking files as invalid.How to test the behavior?
ValidationWarningclass as a sibling toErrorinsideerrors.py, preserving the matching internal shape (.name,.reason,.location).ValidationResultwrapper class inerrors.pywith custom Python overrides (__bool__,__len__,__iter__,__getitem__) pointing explicitly to theerrorsbucket to ensure backward compatibility.ValidatorMap.validate()insidevalidator.pyto capture theerrors_list, wrap it into the newValidationResultcontainer with an empty warnings container (warnings=[]), and adjusted its strict@docvalreturn type check tortype=(list, ValidationResult).Checklist
CHANGELOG.mdwith your changes?