From fe0d57b4cd8e14e7f63cb082bb0120b49692a7f1 Mon Sep 17 00:00:00 2001 From: IanCa Date: Tue, 9 May 2023 17:43:55 -0500 Subject: [PATCH 1/3] Add Inset tag validation, enable inset spec tests --- hed/errors/error_messages.py | 19 ++++++++++++------- hed/errors/error_types.py | 6 +++--- hed/models/model_constants.py | 5 ++++- hed/validator/onset_validator.py | 10 +++++++--- hed/validator/tag_validator.py | 2 +- spec_tests/hed-specification | 2 +- spec_tests/test_errors.py | 4 +--- tests/validator/test_onset_validator.py | 2 +- 8 files changed, 30 insertions(+), 20 deletions(-) diff --git a/hed/errors/error_messages.py b/hed/errors/error_messages.py index 4c333ff22..95a4f438b 100644 --- a/hed/errors/error_messages.py +++ b/hed/errors/error_messages.py @@ -360,41 +360,46 @@ def def_error_bad_location(tag): return f"Tag '{str(tag)}' is found in a location it is not allowed to be." -@hed_tag_error(OnsetErrors.ONSET_DEF_UNMATCHED, actual_code=ValidationErrors.ONSET_OFFSET_ERROR) +@hed_tag_error(OnsetErrors.ONSET_DEF_UNMATCHED, actual_code=ValidationErrors.ONSET_OFFSET_INSET_ERROR) def onset_error_def_unmatched(tag): return f"The def tag in an onset/offset tag is unmatched. Def tag: '{tag}'" -@hed_tag_error(OnsetErrors.OFFSET_BEFORE_ONSET, actual_code=ValidationErrors.ONSET_OFFSET_ERROR) +@hed_tag_error(OnsetErrors.OFFSET_BEFORE_ONSET, actual_code=ValidationErrors.ONSET_OFFSET_INSET_ERROR) def onset_error_offset_before_onset(tag): return f"Offset tag '{tag}' does not have a matching onset." -@hed_tag_error(OnsetErrors.ONSET_NO_DEF_TAG_FOUND, actual_code=ValidationErrors.ONSET_OFFSET_ERROR) +@hed_tag_error(OnsetErrors.INSET_BEFORE_ONSET, actual_code=ValidationErrors.ONSET_OFFSET_INSET_ERROR) +def onset_error_inset_before_onset(tag): + return f"Inset tag '{tag}' does not have a matching onset." + + +@hed_tag_error(OnsetErrors.ONSET_NO_DEF_TAG_FOUND, actual_code=ValidationErrors.ONSET_OFFSET_INSET_ERROR) def onset_no_def_found(tag): return f"'{tag}' tag has no def or def-expand tag in string." -@hed_tag_error(OnsetErrors.ONSET_TOO_MANY_DEFS, actual_code=ValidationErrors.ONSET_OFFSET_ERROR) +@hed_tag_error(OnsetErrors.ONSET_TOO_MANY_DEFS, actual_code=ValidationErrors.ONSET_OFFSET_INSET_ERROR) def onset_too_many_defs(tag, tag_list): tag_list_strings = [str(tag) for tag in tag_list] return f"Too many def tags found in onset for {tag}. Expected 1, also found: {tag_list_strings}" -@hed_tag_error(OnsetErrors.ONSET_WRONG_NUMBER_GROUPS, actual_code=ValidationErrors.ONSET_OFFSET_ERROR) +@hed_tag_error(OnsetErrors.ONSET_WRONG_NUMBER_GROUPS, actual_code=ValidationErrors.ONSET_OFFSET_INSET_ERROR) def onset_too_many_groups(tag, tag_list): tag_list_strings = [str(a_tag) for a_tag in tag_list] return f"An onset tag should have at most 2 sibling nodes, an offset tag should have 1. " +\ f"Found {len(tag_list_strings)}: {tag_list_strings}" -@hed_tag_error(OnsetErrors.ONSET_TAG_OUTSIDE_OF_GROUP, actual_code=ValidationErrors.ONSET_OFFSET_ERROR) +@hed_tag_error(OnsetErrors.ONSET_TAG_OUTSIDE_OF_GROUP, actual_code=ValidationErrors.ONSET_OFFSET_INSET_ERROR) def onset_wrong_type_tag(tag, def_tag): return f"Onset def tag '{def_tag}' has an improper sibling tag '{tag}'. All onset context tags must be " + \ f"in a single group together." -@hed_tag_error(OnsetErrors.ONSET_PLACEHOLDER_WRONG, actual_code=ValidationErrors.ONSET_OFFSET_ERROR) +@hed_tag_error(OnsetErrors.ONSET_PLACEHOLDER_WRONG, actual_code=ValidationErrors.ONSET_OFFSET_INSET_ERROR) def onset_wrong_placeholder(tag, has_placeholder): if has_placeholder: return f"Onset/offset def tag {tag} expects a placeholder value, but does not have one." diff --git a/hed/errors/error_types.py b/hed/errors/error_types.py index 0e7d42aef..a7be7d2b4 100644 --- a/hed/errors/error_types.py +++ b/hed/errors/error_types.py @@ -28,7 +28,7 @@ class ValidationErrors: DEF_INVALID = "DEF_INVALID" DEFINITION_INVALID = "DEFINITION_INVALID" NODE_NAME_EMPTY = 'NODE_NAME_EMPTY' - ONSET_OFFSET_ERROR = 'ONSET_OFFSET_ERROR' + ONSET_OFFSET_INSET_ERROR = 'ONSET_OFFSET_INSET_ERROR' PARENTHESES_MISMATCH = 'PARENTHESES_MISMATCH' PLACEHOLDER_INVALID = 'PLACEHOLDER_INVALID' REQUIRED_TAG_MISSING = 'REQUIRED_TAG_MISSING' @@ -135,7 +135,7 @@ class DefinitionErrors: class OnsetErrors: - # These are all ONSET_OFFSET_ERROR + # These are all ONSET_OFFSET_INSET_ERROR OFFSET_BEFORE_ONSET = "OFFSET_BEFORE_ONSET" ONSET_DEF_UNMATCHED = "ONSET_DEF_UNMATCHED" ONSET_WRONG_NUMBER_GROUPS = "ONSET_WRONG_NUMBER_GROUPS" @@ -143,7 +143,7 @@ class OnsetErrors: ONSET_PLACEHOLDER_WRONG = "ONSET_PLACEHOLDER_WRONG" ONSET_TOO_MANY_DEFS = "ONSET_TOO_MANY_DEFS" ONSET_TAG_OUTSIDE_OF_GROUP = "ONSET_TAG_OUTSIDE_OF_GROUP" - + INSET_BEFORE_ONSET = "INSET_BEFORE_ONSET" class ColumnErrors: INVALID_COLUMN_REF = "INVALID_COLUMN_REF" diff --git a/hed/models/model_constants.py b/hed/models/model_constants.py index 98cc37091..5fdb54cda 100644 --- a/hed/models/model_constants.py +++ b/hed/models/model_constants.py @@ -13,11 +13,14 @@ class DefTagNames: DEF_KEY = DEF_ORG_KEY.lower() DEF_EXPAND_KEY = DEF_EXPAND_ORG_KEY.lower() DEFINITION_KEY = DEFINITION_ORG_KEY.lower() + DEF_KEYS = (DEF_KEY, DEF_EXPAND_KEY) ONSET_ORG_KEY = "Onset" OFFSET_ORG_KEY = "Offset" + INSET_ORG_KEY = "Inset" ONSET_KEY = ONSET_ORG_KEY.lower() OFFSET_KEY = OFFSET_ORG_KEY.lower() + INSET_KEY = INSET_ORG_KEY.lower() - DEF_KEYS = (DEF_KEY, DEF_EXPAND_KEY) \ No newline at end of file + TEMPORAL_KEYS = {ONSET_KEY, OFFSET_KEY, INSET_KEY} diff --git a/hed/validator/onset_validator.py b/hed/validator/onset_validator.py index 74efef12d..05bf491b9 100644 --- a/hed/validator/onset_validator.py +++ b/hed/validator/onset_validator.py @@ -66,7 +66,7 @@ def validate_onset_offset(self, hed_string_obj): return onset_issues def _find_onset_tags(self, hed_string_obj): - return hed_string_obj.find_top_level_tags(anchor_tags={DefTagNames.ONSET_KEY, DefTagNames.OFFSET_KEY}) + return hed_string_obj.find_top_level_tags(anchor_tags=DefTagNames.TEMPORAL_KEYS) def _handle_onset_or_offset(self, def_tag, onset_offset_tag): is_onset = onset_offset_tag.short_base_tag == DefTagNames.ONSET_ORG_KEY @@ -89,9 +89,13 @@ def _handle_onset_or_offset(self, def_tag, onset_offset_tag): # onset can never fail as it implies an offset self._onsets[full_def_name.lower()] = full_def_name else: + is_offset = onset_offset_tag.short_base_tag == DefTagNames.OFFSET_KEY if full_def_name.lower() not in self._onsets: - return ErrorHandler.format_error(OnsetErrors.OFFSET_BEFORE_ONSET, tag=def_tag) - else: + if is_offset: + return ErrorHandler.format_error(OnsetErrors.OFFSET_BEFORE_ONSET, tag=def_tag) + else: + return ErrorHandler.format_error(OnsetErrors.INSET_BEFORE_ONSET, tag=def_tag) + elif is_offset: del self._onsets[full_def_name.lower()] return [] diff --git a/hed/validator/tag_validator.py b/hed/validator/tag_validator.py index 86d59d46b..bcebcd789 100644 --- a/hed/validator/tag_validator.py +++ b/hed/validator/tag_validator.py @@ -457,7 +457,7 @@ def check_tag_level_issue(self, original_tag_list, is_top_level, is_group): if top_level_tag.short_base_tag == DefTagNames.DEFINITION_ORG_KEY: actual_code = ValidationErrors.DEFINITION_INVALID elif top_level_tag.short_base_tag in {DefTagNames.ONSET_ORG_KEY, DefTagNames.OFFSET_ORG_KEY}: - actual_code = ValidationErrors.ONSET_OFFSET_ERROR + actual_code = ValidationErrors.ONSET_OFFSET_INSET_ERROR if actual_code: validation_issues += ErrorHandler.format_error(ValidationErrors.HED_TOP_LEVEL_TAG, diff --git a/spec_tests/hed-specification b/spec_tests/hed-specification index cc219769e..4909076a4 160000 --- a/spec_tests/hed-specification +++ b/spec_tests/hed-specification @@ -1 +1 @@ -Subproject commit cc219769e43b1882a31473cb3d96ea2054a5a60b +Subproject commit 4909076a416ee9645c8c539d77cdb9750172d154 diff --git a/spec_tests/test_errors.py b/spec_tests/test_errors.py index 80e3c0651..55fee4863 100644 --- a/spec_tests/test_errors.py +++ b/spec_tests/test_errors.py @@ -24,7 +24,7 @@ "DEF_INVALID", "DEFINITION_INVALID", "NODE_NAME_EMPTY", - "ONSET_OFFSET_ERROR", + "ONSET_OFFSET_INSET_ERROR", "PARENTHESES_MISMATCH", "PLACEHOLDER_INVALID", "REQUIRED_TAG_MISSING", @@ -53,8 +53,6 @@ "VERSION_DEPRECATED": "Not applicable", "onset-offset-error-duplicated-onset-or-offset": "TBD how we implement this", "tag-extension-invalid-bad-node-name": "Part of character invalid checking/didn't get to it yet", - "inset-group-has-extras": "Inset tags not in yet", - "inset-outside-its-event": "Inset tags not in yet" } diff --git a/tests/validator/test_onset_validator.py b/tests/validator/test_onset_validator.py index c6908646a..b1acb3962 100644 --- a/tests/validator/test_onset_validator.py +++ b/tests/validator/test_onset_validator.py @@ -263,7 +263,7 @@ def test_onset_multiple_or_misplaced_errors(self): f"({self.placeholder_label_def_string},Onset, Offset)", ] test_issues = [ - self.format_error(ValidationErrors.HED_TOP_LEVEL_TAG, tag=1, actual_error=ValidationErrors.ONSET_OFFSET_ERROR) + self.format_error(ValidationErrors.HED_TOP_LEVEL_TAG, tag=1, actual_error=ValidationErrors.ONSET_OFFSET_INSET_ERROR) + self.format_error(ValidationErrors.HED_TOP_LEVEL_TAG, tag=1), self.format_error(ValidationErrors.HED_MULTIPLE_TOP_TAGS, tag=1, multiple_tags=["Onset"]) + self.format_error(ValidationErrors.HED_TAG_REPEATED, tag=2) From bff1513618fd3bdf3f810a4e3eb12a84d9c5c468 Mon Sep 17 00:00:00 2001 From: IanCa Date: Tue, 9 May 2023 17:59:34 -0500 Subject: [PATCH 2/3] Fix typo --- hed/validator/onset_validator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hed/validator/onset_validator.py b/hed/validator/onset_validator.py index 05bf491b9..8cac74422 100644 --- a/hed/validator/onset_validator.py +++ b/hed/validator/onset_validator.py @@ -89,7 +89,7 @@ def _handle_onset_or_offset(self, def_tag, onset_offset_tag): # onset can never fail as it implies an offset self._onsets[full_def_name.lower()] = full_def_name else: - is_offset = onset_offset_tag.short_base_tag == DefTagNames.OFFSET_KEY + is_offset = onset_offset_tag.short_base_tag == DefTagNames.OFFSET_ORG_KEY if full_def_name.lower() not in self._onsets: if is_offset: return ErrorHandler.format_error(OnsetErrors.OFFSET_BEFORE_ONSET, tag=def_tag) From c8759ae560ff1c38632eb4d2659e143d868c0034 Mon Sep 17 00:00:00 2001 From: IanCa <30812436+IanCa@users.noreply.github.com> Date: Tue, 9 May 2023 18:42:17 -0500 Subject: [PATCH 3/3] Update dependabot.yml --- .github/dependabot.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2234e7061..8f7ecd13c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -16,4 +16,3 @@ updates: interval: "daily" target-branch: "develop" directory: / - automerge: true \ No newline at end of file