diff --git a/hed/errors/error_messages.py b/hed/errors/error_messages.py index c6f4250e4..a8c5dd170 100644 --- a/hed/errors/error_messages.py +++ b/hed/errors/error_messages.py @@ -77,13 +77,13 @@ def val_error_require_child(tag): @hed_error(ValidationErrors.TAG_NOT_UNIQUE) -def val_error_multiple_unique(tag_prefix): - return f"Multiple unique tags with prefix - '{tag_prefix}'" +def val_error_multiple_unique(tag_namespace): + return f"Multiple unique tags with namespace - '{tag_namespace}'" -@hed_tag_error(ValidationErrors.TAG_PREFIX_INVALID) -def val_error_prefix_invalid(tag, tag_prefix): - return f"Prefixes can only contain alpha characters. - '{tag_prefix}'" +@hed_tag_error(ValidationErrors.TAG_NAMESPACE_PREFIX_INVALID) +def val_error_prefix_invalid(tag, tag_namespace): + return f"Prefixes can only contain alpha characters. - '{tag_namespace}'" @hed_tag_error(ValidationErrors.TAG_EXTENSION_INVALID) @@ -146,9 +146,9 @@ def val_error_hed_blank_column(column_number): return f"Column number {column_number} has no column name" -@hed_tag_error(ValidationErrors.HED_LIBRARY_UNMATCHED, actual_code=ValidationErrors.TAG_PREFIX_INVALID) -def val_error_unknown_prefix(tag, unknown_prefix, known_prefixes): - return f"Tag '{tag} has unknown prefix '{unknown_prefix}'. Valid prefixes: {known_prefixes}" +@hed_tag_error(ValidationErrors.HED_LIBRARY_UNMATCHED, actual_code=ValidationErrors.TAG_NAMESPACE_PREFIX_INVALID) +def val_error_unknown_namespace(tag, unknown_prefix, known_prefixes): + return f"Tag '{tag} has unknown namespace '{unknown_prefix}'. Valid prefixes: {known_prefixes}" @hed_tag_error(ValidationErrors.NODE_NAME_EMPTY, has_sub_tag=True) @@ -217,8 +217,8 @@ def val_error_top_level_tags(tag, multiple_tags): @hed_error(ValidationErrors.REQUIRED_TAG_MISSING) -def val_warning_required_prefix_missing(tag_prefix): - return f"Tag with prefix '{tag_prefix}' is required" +def val_warning_required_prefix_missing(tag_namespace): + return f"Tag with namespace '{tag_namespace}' is required" @hed_tag_error(ValidationErrors.STYLE_WARNING, default_severity=ErrorSeverity.WARNING) diff --git a/hed/errors/error_types.py b/hed/errors/error_types.py index 36ef907af..fc3aa3788 100644 --- a/hed/errors/error_types.py +++ b/hed/errors/error_types.py @@ -42,7 +42,7 @@ class ValidationErrors: TAG_GROUP_ERROR = "TAG_GROUP_ERROR" TAG_INVALID = "TAG_INVALID" TAG_NOT_UNIQUE = 'TAG_NOT_UNIQUE' - TAG_PREFIX_INVALID = 'TAG_PREFIX_INVALID' + TAG_NAMESPACE_PREFIX_INVALID = 'TAG_NAMESPACE_PREFIX_INVALID' TAG_REQUIRES_CHILD = 'TAG_REQUIRES_CHILD' TILDES_UNSUPPORTED = 'TILDES_UNSUPPORTED' UNITS_INVALID = 'UNITS_INVALID' diff --git a/hed/models/hed_tag.py b/hed/models/hed_tag.py index d124c338e..0145a46b7 100644 --- a/hed/models/hed_tag.py +++ b/hed/models/hed_tag.py @@ -35,7 +35,7 @@ def __init__(self, hed_string, span=None, hed_schema=None, def_dict=None): # This is not generally used anymore, but you can use it to replace a tag in place. self._tag = None - self._schema_prefix = self._get_schema_prefix(self.org_tag) + self._namespace = self._get_schema_namespace(self.org_tag) # This is the schema this tag was converted to. self._schema = None @@ -68,14 +68,14 @@ def copy(self): return return_copy @property - def schema_prefix(self): - """ Library prefix for this tag if one exists. + def schema_namespace(self): + """ Library namespace for this tag if one exists. Returns: - prefix (str): The library prefix, including the colon. + namespace (str): The library namespace, including the colon. """ - return self._schema_prefix + return self._namespace @property def short_tag(self): @@ -89,7 +89,7 @@ def short_tag(self): """ if self._schema_entry: - return f"{self._schema_prefix}{self._schema_entry.short_tag_name}{self._extension_value}" + return f"{self._namespace}{self._schema_entry.short_tag_name}{self._extension_value}" return str(self) @@ -141,7 +141,7 @@ def short_base_tag(self, new_tag_val): if self._schema: if self.is_takes_value_tag(): new_tag_val = new_tag_val + "/#" - tag_entry = self._schema.get_tag_entry(new_tag_val, schema_prefix=self.schema_prefix) + tag_entry = self._schema.get_tag_entry(new_tag_val, schema_namespace=self.schema_namespace) self._schema_entry = tag_entry else: @@ -246,7 +246,7 @@ def long_tag(self): """ if self._schema_entry: - return f"{self._schema_prefix}{self._schema_entry.long_tag_name}{self._extension_value}" + return f"{self._namespace}{self._schema_entry.long_tag_name}{self._extension_value}" return str(self) @property @@ -336,7 +336,7 @@ def convert_to_canonical_forms(self, hed_schema): list: A list of issues found during conversion. Each element is a dictionary. """ - tag_entry, remainder, tag_issues = hed_schema.find_tag_entry(self, self.schema_prefix) + tag_entry, remainder, tag_issues = hed_schema.find_tag_entry(self, self.schema_namespace) self._schema_entry = tag_entry self._schema = hed_schema if self._schema_entry: @@ -554,14 +554,14 @@ def any_parent_has_attribute(self, attribute): return self._schema_entry.any_parent_has_attribute(attribute=attribute) @staticmethod - def _get_schema_prefix(org_tag): - """ Finds the library prefix for the tag. + def _get_schema_namespace(org_tag): + """ Finds the library namespace for the tag. Parameters: org_tag (str): A string representing a tag. Returns: - str: Library prefix string or empty. + str: Library namespace string or empty. """ first_slash = org_tag.find("/") @@ -633,7 +633,7 @@ def replace_placeholder(self, placeholder_value): def __hash__(self): if self._schema_entry: return hash( - self._schema_prefix + self._schema_entry.short_tag_name.lower() + self._extension_value.lower()) + self._namespace + self._schema_entry.short_tag_name.lower() + self._extension_value.lower()) else: return hash(self.lower()) @@ -667,7 +667,7 @@ def __deepcopy__(self, memo): # copy all other attributes except schema and schema_entry new_tag._tag = copy.deepcopy(self._tag, memo) - new_tag._schema_prefix = copy.deepcopy(self._schema_prefix, memo) + new_tag._namespace = copy.deepcopy(self._namespace, memo) new_tag._extension_value = copy.deepcopy(self._extension_value, memo) new_tag._parent = copy.deepcopy(self._parent, memo) new_tag._expandable = copy.deepcopy(self._expandable, memo) diff --git a/hed/schema/hed_schema.py b/hed/schema/hed_schema.py index bcd93be8b..587e060b0 100644 --- a/hed/schema/hed_schema.py +++ b/hed/schema/hed_schema.py @@ -27,8 +27,8 @@ def __init__(self): self.epilogue = "" self._is_hed3_schema = None - # This is the specified library name_prefix - tags will be {schema_prefix}:{tag_name} - self._schema_prefix = "" + # This is the specified library name_prefix - tags will be {schema_namespace}:{tag_name} + self._namespace = "" self._sections = self._create_empty_sections() @@ -46,16 +46,16 @@ def version(self): return self.header_attributes['version'] def get_formatted_version(self, as_string=False): - """ The HED version string including prefix and library name if any of this schema. + """ The HED version string including namespace and library name if any of this schema. Returns: - str: The complete version of this schema including library name and prefix. + str: The complete version of this schema including library name and namespace. """ library = self.library if library: library = library + '_' - return self._schema_prefix + library + self.version + return self._namespace + library + self.version @property def library(self): @@ -104,11 +104,11 @@ def get_save_header_attributes(self, save_merged=False): return header_attributes - def schema_for_prefix(self, prefix): - """ Return HedSchema object for this prefix. + def schema_for_namespace(self, namespace): + """ Return HedSchema object for this namespace. Parameters: - prefix (str): The schema library name prefix. + namespace (str): The schema library name namespace. Returns: HedSchema: The HED schema object for this schema. @@ -117,7 +117,7 @@ def schema_for_prefix(self, prefix): -This is mostly a placeholder for HedSchemaGroup and may be refactored out later. """ - if self._schema_prefix != prefix: + if self._namespace != namespace: return None return self @@ -131,7 +131,7 @@ def valid_prefixes(self): Notes: - The return value is always length 1 if using a HedSchema. """ - return [self._schema_prefix] + return [self._namespace] # =============================================== # Creation and saving functions @@ -210,17 +210,17 @@ def save_as_xml(self, filename=None, save_merged=True): return filename return local_xml_file - def set_schema_prefix(self, schema_prefix): - """ Set library prefix associated for this schema. + def set_schema_prefix(self, schema_namespace): + """ Set library namespace associated for this schema. Parameters: - schema_prefix (str): Should be empty, or end with a colon.(Colon will be automated added if missing). + schema_namespace (str): Should be empty, or end with a colon.(Colon will be automated added if missing). """ - if schema_prefix and schema_prefix[-1] != ":": - schema_prefix += ":" + if schema_namespace and schema_namespace[-1] != ":": + schema_namespace += ":" - self._schema_prefix = schema_prefix + self._namespace = schema_namespace def check_compliance(self, check_for_warnings=True, name=None, error_handler=None): """ Check for HED3 compliance of this schema. @@ -387,7 +387,7 @@ def __eq__(self, other): # s = f"{key} unmatched: '{str(dict1[key].name)}' vs '{str(dict2[key].name)}'" # print(s) return False - if self._schema_prefix != other._schema_prefix: + if self._namespace != other._namespace: return False return True @@ -424,27 +424,27 @@ def get_tags_with_attribute(self, key, section_key=HedSectionKey.AllTags): """ return self._sections[section_key].get_entries_with_attribute(key, return_name_only=True, - schema_prefix=self._schema_prefix) + schema_namespace=self._namespace) - def get_tag_entry(self, name, key_class=HedSectionKey.AllTags, schema_prefix=""): + def get_tag_entry(self, name, key_class=HedSectionKey.AllTags, schema_namespace=""): """ Return the schema entry for this tag, if one exists. Parameters: name (str): Any form of basic tag(or other section entry) to look up. This will not handle extensions or similar. - If this is a tag, it can have a schema prefix, but it's not required + If this is a tag, it can have a schema namespace, but it's not required key_class (HedSectionKey or str): The type of entry to return. - schema_prefix (str): Only used on AllTags. If incorrect, will return None. + schema_namespace (str): Only used on AllTags. If incorrect, will return None. Returns: HedSchemaEntry: The schema entry for the given tag. """ if key_class == HedSectionKey.AllTags: - if schema_prefix != self._schema_prefix: + if schema_namespace != self._namespace: return None - if name.startswith(self._schema_prefix): - name = name[len(self._schema_prefix):] + if name.startswith(self._namespace): + name = name[len(self._namespace):] return self._get_tag_entry(name, key_class) @@ -462,14 +462,14 @@ def _get_tag_entry(self, name, key_class=HedSectionKey.AllTags): """ return self._sections[key_class].get(name) - def find_tag_entry(self, tag, schema_prefix=""): + def find_tag_entry(self, tag, schema_namespace=""): """ Find the schema entry for a given source tag. - Note: Will not identify tags if schema_prefix is set incorrectly + Note: Will not identify tags if schema_namespace is set incorrectly Parameters: tag (str, HedTag): Any form of tag to look up. Can have an extension, value, etc. - schema_prefix (str): The schema prefix of the tag, if any. + schema_namespace (str): The schema namespace of the tag, if any. Returns: HedTagEntry: The located tag entry for this tag. @@ -480,18 +480,18 @@ def find_tag_entry(self, tag, schema_prefix=""): Works left to right (which is mostly relevant for errors). """ - if schema_prefix != self._schema_prefix: + if schema_namespace != self._namespace: validation_issues = ErrorHandler.format_error(ValidationErrors.HED_LIBRARY_UNMATCHED, tag, - schema_prefix, self.valid_prefixes) + schema_namespace, self.valid_prefixes) return None, None, validation_issues - return self._find_tag_entry(tag, schema_prefix) + return self._find_tag_entry(tag, schema_namespace) - def _find_tag_entry(self, tag, schema_prefix=""): + def _find_tag_entry(self, tag, schema_namespace=""): """ Find the schema entry for a given source tag. Parameters: tag (str, HedTag): Any form of tag to look up. Can have an extension, value, etc. - schema_prefix (str): The schema prefix of the tag, if any. + schema_namespace (str): The schema namespace of the tag, if any. Returns: HedTagEntry: The located tag entry for this tag. @@ -503,9 +503,9 @@ def _find_tag_entry(self, tag, schema_prefix=""): """ clean_tag = str(tag) - prefix = schema_prefix - clean_tag = clean_tag[len(prefix):] - prefix_tag_adj = len(prefix) + namespace = schema_namespace + clean_tag = clean_tag[len(namespace):] + prefix_tag_adj = len(namespace) working_tag = clean_tag.lower() # Most tags are in the schema directly, so test that first diff --git a/hed/schema/hed_schema_group.py b/hed/schema/hed_schema_group.py index 45a57f853..780c5d7fd 100644 --- a/hed/schema/hed_schema_group.py +++ b/hed/schema/hed_schema_group.py @@ -33,12 +33,12 @@ def __init__(self, schema_list): if len(schema_list) == 0: raise HedFileError(HedExceptions.BAD_PARAMETERS, "Empty list passed to HedSchemaGroup constructor.", filename="Combined Schema") - schema_prefixes = [hed_schema._schema_prefix for hed_schema in schema_list] + schema_prefixes = [hed_schema._namespace for hed_schema in schema_list] if len(set(schema_prefixes)) != len(schema_prefixes): raise HedFileError(HedExceptions.SCHEMA_DUPLICATE_PREFIX, "Multiple schema share the same tag name_prefix. This is not allowed.", filename="Combined Schema") - self._schemas = {hed_schema._schema_prefix: hed_schema for hed_schema in schema_list} + self._schemas = {hed_schema._namespace: hed_schema for hed_schema in schema_list} # =============================================== # General schema properties/functions @@ -87,17 +87,17 @@ def value_classes(self): def __eq__(self, other): return self._schemas == other._schemas - def schema_for_prefix(self, prefix): - """ Return the HedSchema for the library prefix. + def schema_for_namespace(self, namespace): + """ Return the HedSchema for the library namespace. Parameters: - prefix (str): A schema library name prefix. + namespace (str): A schema library name namespace. Returns: - HedSchema or None: The specific schema for this library name prefix if exists. + HedSchema or None: The specific schema for this library name namespace if exists. """ - schema = self._schemas.get(prefix) + schema = self._schemas.get(namespace) return schema @property @@ -142,14 +142,14 @@ def get_tags_with_attribute(self, key): all_tags.update(schema.get_tags_with_attribute(key)) return all_tags - # todo: maybe tweak this API so you don't have to pass in library prefix? - def get_tag_entry(self, name, key_class=HedSectionKey.AllTags, schema_prefix=""): + # todo: maybe tweak this API so you don't have to pass in library namespace? + def get_tag_entry(self, name, key_class=HedSectionKey.AllTags, schema_namespace=""): """ Return the schema entry for this tag, if one exists. Parameters: name (str): Any form of basic tag(or other section entry) to look up. key_class (HedSectionKey): The tag section to search. - schema_prefix (str or None): An optional prefix associated with this tag. + schema_namespace (str or None): An optional namespace associated with this tag. Returns: HedSchemaEntry: The schema entry for the given tag. @@ -158,18 +158,18 @@ def get_tag_entry(self, name, key_class=HedSectionKey.AllTags, schema_prefix="") - This will not handle extensions or similar. """ - specific_schema = self.schema_for_prefix(schema_prefix) + specific_schema = self.schema_for_namespace(schema_namespace) if not specific_schema: return None - return specific_schema.get_tag_entry(name, key_class, schema_prefix) + return specific_schema.get_tag_entry(name, key_class, schema_namespace) - def find_tag_entry(self, tag, schema_prefix=""): + def find_tag_entry(self, tag, schema_namespace=""): """ Find a schema entry for a source tag. Parameters: tag (str or HedTag): Any form of tag to look up. Can have an extension, value, etc. - schema_prefix (str): The prefix the library, if any. + schema_namespace (str): The namespace the library, if any. Returns: tuple: @@ -181,10 +181,10 @@ def find_tag_entry(self, tag, schema_prefix=""): - Works right to left.(mostly relevant for errors). """ - specific_schema = self.schema_for_prefix(schema_prefix) + specific_schema = self.schema_for_namespace(schema_namespace) if not specific_schema: validation_issues = ErrorHandler.format_error(ValidationErrors.HED_LIBRARY_UNMATCHED, tag, - schema_prefix, self.valid_prefixes) + schema_namespace, self.valid_prefixes) return None, None, validation_issues - return specific_schema._find_tag_entry(tag, schema_prefix) + return specific_schema._find_tag_entry(tag, schema_namespace) diff --git a/hed/schema/hed_schema_io.py b/hed/schema/hed_schema_io.py index 3f022d483..e274e9e39 100644 --- a/hed/schema/hed_schema_io.py +++ b/hed/schema/hed_schema_io.py @@ -11,13 +11,13 @@ from hed.schema.schema_validation_util import validate_version_string -def from_string(schema_string, file_type=".xml", schema_prefix=None): +def from_string(schema_string, file_type=".xml", schema_namespace=None): """ Create a schema from the given string. Parameters: schema_string (str): An XML or mediawiki file as a single long string. file_type (str): The extension(including the .) corresponding to a file source. - schema_prefix (str, None): The name_prefix all tags in this schema will accept. + schema_namespace (str, None): The name_prefix all tags in this schema will accept. Returns: (HedSchema): The loaded schema. @@ -40,8 +40,8 @@ def from_string(schema_string, file_type=".xml", schema_prefix=None): else: raise HedFileError(HedExceptions.INVALID_EXTENSION, "Unknown schema extension", filename=file_type) - if schema_prefix: - hed_schema.set_schema_prefix(schema_prefix=schema_prefix) + if schema_namespace: + hed_schema.set_schema_prefix(schema_namespace=schema_namespace) return hed_schema @@ -68,12 +68,12 @@ def get_schema_versions(hed_schema, as_string=True): raise ValueError("InvalidHedSchemaOrHedSchemaGroup", "Expected schema or schema group") -def load_schema(hed_path=None, schema_prefix=None): +def load_schema(hed_path=None, schema_namespace=None): """ Load a schema from the given file or URL path. Parameters: hed_path (str or None): A filepath or url to open a schema from. - schema_prefix (str or None): The name_prefix all tags in this schema will accept. + schema_namespace (str or None): The name_prefix all tags in this schema will accept. Returns: HedSchema: The loaded schema. @@ -98,8 +98,8 @@ def load_schema(hed_path=None, schema_prefix=None): else: raise HedFileError(HedExceptions.INVALID_EXTENSION, "Unknown schema extension", filename=hed_path) - if schema_prefix: - hed_schema.set_schema_prefix(schema_prefix=schema_prefix) + if schema_namespace: + hed_schema.set_schema_prefix(schema_namespace=schema_namespace) return hed_schema @@ -124,7 +124,7 @@ def _load_schema_version(xml_version=None, xml_folder=None): Parameters: xml_folder (str): Path to a folder containing schema. - xml_version (str or list): HED version format string. Expected format: '[schema_prefix:][library_name_]X.Y.Z'. + xml_version (str or list): HED version format string. Expected format: '[schema_namespace:][library_name_]X.Y.Z'. Returns: HedSchema or HedSchemaGroup: The requested HedSchema object. @@ -135,11 +135,11 @@ def _load_schema_version(xml_version=None, xml_folder=None): Notes: - The library schema files have names of the form HED_(LIBRARY_NAME)_(version).xml. """ - schema_prefix = "" + schema_namespace = "" library_name = None if xml_version: if ":" in xml_version: - schema_prefix, _, xml_version = xml_version.partition(":") + schema_namespace, _, xml_version = xml_version.partition(":") if "_" in xml_version: library_name, _, xml_version = xml_version.rpartition("_") elif validate_version_string(xml_version): @@ -161,8 +161,8 @@ def _load_schema_version(xml_version=None, xml_folder=None): else: raise e - if schema_prefix: - hed_schema.set_schema_prefix(schema_prefix=schema_prefix) + if schema_namespace: + hed_schema.set_schema_prefix(schema_namespace=schema_namespace) return hed_schema diff --git a/hed/schema/hed_schema_section.py b/hed/schema/hed_schema_section.py index c0cf21cfc..9c7dbd9fd 100644 --- a/hed/schema/hed_schema_section.py +++ b/hed/schema/hed_schema_section.py @@ -74,13 +74,13 @@ def _add_to_dict(self, name, new_entry, parent_index=None): self.all_entries.insert(parent_index, new_entry) return return_entry - def get_entries_with_attribute(self, attribute_name, return_name_only=False, schema_prefix=""): + def get_entries_with_attribute(self, attribute_name, return_name_only=False, schema_namespace=""): """ Return entries or names with given attribute. Parameters: attribute_name (str): The name of the attribute(generally a HedKey entry). return_name_only (bool): If true, return the name as a string rather than the tag entry. - schema_prefix (str): Prepends given prefix to each name if returning names. + schema_namespace (str): Prepends given namespace to each name if returning names. Returns: list: List of HedSchemaEntry or strings representing the names. @@ -92,7 +92,7 @@ def get_entries_with_attribute(self, attribute_name, return_name_only=False, sch cache_val = self._attribute_cache[attribute_name] if return_name_only: - return [f"{schema_prefix}{tag_entry.name}" for tag_entry in cache_val] + return [f"{schema_namespace}{tag_entry.name}" for tag_entry in cache_val] return cache_val # =============================================== @@ -212,8 +212,6 @@ def _check_if_duplicate(self, name, new_entry): return new_entry def _add_to_dict(self, name, new_entry, parent_index=None): - if new_entry.has_attribute(HedKey.Rooted): - del new_entry.attributes[HedKey.Rooted] if new_entry.has_attribute(HedKey.InLibrary): parent_name = new_entry.parent_name if parent_name.lower() in self: diff --git a/hed/schema/schema_io/schema2base.py b/hed/schema/schema_io/schema2base.py index d7c717476..7ed8aceaf 100644 --- a/hed/schema/schema_io/schema2base.py +++ b/hed/schema/schema_io/schema2base.py @@ -92,8 +92,6 @@ def _output_tags(self, all_tags): not tag_entry.parent.has_attribute(HedKey.InLibrary) and not self._save_merged: if tag_entry.parent.name not in all_nodes: level_adj = level - tag_entry = copy.deepcopy(tag_entry) - tag_entry.attributes[HedKey.Rooted] = tag_entry.parent.short_tag_name parent_node = all_nodes.get(tag_entry.parent_name, schema_node) child_node = self._write_tag_entry(tag_entry, parent_node, level - level_adj) diff --git a/hed/schema/schema_validation_util.py b/hed/schema/schema_validation_util.py index e6de68e3d..a1fe1d356 100644 --- a/hed/schema/schema_validation_util.py +++ b/hed/schema/schema_validation_util.py @@ -121,25 +121,29 @@ def find_rooted_entry(tag_entry, schema, loading_merged): raise HedFileError(HedExceptions.ROOTED_TAG_INVALID, f"Rooted tag attribute found on '{tag_entry.short_tag_name}' in a standard schema.", schema.filename) - if loading_merged: - raise HedFileError(HedExceptions.ROOTED_TAG_INVALID, - f'Found rooted tag \'{tag_entry.short_tag_name}\' in schema without unmerged="True"', - schema.filename) if not isinstance(rooted_tag, str): raise HedFileError(HedExceptions.ROOTED_TAG_INVALID, f'Rooted tag \'{tag_entry.short_tag_name}\' is not a string."', schema.filename) - if tag_entry.parent_name: + if tag_entry.parent_name and not loading_merged: raise HedFileError(HedExceptions.ROOTED_TAG_INVALID, f'Found rooted tag \'{tag_entry.short_tag_name}\' as a non root node.', schema.filename) + if not tag_entry.parent_name and loading_merged: + raise HedFileError(HedExceptions.ROOTED_TAG_INVALID, + f'Found rooted tag \'{tag_entry.short_tag_name}\' as a root node in a merged schema.', + schema.filename) + rooted_entry = schema.all_tags.get(rooted_tag) if not rooted_entry or rooted_entry.has_attribute(constants.HedKey.InLibrary): raise HedFileError(HedExceptions.ROOTED_TAG_DOES_NOT_EXIST, f"Rooted tag '{tag_entry.short_tag_name}' not found in paired standard schema", schema.filename) + if loading_merged: + return None + return rooted_entry diff --git a/hed/validator/tag_validator.py b/hed/validator/tag_validator.py index bcebcd789..9986c6766 100644 --- a/hed/validator/tag_validator.py +++ b/hed/validator/tag_validator.py @@ -488,7 +488,7 @@ def check_for_required_tags(self, tags): for required_prefix in required_prefixes: if not any(tag.long_tag.lower().startswith(required_prefix.lower()) for tag in tags): validation_issues += ErrorHandler.format_error(ValidationErrors.REQUIRED_TAG_MISSING, - tag_prefix=required_prefix) + tag_namespace=required_prefix) return validation_issues def check_multiple_unique_tags_exist(self, tags): @@ -509,19 +509,19 @@ def check_multiple_unique_tags_exist(self, tags): unique_tag_prefix_bool_mask = [x.long_tag.lower().startswith(unique_prefix.lower()) for x in tags] if sum(unique_tag_prefix_bool_mask) > 1: validation_issues += ErrorHandler.format_error(ValidationErrors.TAG_NOT_UNIQUE, - tag_prefix=unique_prefix) + tag_namespace=unique_prefix) return validation_issues # ========================================================================== # Private utility functions # =========================================================================+ def _check_invalid_prefix_issues(self, original_tag): - """Check for invalid schema prefix.""" + """Check for invalid schema namespace.""" issues = [] - schema_prefix = original_tag.schema_prefix - if schema_prefix and not schema_prefix[:-1].isalpha(): - issues += ErrorHandler.format_error(ValidationErrors.TAG_PREFIX_INVALID, - tag=original_tag, tag_prefix=schema_prefix) + schema_namespace = original_tag.schema_namespace + if schema_namespace and not schema_namespace[:-1].isalpha(): + issues += ErrorHandler.format_error(ValidationErrors.TAG_NAMESPACE_PREFIX_INVALID, + tag=original_tag, tag_namespace=schema_namespace) return issues def _validate_value_class_portion(self, original_tag, portion_to_validate): diff --git a/spec_tests/hed-specification b/spec_tests/hed-specification index d7d174fde..33f48d286 160000 --- a/spec_tests/hed-specification +++ b/spec_tests/hed-specification @@ -1 +1 @@ -Subproject commit d7d174fde455b42c0c0a0534b3566f76fac53496 +Subproject commit 33f48d286ea3cb69e8e1c77a9b10379d676c6af8 diff --git a/spec_tests/test_errors.py b/spec_tests/test_errors.py index 55fee4863..3c2793d94 100644 --- a/spec_tests/test_errors.py +++ b/spec_tests/test_errors.py @@ -38,7 +38,7 @@ "TAG_GROUP_ERROR", "TAG_INVALID", "TAG_NOT_UNIQUE", - "TAG_PREFIX_INVALID", + "TAG_NAMESPACE_PREFIX_INVALID", "TAG_REQUIRES_CHILD", "TILDES_UNSUPPORTED", "UNITS_INVALID", @@ -51,7 +51,7 @@ skip_tests = { "VERSION_DEPRECATED": "Not applicable", - "onset-offset-error-duplicated-onset-or-offset": "TBD how we implement this", + "onset-offset-inset-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", } diff --git a/tests/schema/test_hed_schema.py b/tests/schema/test_hed_schema.py index 15deaffdd..f7a5c29c2 100644 --- a/tests/schema/test_hed_schema.py +++ b/tests/schema/test_hed_schema.py @@ -20,7 +20,7 @@ def setUpClass(cls): schema_file = '../data/validator_tests/HED8.0.0_added_tests.mediawiki' hed_xml = os.path.join(os.path.dirname(os.path.realpath(__file__)), schema_file) hed_schema1 = load_schema(hed_xml) - hed_schema2 = load_schema(hed_xml, schema_prefix="tl:") + hed_schema2 = load_schema(hed_xml, schema_namespace="tl:") cls.hed_schema_group = HedSchemaGroup([hed_schema1, hed_schema2]) def test_name(self): @@ -156,19 +156,19 @@ def test_bad_prefixes(self): self.assertFalse(schema.get_tag_entry("sc:Event")) self.assertFalse(schema.get_tag_entry("unknown:Event")) self.assertFalse(schema.get_tag_entry(":Event")) - self.assertFalse(schema.get_tag_entry("Event", schema_prefix=None)) - self.assertTrue(schema.get_tag_entry("Event", schema_prefix='')) - self.assertFalse(schema.get_tag_entry("Event", schema_prefix='unknown')) + self.assertFalse(schema.get_tag_entry("Event", schema_namespace=None)) + self.assertTrue(schema.get_tag_entry("Event", schema_namespace='')) + self.assertFalse(schema.get_tag_entry("Event", schema_namespace='unknown')) def test_bad_prefixes_library(self): schema = load_schema_version(xml_version="tl:8.0.0") - self.assertTrue(schema.get_tag_entry("tl:Event", schema_prefix="tl:")) - self.assertFalse(schema.get_tag_entry("sc:Event", schema_prefix="tl:")) - self.assertTrue(schema.get_tag_entry("Event", schema_prefix="tl:")) - self.assertFalse(schema.get_tag_entry("unknown:Event", schema_prefix="tl:")) - self.assertFalse(schema.get_tag_entry(":Event", schema_prefix="tl:")) - self.assertFalse(schema.get_tag_entry("Event", schema_prefix=None)) - self.assertFalse(schema.get_tag_entry("Event", schema_prefix='')) - self.assertFalse(schema.get_tag_entry("Event", schema_prefix='unknown')) + self.assertTrue(schema.get_tag_entry("tl:Event", schema_namespace="tl:")) + self.assertFalse(schema.get_tag_entry("sc:Event", schema_namespace="tl:")) + self.assertTrue(schema.get_tag_entry("Event", schema_namespace="tl:")) + self.assertFalse(schema.get_tag_entry("unknown:Event", schema_namespace="tl:")) + self.assertFalse(schema.get_tag_entry(":Event", schema_namespace="tl:")) + self.assertFalse(schema.get_tag_entry("Event", schema_namespace=None)) + self.assertFalse(schema.get_tag_entry("Event", schema_namespace='')) + self.assertFalse(schema.get_tag_entry("Event", schema_namespace='unknown')) diff --git a/tests/schema/test_hed_schema_group.py b/tests/schema/test_hed_schema_group.py index 1f808133c..891dfc2b1 100644 --- a/tests/schema/test_hed_schema_group.py +++ b/tests/schema/test_hed_schema_group.py @@ -10,7 +10,7 @@ def setUpClass(cls): schema_file = '../data/validator_tests/HED8.0.0_added_tests.mediawiki' hed_xml = os.path.join(os.path.dirname(os.path.realpath(__file__)), schema_file) hed_schema1 = load_schema(hed_xml) - hed_schema2 = load_schema(hed_xml, schema_prefix="tl:") + hed_schema2 = load_schema(hed_xml, schema_namespace="tl:") cls.hed_schema_group = HedSchemaGroup([hed_schema1, hed_schema2]) def test_schema_compliance(self): @@ -18,7 +18,7 @@ def test_schema_compliance(self): self.assertEqual(len(warnings), 10) def test_get_tag_entry(self): - tag_entry = self.hed_schema_group.get_tag_entry("Event", schema_prefix="tl:") + tag_entry = self.hed_schema_group.get_tag_entry("Event", schema_namespace="tl:") self.assertTrue(tag_entry) def test_bad_prefixes(self): @@ -29,11 +29,11 @@ def test_bad_prefixes(self): self.assertFalse(schema.get_tag_entry("unknown:Event")) self.assertFalse(schema.get_tag_entry(":Event")) - self.assertTrue(schema.get_tag_entry("tl:Event", schema_prefix="tl:")) - self.assertFalse(schema.get_tag_entry("sc:Event", schema_prefix="tl:")) - self.assertTrue(schema.get_tag_entry("Event", schema_prefix="tl:")) - self.assertFalse(schema.get_tag_entry("unknown:Event", schema_prefix="tl:")) - self.assertFalse(schema.get_tag_entry(":Event", schema_prefix="tl:")) + self.assertTrue(schema.get_tag_entry("tl:Event", schema_namespace="tl:")) + self.assertFalse(schema.get_tag_entry("sc:Event", schema_namespace="tl:")) + self.assertTrue(schema.get_tag_entry("Event", schema_namespace="tl:")) + self.assertFalse(schema.get_tag_entry("unknown:Event", schema_namespace="tl:")) + self.assertFalse(schema.get_tag_entry(":Event", schema_namespace="tl:")) - self.assertFalse(schema.get_tag_entry("Event", schema_prefix=None)) - self.assertTrue(schema.get_tag_entry("Event", schema_prefix="")) + self.assertFalse(schema.get_tag_entry("Event", schema_namespace=None)) + self.assertTrue(schema.get_tag_entry("Event", schema_namespace="")) diff --git a/tests/schema/test_hed_schema_io.py b/tests/schema/test_hed_schema_io.py index 5511c7cd3..62b00fcce 100644 --- a/tests/schema/test_hed_schema_io.py +++ b/tests/schema/test_hed_schema_io.py @@ -46,12 +46,12 @@ def test_load_schema_version_tags(self): self.assertEqual(schema, schema2) score_lib = load_schema_version(xml_version="score_1.0.0") - self.assertEqual(score_lib._schema_prefix, "") + self.assertEqual(score_lib._namespace, "") self.assertTrue(score_lib.get_tag_entry("Modulator")) score_lib = load_schema_version(xml_version="sc:score_1.0.0") - self.assertEqual(score_lib._schema_prefix, "sc:") - self.assertTrue(score_lib.get_tag_entry("Modulator", schema_prefix="sc:")) + self.assertEqual(score_lib._namespace, "sc:") + self.assertTrue(score_lib.get_tag_entry("Modulator", schema_namespace="sc:")) def test_load_schema_version(self): ver1 = "8.0.0" @@ -61,67 +61,67 @@ def test_load_schema_version(self): self.assertEqual(schemas1.library, "", "load_schema_version standard schema has no library") ver2 = "base:8.0.0" schemas2 = load_schema_version(ver2) - self.assertIsInstance(schemas2, HedSchema, "load_schema_version returns HedSchema version+prefix") - self.assertEqual(schemas2.version, "8.0.0", "load_schema_version has the right version with prefix") - self.assertEqual(schemas2._schema_prefix, "base:", "load_schema_version has the right version with prefix") + self.assertIsInstance(schemas2, HedSchema, "load_schema_version returns HedSchema version+namespace") + self.assertEqual(schemas2.version, "8.0.0", "load_schema_version has the right version with namespace") + self.assertEqual(schemas2._namespace, "base:", "load_schema_version has the right version with namespace") ver3 = ["base:8.0.0"] schemas3 = load_schema_version(ver3) - self.assertIsInstance(schemas3, HedSchema, "load_schema_version returns HedSchema version+prefix") - self.assertEqual(schemas3.version, "8.0.0", "load_schema_version has the right version with prefix") - self.assertEqual(schemas3._schema_prefix, "base:", "load_schema_version has the right version with prefix") + self.assertIsInstance(schemas3, HedSchema, "load_schema_version returns HedSchema version+namespace") + self.assertEqual(schemas3.version, "8.0.0", "load_schema_version has the right version with namespace") + self.assertEqual(schemas3._namespace, "base:", "load_schema_version has the right version with namespace") ver3 = ["base:"] schemas3 = load_schema_version(ver3) - self.assertIsInstance(schemas3, HedSchema, "load_schema_version returns HedSchema version+prefix") - self.assertTrue(schemas3.version, "load_schema_version has the right version with prefix") - self.assertEqual(schemas3._schema_prefix, "base:", "load_schema_version has the right version with prefix") + self.assertIsInstance(schemas3, HedSchema, "load_schema_version returns HedSchema version+namespace") + self.assertTrue(schemas3.version, "load_schema_version has the right version with namespace") + self.assertEqual(schemas3._namespace, "base:", "load_schema_version has the right version with namespace") def test_load_schema_version_libraries(self): ver1 = "score_1.0.0" schemas1 = load_schema_version(ver1) self.assertIsInstance(schemas1, HedSchema, "load_schema_version returns a HedSchema if a string version") self.assertEqual(schemas1.version, "1.0.0", "load_schema_version has the right version") - self.assertEqual(schemas1.library, "score", "load_schema_version works with single library no prefix") + self.assertEqual(schemas1.library, "score", "load_schema_version works with single library no namespace") self.assertEqual(schemas1.get_formatted_version(), "score_1.0.0", - "load_schema_version gives correct version_string with single library no prefix") + "load_schema_version gives correct version_string with single library no namespace") ver1 = "score_" schemas1 = load_schema_version(ver1) self.assertIsInstance(schemas1, HedSchema, "load_schema_version returns a HedSchema if a string version") self.assertTrue(schemas1.version, "load_schema_version has the right version") - self.assertEqual(schemas1.library, "score", "load_schema_version works with single library no prefix") + self.assertEqual(schemas1.library, "score", "load_schema_version works with single library no namespace") ver1 = "score" schemas1 = load_schema_version(ver1) self.assertIsInstance(schemas1, HedSchema, "load_schema_version returns a HedSchema if a string version") self.assertTrue(schemas1.version, "load_schema_version has the right version") - self.assertEqual(schemas1.library, "score", "load_schema_version works with single library no prefix") + self.assertEqual(schemas1.library, "score", "load_schema_version works with single library no namespace") ver2 = "base:score_1.0.0" schemas2 = load_schema_version(ver2) - self.assertIsInstance(schemas2, HedSchema, "load_schema_version returns HedSchema version+prefix") - self.assertEqual(schemas2.version, "1.0.0", "load_schema_version has the right version with prefix") - self.assertEqual(schemas2._schema_prefix, "base:", "load_schema_version has the right version with prefix") + self.assertIsInstance(schemas2, HedSchema, "load_schema_version returns HedSchema version+namespace") + self.assertEqual(schemas2.version, "1.0.0", "load_schema_version has the right version with namespace") + self.assertEqual(schemas2._namespace, "base:", "load_schema_version has the right version with namespace") self.assertEqual(schemas2.get_formatted_version(as_string=True), "base:score_1.0.0", - "load_schema_version gives correct version_string with single library with prefix") + "load_schema_version gives correct version_string with single library with namespace") ver3 = ["8.0.0", "sc:score_1.0.0"] schemas3 = load_schema_version(ver3) - self.assertIsInstance(schemas3, HedSchemaGroup, "load_schema_version returns HedSchema version+prefix") + self.assertIsInstance(schemas3, HedSchemaGroup, "load_schema_version returns HedSchema version+namespace") self.assertIsInstance(schemas3._schemas, dict, "load_schema_version group keeps dictionary of hed versions") self.assertEqual(len(schemas3._schemas), 2, "load_schema_version group dictionary is right length") s = schemas3._schemas[""] - self.assertEqual(s.version, "8.0.0", "load_schema_version has the right version with prefix") + self.assertEqual(s.version, "8.0.0", "load_schema_version has the right version with namespace") self.assertEqual(schemas3.get_formatted_version(as_string=True), '["8.0.0", "sc:score_1.0.0"]', - "load_schema_version gives correct version_string with single library with prefix") + "load_schema_version gives correct version_string with single library with namespace") formatted_list = schemas3.get_formatted_version(as_string=False) self.assertEqual(len(formatted_list), 2, - "load_schema_version gives correct version_string with single library with prefix") + "load_schema_version gives correct version_string with single library with namespace") ver4 = ["ts:8.0.0", "sc:score_1.0.0"] schemas4 = load_schema_version(ver4) - self.assertIsInstance(schemas4, HedSchemaGroup, "load_schema_version returns HedSchema version+prefix") + self.assertIsInstance(schemas4, HedSchemaGroup, "load_schema_version returns HedSchema version+namespace") self.assertIsInstance(schemas4._schemas, dict, "load_schema_version group keeps dictionary of hed versions") self.assertEqual(len(schemas4._schemas), 2, "load_schema_version group dictionary is right length") self.assertEqual(schemas4.get_formatted_version(), '["ts:8.0.0", "sc:score_1.0.0"]', "load_schema_version gives correct version_string with multiple prefixes") s = schemas4._schemas["ts:"] - self.assertEqual(s.version, "8.0.0", "load_schema_version has the right version with prefix") + self.assertEqual(s.version, "8.0.0", "load_schema_version has the right version with namespace") with self.assertRaises(KeyError) as context: schemas4._schemas[""] self.assertEqual(context.exception.args[0], '') @@ -321,4 +321,5 @@ def test_cannot_load_schemas(self): ] for file in files: with self.assertRaises(HedFileError): + # print(file) load_schema(file) diff --git a/tests/schema/test_schema_converters.py b/tests/schema/test_schema_converters.py index 1b2a335ae..e2e1eb465 100644 --- a/tests/schema/test_schema_converters.py +++ b/tests/schema/test_schema_converters.py @@ -173,7 +173,7 @@ class TestConverterSavingPrefix(unittest.TestCase): def setUpClass(cls): cls.xml_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), cls.xml_file) cls.hed_schema_xml = schema.load_schema(cls.xml_file) - cls.hed_schema_xml_prefix = schema.load_schema(cls.xml_file, schema_prefix="tl:") + cls.hed_schema_xml_prefix = schema.load_schema(cls.xml_file, schema_namespace="tl:") def test_saving_prefix(self): saved_filename = self.hed_schema_xml_prefix.save_as_xml() diff --git a/tests/tools/bids/test_bids_dataset.py b/tests/tools/bids/test_bids_dataset.py index 6289be314..e4af39331 100644 --- a/tests/tools/bids/test_bids_dataset.py +++ b/tests/tools/bids/test_bids_dataset.py @@ -88,8 +88,8 @@ def test_with_schema_group(self): library2_url = "https://raw.githubusercontent.com/hed-standard/hed-schemas/main/" + \ "library_schemas/testlib/hedxml/HED_testlib_1.0.2.xml" schema_list = [load_schema_version(xml_version=base_version)] - schema_list.append(load_schema(library1_url, schema_prefix="sc")) - schema_list.append(load_schema(library2_url, schema_prefix="test")) + schema_list.append(load_schema(library1_url, schema_namespace="sc")) + schema_list.append(load_schema(library2_url, schema_namespace="test")) x = HedSchemaGroup(schema_list) bids = BidsDataset(self.library_path, schema=x) self.assertIsInstance(bids, BidsDataset, diff --git a/tests/validator/test_tag_validator.py b/tests/validator/test_tag_validator.py index 5f453f806..471075553 100644 --- a/tests/validator/test_tag_validator.py +++ b/tests/validator/test_tag_validator.py @@ -849,12 +849,12 @@ def test_includes_all_required_tags(self): expected_issues = { 'complete': [], 'missingAgent': self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, - tag_prefix='Agent/Animal-agent'), - 'missingAction': self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_prefix='Action'), + tag_namespace='Agent/Animal-agent'), + 'missingAction': self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_namespace='Action'), 'inSubGroup': [], 'missingAll': - self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_prefix='Action') - + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_prefix='Agent/Animal-agent'), + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_namespace='Action') + + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_namespace='Agent/Animal-agent'), } self.validator_semantic(test_strings, expected_results, expected_issues, True) @@ -877,9 +877,9 @@ def test_multiple_copies_unique_tags(self): expected_issues = { 'legal': [], 'multipleDesc': self.format_error(ValidationErrors.TAG_NOT_UNIQUE, - tag_prefix='Property/Organizational-property/Event-context'), + tag_namespace='Property/Organizational-property/Event-context'), 'multipleDescIncShort': self.format_error(ValidationErrors.TAG_NOT_UNIQUE, - tag_prefix='Property/Organizational-property/Event-context'), + tag_namespace='Property/Organizational-property/Event-context'), } self.validator_semantic(test_strings, expected_results, expected_issues, False) diff --git a/tests/validator/test_tag_validator_library.py b/tests/validator/test_tag_validator_library.py index 571fa2b85..194705f02 100644 --- a/tests/validator/test_tag_validator_library.py +++ b/tests/validator/test_tag_validator_library.py @@ -18,7 +18,7 @@ def setUpClass(cls): schema_file = '../data/validator_tests/HED8.0.0_added_tests.mediawiki' hed_xml = os.path.join(os.path.dirname(os.path.realpath(__file__)), schema_file) hed_schema1 = schema.load_schema(hed_xml) - hed_schema2 = schema.load_schema(hed_xml, schema_prefix="tl:") + hed_schema2 = schema.load_schema(hed_xml, schema_namespace="tl:") cls.hed_schema = HedSchemaGroup([hed_schema1, hed_schema2]) cls.error_handler = error_reporter.ErrorHandler() @@ -27,8 +27,8 @@ def setUpClass(cls): def test_invalid_load(self): schema_file = '../data/schema_tests/HED8.0.0t.xml' hed_xml = os.path.join(os.path.dirname(os.path.realpath(__file__)), schema_file) - hed_schema1 = schema.load_schema(hed_xml, schema_prefix="tl:") - hed_schema2 = schema.load_schema(hed_xml, schema_prefix="tl:") + hed_schema1 = schema.load_schema(hed_xml, schema_namespace="tl:") + hed_schema2 = schema.load_schema(hed_xml, schema_namespace="tl:") self.assertRaises(HedFileError, HedSchemaGroup, [hed_schema1, hed_schema2]) @@ -440,14 +440,14 @@ def test_includes_all_required_tags(self): expected_issues = { 'complete': [], 'missingAgent': self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, - tag_prefix='Agent/Animal-agent'), - 'missingAction': self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_prefix='Action'), + tag_namespace='Agent/Animal-agent'), + 'missingAction': self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_namespace='Action'), 'inSubGroup': [], 'missingAll': - self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_prefix='Action') - + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_prefix='Agent/Animal-agent') - + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_prefix='tl:Action') - + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_prefix='tl:Agent/Animal-agent'), + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_namespace='Action') + + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_namespace='Agent/Animal-agent') + + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_namespace='tl:Action') + + self.format_error(ValidationErrors.REQUIRED_TAG_MISSING, tag_namespace='tl:Agent/Animal-agent'), } self.validator_semantic(test_strings, expected_results, expected_issues, True) @@ -470,9 +470,9 @@ def test_multiple_copies_unique_tags(self): expected_issues = { 'legal': [], 'multipleDesc': self.format_error(ValidationErrors.TAG_NOT_UNIQUE, - tag_prefix='tl:Property/Organizational-property/Event-context'), + tag_namespace='tl:Property/Organizational-property/Event-context'), 'multipleDescIncShort': self.format_error(ValidationErrors.TAG_NOT_UNIQUE, - tag_prefix='tl:Property/Organizational-property/Event-context'), + tag_namespace='tl:Property/Organizational-property/Event-context'), } self.validator_semantic(test_strings, expected_results, expected_issues, False)