From 885f7a15c04433988d3e54cc58111937cfdb494b Mon Sep 17 00:00:00 2001 From: Sejal Date: Wed, 27 May 2026 18:08:09 +0000 Subject: [PATCH 1/8] Refactor validator return type to support warnings via ValidationResult wrapper (#1479) --- src/hdmf/validate/errors.py | 72 ++++++++++++++++++++++++++++++++++ src/hdmf/validate/validator.py | 7 ++-- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/hdmf/validate/errors.py b/src/hdmf/validate/errors.py index c1b4360a1..8348eb445 100644 --- a/src/hdmf/validate/errors.py +++ b/src/hdmf/validate/errors.py @@ -85,6 +85,78 @@ def __eq__(self, other): return hash(self) == hash(other) +class ValidationWarning: + + @docval({'name': 'name', 'type': str, 'doc': 'the name of the component that is erroneous'}, + {'name': 'reason', 'type': str, 'doc': 'the reason for the warning'}, + {'name': 'location', 'type': str, 'doc': 'the location of the warning', 'default': None}) + def __init__(self, **kwargs): + self.__name = getargs('name', kwargs) + self.__reason = getargs('reason', kwargs) + self.__location = getargs('location', kwargs) + + @property + def name(self): + return self.__name + + @property + def reason(self): + return self.__reason + + @property + def location(self): + return self.__location + + @location.setter + def location(self, loc): + self.__location = loc + + def __str__(self): + return self.__format_str(self.name, self.location, self.reason) + + @staticmethod + def __format_str(name, location, reason): + if location is not None: + return "%s (%s): %s" % (name, location, reason) + else: + return "%s: %s" % (name, reason) + + def __repr__(self): + return self.__str__() + + def __hash__(self): + return hash(self.__equatable_str()) + + def __equatable_str(self): + if self.location is not None: + equatable_name = self.name.split('/')[-1] + else: + equatable_name = self.name + return self.__format_str(equatable_name, self.location, self.reason) + + def __eq__(self, other): + return hash(self) == hash(other) + + +class ValidationResult: + + 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 [] + + def __iter__(self): + return iter(self.errors) + + def __len__(self): + return len(self.errors) + + def __bool__(self): + return bool(self.errors) + + def __getitem__(self, i): + return self.errors[i] + + class DtypeError(Error): @docval({'name': 'name', 'type': str, 'doc': 'the name of the component that is erroneous'}, diff --git a/src/hdmf/validate/validator.py b/src/hdmf/validate/validator.py index cac9dad1d..384a32c10 100644 --- a/src/hdmf/validate/validator.py +++ b/src/hdmf/validate/validator.py @@ -7,7 +7,7 @@ import numpy as np from .errors import Error, DtypeError, MissingError, MissingDataType, ShapeError, IllegalLinkError, IncorrectDataType -from .errors import ExpectedArrayError, IncorrectQuantityError +from .errors import ExpectedArrayError, IncorrectQuantityError, ValidationResult from ..build import GroupBuilder, DatasetBuilder, LinkBuilder, ReferenceBuilder from ..build.builders import BaseBuilder from ..spec import Spec, AttributeSpec, GroupSpec, DatasetSpec, RefSpec, LinkSpec @@ -270,7 +270,7 @@ def get_validator(self, **kwargs): raise ValueError(msg) @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)) def validate(self, **kwargs): """Validate a builder against a Spec @@ -283,7 +283,8 @@ def validate(self, **kwargs): msg = "builder must have data type defined with attribute '%s'" % self.__type_key raise ValueError(msg) validator = self.get_validator(dt) - return validator.validate(builder) + errors_list = validator.validate(builder) + return ValidationResult(errors=errors_list, warnings=[]) class Validator(metaclass=ABCMeta): From 8e46bd408532dad47e1a4feae6c7e6ee0cecca3b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 18:14:11 +0000 Subject: [PATCH 2/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/hdmf/validate/errors.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hdmf/validate/errors.py b/src/hdmf/validate/errors.py index 8348eb445..2d281885f 100644 --- a/src/hdmf/validate/errors.py +++ b/src/hdmf/validate/errors.py @@ -136,23 +136,23 @@ def __equatable_str(self): def __eq__(self, other): return hash(self) == hash(other) - + class ValidationResult: - + 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 [] def __iter__(self): return iter(self.errors) - + def __len__(self): return len(self.errors) - + def __bool__(self): return bool(self.errors) - + def __getitem__(self, i): return self.errors[i] From c1225d4bec02a247cac4a8826d90932b58186f4a Mon Sep 17 00:00:00 2001 From: Sejal Date: Tue, 2 Jun 2026 10:38:26 +0000 Subject: [PATCH 3/8] Update docstring and import for ValidationResult in common init --- CHANGELOG.md | 1 + src/hdmf/common/__init__.py | 9 ++++-- src/hdmf/validate/errors.py | 9 ++++-- src/hdmf/validate/validator.py | 2 +- tests/unit/validator_tests/test_validate.py | 34 ++++++++++++++++++++- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db863fa9d..d37b116a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - 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) ### Removed - Dropped support for Python 3.9. The minimum supported version is now Python 3.10. @rly [#xxx](https://github.com/hdmf-dev/hdmf/pull/xxx) diff --git a/src/hdmf/common/__init__.py b/src/hdmf/common/__init__.py index 20d39905a..d41590dc1 100644 --- a/src/hdmf/common/__init__.py +++ b/src/hdmf/common/__init__.py @@ -14,7 +14,7 @@ from ..utils import docval, getargs, get_docval, AllowPositional # noqa: E402 from ..backends.io import HDMFIO # noqa: E402 from ..backends.hdf5 import HDF5IO # noqa: E402 -from ..validate import ValidatorMap # noqa: E402 +from ..validate import ValidatorMap, ValidationResult # noqa: E402 from ..build import BuildManager, TypeMap # noqa: E402 from ..container import _set_exp # noqa: E402 @@ -207,10 +207,13 @@ def get_manager(**kwargs): 'doc': 'the namespace to validate against', 'default': CORE_NAMESPACE}, {'name': 'experimental', 'type': bool, 'doc': 'data type is an experimental data type', 'default': False}, - returns="errors in the file", rtype=list, + returns="errors and warnings in the file", rtype=ValidationResult, is_method=False) def validate(**kwargs): - """Validate an file against a namespace""" + """Validate an file against a namespace. + Returns: + ValidationResult: A ValidationResult object containing the errors and warnings found. + """ io, namespace, experimental = getargs('io', 'namespace', 'experimental', kwargs) if experimental: namespace = EXP_NAMESPACE diff --git a/src/hdmf/validate/errors.py b/src/hdmf/validate/errors.py index 8348eb445..1e3099cc2 100644 --- a/src/hdmf/validate/errors.py +++ b/src/hdmf/validate/errors.py @@ -12,7 +12,9 @@ "MissingDataType", "IllegalLinkError", "IncorrectDataType", - "IncorrectQuantityError" + "IncorrectQuantityError", + "ValidationWarning", + "ValidationResult" ] @@ -142,7 +144,7 @@ class ValidationResult: 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 [] + self.warnings = list(warnings) if warnings is not None else [] def __iter__(self): return iter(self.errors) @@ -155,6 +157,9 @@ def __bool__(self): def __getitem__(self, i): return self.errors[i] + + def __repr__(self): + return "ValidationResult(errors=%r, warnings=%r)" % (self.errors, self.warnings) class DtypeError(Error): diff --git a/src/hdmf/validate/validator.py b/src/hdmf/validate/validator.py index 384a32c10..edde6c8ff 100644 --- a/src/hdmf/validate/validator.py +++ b/src/hdmf/validate/validator.py @@ -270,7 +270,7 @@ def get_validator(self, **kwargs): raise ValueError(msg) @docval({'name': 'builder', 'type': BaseBuilder, 'doc': 'the builder to validate'}, - returns="a list of errors found", rtype=(list, ValidationResult)) + returns="A ValidationResult containing the errors and warnings found", rtype=ValidationResult) def validate(self, **kwargs): """Validate a builder against a Spec diff --git a/tests/unit/validator_tests/test_validate.py b/tests/unit/validator_tests/test_validate.py index 1ea50baed..a6ef791be 100644 --- a/tests/unit/validator_tests/test_validate.py +++ b/tests/unit/validator_tests/test_validate.py @@ -12,7 +12,7 @@ from hdmf.testing import TestCase, remove_test_file from hdmf.validate import ValidatorMap from hdmf.validate.errors import (DtypeError, MissingError, ExpectedArrayError, MissingDataType, - IncorrectQuantityError, IllegalLinkError, ShapeError) + IncorrectQuantityError, IllegalLinkError, ShapeError, ValidationWarning, ValidationResult, Error) from hdmf.backends.hdf5 import HDF5IO from hdmf.utils import ZARR_INSTALLED, StrDataset @@ -1723,3 +1723,35 @@ def test_utf8_for_ascii_hdf5(self): self.assertEqual(len(results), 1) self.assertIsInstance(results[0], DtypeError) self.assertEqual("Foo/data (my_foo/data): incorrect type - expected 'bytes', got 'utf'", str(results[0])) + + +class TestValidationResultWrapper: + """Unit tests for the ValidationResult container and ValidationWarning class. + + These tests verify that the ValidationResult wrapper correctly isolates + warnings while maintaining perfect backward compatibility by ensuring that + magic methods (__len__, __bool__, __iter__, __getitem__) reflect the errors + list only. + """ + + def test_validation_result_basic_behavior(self): + err = Error(name="TestError", reason="Critical issue", location="root") + warn = ValidationWarning(name="TestWarning", reason="Minor issue", location="root") + + result = ValidationResult(errors=[err], warnings=[warn]) + assert result.errors == [err] + assert result.warnings == [warn] + + assert len(result) == 1 + assert bool(result) is True + assert result[0] == err + assert list(result) == [err] + + def test_validation_result_empty_behavior(self): + empty_result = ValidationResult() + assert len(empty_result) == 0 + assert bool(empty_result) is False + assert empty_result.warnings == [] + + def test_validate_method_returns_empty_warnings(self): + pass \ No newline at end of file From 669261ea5819d11d5b4014b1412479380b20a752 Mon Sep 17 00:00:00 2001 From: Sejal Date: Tue, 2 Jun 2026 11:05:16 +0000 Subject: [PATCH 4/8] style: resolve ruff line length check on test imports --- tests/unit/validator_tests/test_validate.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/validator_tests/test_validate.py b/tests/unit/validator_tests/test_validate.py index dc2bdfee1..8070b255f 100644 --- a/tests/unit/validator_tests/test_validate.py +++ b/tests/unit/validator_tests/test_validate.py @@ -12,7 +12,8 @@ from hdmf.testing import TestCase, remove_test_file from hdmf.validate import ValidatorMap from hdmf.validate.errors import (DtypeError, MissingError, ExpectedArrayError, MissingDataType, - IncorrectQuantityError, IllegalLinkError, ShapeError,IncorrectDataType, ValidationWarning, ValidationResult, Error) + IncorrectQuantityError, IllegalLinkError, ShapeError,IncorrectDataType, + ValidationWarning, ValidationResult, Error) from hdmf.backends.hdf5 import HDF5IO from hdmf.utils import ZARR_INSTALLED, StrDataset from hdmf.validate.errors import Error From 88bb8e9645041b18a7ca04369f54dc0632546c12 Mon Sep 17 00:00:00 2001 From: Sejal Date: Tue, 2 Jun 2026 11:13:33 +0000 Subject: [PATCH 5/8] style: fix ruff F811 duplicate import redefinition error --- tests/unit/validator_tests/test_validate.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/validator_tests/test_validate.py b/tests/unit/validator_tests/test_validate.py index 8070b255f..daf087983 100644 --- a/tests/unit/validator_tests/test_validate.py +++ b/tests/unit/validator_tests/test_validate.py @@ -16,7 +16,6 @@ ValidationWarning, ValidationResult, Error) from hdmf.backends.hdf5 import HDF5IO from hdmf.utils import ZARR_INSTALLED, StrDataset -from hdmf.validate.errors import Error CORE_NAMESPACE = 'test_core' From 964acbff8197a7408e9957ac776574719ce1bf45 Mon Sep 17 00:00:00 2001 From: Sejal Date: Wed, 17 Jun 2026 11:03:30 +0000 Subject: [PATCH 6/8] Fix PR feedback, update ValidationWarning equality, and test structure --- CHANGELOG.md | 4 +- src/hdmf/common/__init__.py | 6 +- src/hdmf/validate/errors.py | 2 +- tests/unit/validator_tests/test_validate.py | 81 ++++++++++++--------- 4 files changed, 54 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 655b6e4c1..f7c024bbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # HDMF Changelog +## HDMF 6.1.0 (Upcoming) +- Refactored validator return type to `ValidationResult` to support upcoming validation warnings. @sejalpunwatkar [#1480](https://github.com/hdmf-dev/hdmf/pull/1480) + ## HDMF 6.0.2 (May 15, 2026) ### Fixed @@ -60,7 +63,6 @@ - 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) - Removed `test-min-deps` dependency group and replaced it with `uv pip install --resolution lowest-direct` in tox, making the project compatible with uv. @h-mayorquin [#1408](https://github.com/hdmf-dev/hdmf/pull/1408) - Changed `get_data_shape` to check `shape` before `maxshape`, so that objects with both attributes (e.g., h5py datasets) return their actual shape rather than their maximum shape. @rly [#1180](https://github.com/hdmf-dev/hdmf/pull/1180) diff --git a/src/hdmf/common/__init__.py b/src/hdmf/common/__init__.py index d41590dc1..85c75f4d3 100644 --- a/src/hdmf/common/__init__.py +++ b/src/hdmf/common/__init__.py @@ -210,10 +210,8 @@ def get_manager(**kwargs): returns="errors and warnings in the file", rtype=ValidationResult, is_method=False) def validate(**kwargs): - """Validate an file against a namespace. - Returns: - ValidationResult: A ValidationResult object containing the errors and warnings found. - """ + """Validate an file against a namespace.""" + io, namespace, experimental = getargs('io', 'namespace', 'experimental', kwargs) if experimental: namespace = EXP_NAMESPACE diff --git a/src/hdmf/validate/errors.py b/src/hdmf/validate/errors.py index c788013e0..7e36691d2 100644 --- a/src/hdmf/validate/errors.py +++ b/src/hdmf/validate/errors.py @@ -137,7 +137,7 @@ def __equatable_str(self): return self.__format_str(equatable_name, self.location, self.reason) def __eq__(self, other): - return hash(self) == hash(other) + return type(self) is type(other) and hash(self) == hash(other) class ValidationResult: diff --git a/tests/unit/validator_tests/test_validate.py b/tests/unit/validator_tests/test_validate.py index daf087983..5c12d3e6b 100644 --- a/tests/unit/validator_tests/test_validate.py +++ b/tests/unit/validator_tests/test_validate.py @@ -12,7 +12,7 @@ from hdmf.testing import TestCase, remove_test_file from hdmf.validate import ValidatorMap from hdmf.validate.errors import (DtypeError, MissingError, ExpectedArrayError, MissingDataType, - IncorrectQuantityError, IllegalLinkError, ShapeError,IncorrectDataType, + IncorrectQuantityError, IllegalLinkError, ShapeError, IncorrectDataType, ValidationWarning, ValidationResult, Error) from hdmf.backends.hdf5 import HDF5IO from hdmf.utils import ZARR_INSTALLED, StrDataset @@ -1765,38 +1765,6 @@ def test_utf8_for_ascii_hdf5(self): self.assertIsInstance(results[0], DtypeError) self.assertEqual("Foo/data (my_foo/data): incorrect type - expected 'bytes', got 'utf'", str(results[0])) - -class TestValidationResultWrapper: - """Unit tests for the ValidationResult container and ValidationWarning class. - - These tests verify that the ValidationResult wrapper correctly isolates - warnings while maintaining perfect backward compatibility by ensuring that - magic methods (__len__, __bool__, __iter__, __getitem__) reflect the errors - list only. - """ - - def test_validation_result_basic_behavior(self): - err = Error(name="TestError", reason="Critical issue", location="root") - warn = ValidationWarning(name="TestWarning", reason="Minor issue", location="root") - - result = ValidationResult(errors=[err], warnings=[warn]) - assert result.errors == [err] - assert result.warnings == [warn] - - assert len(result) == 1 - assert bool(result) is True - assert result[0] == err - assert list(result) == [err] - - def test_validation_result_empty_behavior(self): - empty_result = ValidationResult() - assert len(empty_result) == 0 - assert bool(empty_result) is False - assert empty_result.warnings == [] - - def test_validate_method_returns_empty_warnings(self): - pass - def test_dataset_reference_type_validation_hierarchy_success(self): """Test that subtype references are accepted via type hierarchy.""" @@ -2076,3 +2044,50 @@ def test_isodatetime_no_time_component_fails(self): self.assertEqual(len(result), 1) self.assertIsInstance(result[0], Error) + +class TestValidationResultWrapper(TestCase): + """Unit tests for the ValidationResult container and ValidationWarning class. + + These tests verify that the ValidationResult wrapper correctly isolates + warnings while maintaining perfect backward compatibility by ensuring that + magic methods (__len__, __bool__, __iter__, __getitem__) reflect the errors + list only. + """ + + def test_validation_result_basic_behavior(self): + err = Error(name="TestError", reason="Critical issue", location="root") + warn = ValidationWarning(name="TestWarning", reason="Minor issue", location="root") + + result = ValidationResult(errors=[err], warnings=[warn]) + assert result.errors == [err] + assert result.warnings == [warn] + + assert len(result) == 1 + assert bool(result) is True + assert result[0] == err + assert list(result) == [err] + + def test_validation_result_empty_behavior(self): + empty_result = ValidationResult() + assert len(empty_result) == 0 + assert bool(empty_result) is False + assert empty_result.warnings == [] + + def test_validate_method_returns_empty_warnings(self): + """Test that the validate method returns a ValidationResult with empty warnings for clean data.""" + + catalog = SpecCatalog() + namespace = SpecNamespace( + 'test ns', 'test_ns', + [], + version='0.1.0', + catalog=catalog + ) + vmap = ValidatorMap(namespace) + + builder = GroupBuilder('root') + + result = vmap.validate(builder) + + assert isinstance(result, ValidationResult) + assert result.warnings == [] \ No newline at end of file From 6b88ba97fbacf7189f7db58b37e5a7e94c978656 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:15:27 +0000 Subject: [PATCH 7/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/hdmf/common/__init__.py | 2 +- src/hdmf/validate/errors.py | 2 +- tests/unit/validator_tests/test_validate.py | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hdmf/common/__init__.py b/src/hdmf/common/__init__.py index 85c75f4d3..205bd5e6a 100644 --- a/src/hdmf/common/__init__.py +++ b/src/hdmf/common/__init__.py @@ -211,7 +211,7 @@ def get_manager(**kwargs): is_method=False) def validate(**kwargs): """Validate an file against a namespace.""" - + io, namespace, experimental = getargs('io', 'namespace', 'experimental', kwargs) if experimental: namespace = EXP_NAMESPACE diff --git a/src/hdmf/validate/errors.py b/src/hdmf/validate/errors.py index 7e36691d2..3fb8ea05d 100644 --- a/src/hdmf/validate/errors.py +++ b/src/hdmf/validate/errors.py @@ -157,7 +157,7 @@ def __bool__(self): def __getitem__(self, i): return self.errors[i] - + def __repr__(self): return "ValidationResult(errors=%r, warnings=%r)" % (self.errors, self.warnings) diff --git a/tests/unit/validator_tests/test_validate.py b/tests/unit/validator_tests/test_validate.py index 5c12d3e6b..aa900af0d 100644 --- a/tests/unit/validator_tests/test_validate.py +++ b/tests/unit/validator_tests/test_validate.py @@ -12,7 +12,7 @@ from hdmf.testing import TestCase, remove_test_file from hdmf.validate import ValidatorMap from hdmf.validate.errors import (DtypeError, MissingError, ExpectedArrayError, MissingDataType, - IncorrectQuantityError, IllegalLinkError, ShapeError, IncorrectDataType, + IncorrectQuantityError, IllegalLinkError, ShapeError, IncorrectDataType, ValidationWarning, ValidationResult, Error) from hdmf.backends.hdf5 import HDF5IO from hdmf.utils import ZARR_INSTALLED, StrDataset @@ -2048,9 +2048,9 @@ def test_isodatetime_no_time_component_fails(self): class TestValidationResultWrapper(TestCase): """Unit tests for the ValidationResult container and ValidationWarning class. - These tests verify that the ValidationResult wrapper correctly isolates - warnings while maintaining perfect backward compatibility by ensuring that - magic methods (__len__, __bool__, __iter__, __getitem__) reflect the errors + These tests verify that the ValidationResult wrapper correctly isolates + warnings while maintaining perfect backward compatibility by ensuring that + magic methods (__len__, __bool__, __iter__, __getitem__) reflect the errors list only. """ @@ -2090,4 +2090,4 @@ def test_validate_method_returns_empty_warnings(self): result = vmap.validate(builder) assert isinstance(result, ValidationResult) - assert result.warnings == [] \ No newline at end of file + assert result.warnings == [] From c0b04647aa15b7648aa80b7530abbc25444f3f03 Mon Sep 17 00:00:00 2001 From: Sejal Date: Wed, 17 Jun 2026 11:59:03 +0000 Subject: [PATCH 8/8] Add data type attribute to test builder setup --- tests/unit/validator_tests/test_validate.py | 23 ++++++++------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/tests/unit/validator_tests/test_validate.py b/tests/unit/validator_tests/test_validate.py index aa900af0d..e5296c181 100644 --- a/tests/unit/validator_tests/test_validate.py +++ b/tests/unit/validator_tests/test_validate.py @@ -2059,13 +2059,12 @@ def test_validation_result_basic_behavior(self): warn = ValidationWarning(name="TestWarning", reason="Minor issue", location="root") result = ValidationResult(errors=[err], warnings=[warn]) - assert result.errors == [err] - assert result.warnings == [warn] - - assert len(result) == 1 - assert bool(result) is True - assert result[0] == err - assert list(result) == [err] + self.assertEqual(result.errors, [err]) + self.assertEqual(result.warnings, [warn]) + self.assertEqual(len(result), 1) + self.assertTrue(bool(result)) + self.assertEqual(result[0], err) + self.assertEqual(list(result), [err]) def test_validation_result_empty_behavior(self): empty_result = ValidationResult() @@ -2077,15 +2076,11 @@ def test_validate_method_returns_empty_warnings(self): """Test that the validate method returns a ValidationResult with empty warnings for clean data.""" catalog = SpecCatalog() - namespace = SpecNamespace( - 'test ns', 'test_ns', - [], - version='0.1.0', - catalog=catalog - ) + catalog.register_spec(GroupSpec('A dummy spec', data_type_def='Dummy'), 'test.yaml') + namespace = SpecNamespace('test ns', 'test_ns', [{'source': 'test.yaml'}], version='0.1.0', catalog=catalog) vmap = ValidatorMap(namespace) - builder = GroupBuilder('root') + builder = GroupBuilder('root', attributes={'data_type': 'Dummy'}) result = vmap.validate(builder)