Source code for hed.schema.schema_attribute_validators

"""The built-in functions to validate known attributes.

Template for the functions:

- ``attribute_checker_template(hed_schema, tag_entry, attribute_name)``:
  - ``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 found validating this attribute
    """

from hed.errors.error_types import SchemaWarnings, ValidationErrors, SchemaAttributeErrors
from hed.errors.error_reporter import ErrorHandler
from hed.schema.hed_cache import get_hed_versions
from hed.schema.hed_schema_constants import HedKey, character_types, HedSectionKey
from hed.schema.schema_validation_util import schema_version_for_library
from semantic_version import Version


[docs]def tag_is_placeholder_check(hed_schema, tag_entry, attribute_name): """Check if comma separated list has valid HedTags. 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. """ issues = [] if not tag_entry.name.endswith("/#"): issues += ErrorHandler.format_error(SchemaWarnings.SCHEMA_NON_PLACEHOLDER_HAS_CLASS, tag_entry.name, attribute_name) return issues
[docs]def attribute_is_deprecated(hed_schema, tag_entry, attribute_name): """ Check if the attribute is deprecated. does not check value. 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. """ issues = [] # Attributes has to check properties section_key = HedSectionKey.Attributes if tag_entry.section_key == HedSectionKey.Attributes: section_key = HedSectionKey.Properties attribute_entry = hed_schema.get_tag_entry(attribute_name, section_key) if (attribute_entry and attribute_entry.has_attribute(HedKey.DeprecatedFrom) and not tag_entry.has_attribute(HedKey.DeprecatedFrom)): issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_ATTRIBUTE_VALUE_DEPRECATED, tag_entry.name, attribute_entry.name, attribute_name) return issues
[docs]def item_exists_check(hed_schema, tag_entry, attribute_name, section_key): """Check if the list of possible items exists in the schema and are not deprecated. 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 section_key (HedSectionKey): The section this item should be in. This is generally passed via functools.partial Returns: issues(list): A list of issues from validating this attribute. """ issues = [] item_values = tag_entry.attributes.get(attribute_name, "") split_items = item_values.split(",") for item in split_items: if not item: continue # todo: make a dict if any more added if section_key == HedSectionKey.Tags: item_entry = hed_schema.tags.get(item) elif section_key == HedSectionKey.UnitClasses: item_entry = hed_schema.unit_classes.get(item) elif section_key == HedSectionKey.ValueClasses: item_entry = hed_schema.value_classes.get(item) else: raise ValueError(f"Invalid item type: {section_key}") if not item_entry: issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_GENERIC_ATTRIBUTE_VALUE_INVALID, tag_entry.name, item, attribute_name) elif item_entry.has_attribute(HedKey.DeprecatedFrom) and not tag_entry.has_attribute(HedKey.DeprecatedFrom): issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_ATTRIBUTE_VALUE_DEPRECATED, tag_entry.name, item, attribute_name) return issues
[docs]def unit_exists(hed_schema, tag_entry, attribute_name): """Check the given unit is valid, and not deprecated. 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. """ issues = [] unit = tag_entry.attributes.get(attribute_name, "") unit_entry = tag_entry.get_derivative_unit_entry(unit) if unit and not unit_entry: issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_DEFAULT_UNITS_INVALID, tag_entry.name, unit, tag_entry.units) elif (unit_entry and unit_entry.has_attribute(HedKey.DeprecatedFrom) and not tag_entry.has_attribute(HedKey.DeprecatedFrom)): issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_DEFAULT_UNITS_DEPRECATED, tag_entry.name, unit_entry.name) return issues
# This is effectively unused and can never fail - The schema would catch these errors and refuse to load
[docs]def tag_exists_base_schema_check(hed_schema, tag_entry, attribute_name): """Check if the single tag is a partnered schema tag 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. """ issues = [] rooted_tag = tag_entry.attributes.get(attribute_name, "") if rooted_tag and rooted_tag not in hed_schema.tags: issues += ErrorHandler.format_error(ValidationErrors.NO_VALID_TAG_FOUND, rooted_tag, index_in_tag=0, index_in_tag_end=len(rooted_tag)) return issues
[docs]def tag_is_deprecated_check(hed_schema, tag_entry, attribute_name): """ Check if the element has a valid deprecatedFrom attribute, and that any children have it 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. """ issues = [] deprecated_version = tag_entry.attributes.get(attribute_name, "") library_name = tag_entry.has_attribute(HedKey.InLibrary, return_value=True) if not library_name and not hed_schema.with_standard: library_name = hed_schema.library all_versions = get_hed_versions(library_name=library_name) if deprecated_version: library_version = schema_version_for_library(hed_schema, library_name) # The version must exist, and be lower or equal to our current version if (deprecated_version not in all_versions or (library_version and Version(library_version) <= Version(deprecated_version))): issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_DEPRECATED_INVALID, tag_entry.name, deprecated_version) if hasattr(tag_entry, "children"): # Fix up this error message if we ever actually issue it for units for child in tag_entry.children.values(): if not child.has_attribute(attribute_name): issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_CHILD_OF_DEPRECATED, tag_entry.name, child.name) return issues
[docs]def conversion_factor(hed_schema, tag_entry, attribute_name): """Check if the conversion_factor on is valid 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. """ issues = [] cf = tag_entry.attributes.get(attribute_name, "1.0") try: cf = float(cf.replace("^", "e")) except (ValueError, AttributeError): pass if not isinstance(cf, float) or cf <= 0.0: issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_CONVERSION_FACTOR_NOT_POSITIVE, tag_entry.name, cf) return issues
[docs]def allowed_characters_check(hed_schema, tag_entry, attribute_name): """ Check allowed character has a valid value 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. """ issues = [] allowed_strings = character_types char_string = tag_entry.attributes.get(attribute_name, "") characters = char_string.split(",") for character in characters: if character not in allowed_strings and len(character) != 1: issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_ALLOWED_CHARACTERS_INVALID, tag_entry.name, character) return issues
[docs]def in_library_check(hed_schema, tag_entry, attribute_name): """Check if the library attribute is a valid schema name 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. """ issues = [] library = tag_entry.attributes.get(attribute_name, "") if library not in hed_schema.library.split(","): issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_IN_LIBRARY_INVALID, tag_entry.name, library) return issues
[docs]def is_numeric_value(hed_schema, tag_entry, attribute_name): """Check if the attribute is a valid numeric(float) value 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. """ issues = [] float_str = tag_entry.attributes.get(attribute_name, "") try: float(float_str) except ValueError: issues += ErrorHandler.format_error(SchemaAttributeErrors.SCHEMA_ATTRIBUTE_NUMERIC_INVALID, tag_entry.name, float_str, attribute_name) return issues