Skip to content

Refactor validator return type to support warnings via ValidationResult wrapper (#1479)#1480

Open
sejalpunwatkar wants to merge 3 commits into
hdmf-dev:devfrom
sejalpunwatkar:feature/1479-validation-result
Open

Refactor validator return type to support warnings via ValidationResult wrapper (#1479)#1480
sejalpunwatkar wants to merge 3 commits into
hdmf-dev:devfrom
sejalpunwatkar:feature/1479-validation-result

Conversation

@sejalpunwatkar
Copy link
Copy Markdown
Contributor

Motivation

Addresses #1479

This PR implements Phase 1 (the foundational plumbing) to introduce ValidationWarning infrastructure 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?

  1. Added Core Types: Introduced ValidationWarning class as a sibling to Error inside errors.py, preserving the matching internal shape (.name, .reason, .location).
  2. Built the Smart Container: Implemented the ValidationResult wrapper class in errors.py with custom Python overrides (__bool__, __len__, __iter__, __getitem__) pointing explicitly to the errors bucket to ensure backward compatibility.
  3. Wired the Plumbing: Updated ValidatorMap.validate() inside validator.py to capture the errors_list, wrap it into the new ValidationResult container with an empty warnings container (warnings=[]), and adjusted its strict @docval return type check to rtype=(list, ValidationResult).

Checklist

  • Did you update CHANGELOG.md with your changes?
  • Does the PR clearly describe the problem and the solution?
  • Have you reviewed our Contributing Guide?
  • Does the PR use "Fix #XXX" notation to tell GitHub to close the relevant issue numbered XXX when the PR is merged?

@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

❌ Patch coverage is 64.70588% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.04%. Comparing base (62469df) to head (3ee3ea3).

Files with missing lines Patch % Lines
src/hdmf/validate/errors.py 62.50% 18 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1480      +/-   ##
==========================================
- Coverage   93.18%   93.04%   -0.15%     
==========================================
  Files          41       41              
  Lines       10176    10225      +49     
  Branches     2103     2105       +2     
==========================================
+ Hits         9483     9514      +31     
- Misses        415      433      +18     
  Partials      278      278              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.


def __init__(self, errors = None, warnings = None):
self.errors = list(errors) if errors is not None else []
self.warnings = list(warnings) if errors is not None else []
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.

Suggested change
self.warnings = list(warnings) if errors is not None else []
self.warnings = list(warnings) if warnings is not None else []

"IllegalLinkError",
"IncorrectDataType",
"IncorrectQuantityError"
]
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.

Please add the new classes to __all__


@docval({'name': 'builder', 'type': BaseBuilder, 'doc': 'the builder to validate'},
returns="a list of errors found", rtype=list)
returns="a list of errors found", rtype=(list, ValidationResult))
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.

Suggested change
returns="a list of errors found", rtype=(list, ValidationResult))
returns="A ValidationResult containing the errors and warnings found", rtype=ValidationResult)

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.

Please also update the docstring of validate(...) in src/hdmf/common/__init__.py:210

@rly
Copy link
Copy Markdown
Contributor

rly commented May 30, 2026

Thanks! Looks good overall. Could you please add some basic tests of ValidationResult:

  • validate() returns a ValidationResult with .warnings == [].
  • Backward compatibility: bool, len, iteration, indexing all reflect errors only.
  • Construct ValidationResult(warnings=[w]) and assert the warning survives.

Could you please also add a changelog entry that points to this PR?

Comment on lines +156 to +157
def __getitem__(self, i):
return self.errors[i]
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.

Below this, could you add a simple __repr__ so that users can print this object (like they did the list before) and get a human-readable listing of the errors and warnings instead of the object address?

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.

2 participants