-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add hedId value checking to schema validation
Fix version attribute for merged schemas Remove cache hit from scripts(I think it's not required, but we'll see...) rename tag_util -> util in the normal validator
- Loading branch information
Showing
21 changed files
with
206 additions
and
27 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
from hed.schema.schema_io.ontology_util import get_library_data, remove_prefix | ||
from semantic_version import Version | ||
from hed.schema.hed_schema_io import load_schema_version | ||
from hed.schema.hed_cache import get_hed_versions | ||
from hed.schema.hed_schema_constants import HedKey | ||
from hed.errors.error_types import SchemaAttributeErrors | ||
from hed.errors.error_reporter import ErrorHandler | ||
|
||
|
||
class HedIDValidator: | ||
"""Support class to validate hedIds in schemas""" | ||
def __init__(self, hed_schema): | ||
"""Support class to validate hedIds in schemas | ||
Parameters: | ||
hed_schema(HedSchemaBase): The schema we're validating. | ||
It uses this to derive the version number(s) of the previous schema. | ||
""" | ||
self.hed_schema = hed_schema | ||
self._previous_schemas = {} | ||
|
||
versions = self.hed_schema.version_number.split(",") | ||
libraries = self.hed_schema.library.split(",") | ||
|
||
prev_versions = {} | ||
self.library_data = {} | ||
for version, library in zip(versions, libraries): | ||
prev_version = self._get_previous_version(version, library) | ||
if prev_version: | ||
prev_versions[library] = prev_version | ||
library_data = get_library_data(library) | ||
if library_data: | ||
self.library_data[library] = library_data | ||
|
||
# Add the standard schema if we have a with_standard | ||
if "" not in prev_versions and self.hed_schema.with_standard: | ||
prev_version = self._get_previous_version(self.hed_schema.with_standard, "") | ||
prev_versions[""] = prev_version | ||
self.library_data[""] = get_library_data("") | ||
|
||
if prev_versions: | ||
self._previous_schemas = {library: load_schema_version(full_version) for library, full_version in | ||
prev_versions.items()} | ||
|
||
@staticmethod | ||
def _get_previous_version(version, library): | ||
current_version = Version(version) | ||
all_schema_versions = get_hed_versions(library_name=library) | ||
for old_version in all_schema_versions: | ||
if Version(old_version) < current_version: | ||
prev_version = old_version | ||
if library: | ||
prev_version = f"{library}_{prev_version}" | ||
return prev_version | ||
|
||
def verify_tag_id(self, hed_schema, tag_entry, attribute_name): | ||
"""Validates the hedID attribute values | ||
This follows the template from schema_attribute_validators.py | ||
Parameters: | ||
hed_schema (HedSchema): The schema to use for validation | ||
tag_entry (HedSchemaEntry): The schema entry for this tag. | ||
attribute_name (str): The name of this attribute | ||
Returns: | ||
issues(list): A list of issues from validating this attribute. | ||
""" | ||
# todo: If you have a way to know the schema should have 100% ids, you could check for that and flag missing | ||
new_id = tag_entry.attributes.get(attribute_name, "") | ||
old_id = None | ||
tag_library = tag_entry.has_attribute(HedKey.InLibrary, return_value=True) | ||
if not tag_library: | ||
tag_library = "" | ||
|
||
previous_schema = self._previous_schemas.get(tag_library) | ||
if previous_schema: | ||
old_entry = previous_schema.get_tag_entry(tag_entry.name, key_class=tag_entry.section_key) | ||
if old_entry: | ||
old_id = old_entry.attributes.get(HedKey.HedID) | ||
|
||
if old_id: | ||
try: | ||
old_id = int(remove_prefix(old_id, "HED_")) | ||
except ValueError: | ||
# Just silently ignore invalid old_id values(this shouldn't happen) | ||
pass | ||
if new_id: | ||
try: | ||
new_id = int(remove_prefix(new_id, "HED_")) | ||
except ValueError: | ||
return ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_HED_ID_INVALID, tag_entry.name, new_id) | ||
# Nothing to verify | ||
if new_id is None and old_id is None: | ||
return [] | ||
|
||
issues = [] | ||
if old_id and old_id != new_id: | ||
issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_HED_ID_INVALID, tag_entry.name, new_id, | ||
old_id=old_id) | ||
|
||
library_data = self.library_data.get(tag_library) | ||
if library_data and new_id is not None: | ||
starting_id, ending_id = library_data["id_range"] | ||
if new_id < starting_id or new_id > ending_id: | ||
issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_HED_ID_INVALID, tag_entry.name, | ||
new_id, valid_min=starting_id, valid_max=ending_id) | ||
|
||
return issues |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import unittest | ||
import copy | ||
|
||
from hed.schema.schema_attribute_validator_hed_id import HedIDValidator | ||
from hed.schema import hed_schema_constants | ||
from hed import load_schema_version | ||
from hed.schema import HedKey | ||
|
||
|
||
# tests needed: | ||
# 1. Verify hed id(HARDEST, MAY SKIP) | ||
# 4. Json tests | ||
|
||
class Test(unittest.TestCase): | ||
@classmethod | ||
def setUpClass(cls): | ||
cls.hed_schema = load_schema_version("8.3.0") | ||
cls.test_schema = load_schema_version("testlib_3.0.0") | ||
cls.hed_schema84 = copy.deepcopy(cls.hed_schema) | ||
cls.hed_schema84.header_attributes[hed_schema_constants.VERSION_ATTRIBUTE] = "8.4.0" | ||
|
||
def test_constructor(self): | ||
id_validator = HedIDValidator(self.hed_schema) | ||
|
||
self.assertTrue(id_validator._previous_schemas[""]) | ||
self.assertTrue(id_validator.library_data[""]) | ||
self.assertEqual(id_validator._previous_schemas[""].version_number, "8.2.0") | ||
|
||
id_validator = HedIDValidator(self.test_schema) | ||
|
||
self.assertTrue(id_validator._previous_schemas[""]) | ||
self.assertTrue(id_validator.library_data[""]) | ||
self.assertTrue(id_validator._previous_schemas["testlib"]) | ||
self.assertEqual(id_validator.library_data.get("testlib"), None) | ||
self.assertEqual(id_validator._previous_schemas["testlib"].version_number, "2.1.0") | ||
self.assertEqual(id_validator._previous_schemas[""].version_number, "8.1.0") | ||
|
||
def test_get_previous_version(self): | ||
self.assertEqual(HedIDValidator._get_previous_version("8.3.0", ""), "8.2.0") | ||
self.assertEqual(HedIDValidator._get_previous_version("8.2.0", ""), "8.1.0") | ||
self.assertEqual(HedIDValidator._get_previous_version("8.0.0", ""), None) | ||
self.assertEqual(HedIDValidator._get_previous_version("3.0.0", "testlib"), "testlib_2.1.0") | ||
|
||
def test_verify_tag_id(self): | ||
event_entry = self.hed_schema84.tags["Event"] | ||
event_entry.attributes[HedKey.HedID] = "HED_0000000" | ||
|
||
id_validator = HedIDValidator(self.hed_schema84) | ||
|
||
issues = id_validator.verify_tag_id(self.hed_schema84, event_entry, HedKey.HedID) | ||
self.assertTrue("It has changed", issues[0]["message"]) | ||
self.assertTrue("between 10000", issues[0]["message"]) | ||
breakHere = 3 | ||
|
||
event_entry = self.hed_schema84.tags["Event"] | ||
event_entry.attributes[HedKey.HedID] = "HED_XXXXXXX" | ||
self.assertTrue("It must be an integer in the format", issues[0]["message"]) |
This file contains 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
This file contains 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