Error handling

Error handling and reporting classes for HED validation and processing.

Error types and constants

HedExceptions

class HedExceptions[source]

Bases: object

HED exception codes.

BAD_COLUMN_NAMES = 'BAD_COLUMN_NAMES'
BAD_PARAMETERS = 'BAD_PARAMETERS'
CANNOT_PARSE_JSON = 'CANNOT_PARSE_JSON'
CANNOT_PARSE_RDF = 'CANNOT_PARSE_RDF'
CANNOT_PARSE_XML = 'CANNOT_PARSE_XML'
FILE_NOT_FOUND = 'FILE_NOT_FOUND'
GENERIC_ERROR = 'GENERIC_ERROR'
HED_SCHEMA_NODE_NAME_INVALID = 'HED_SCHEMA_NODE_NAME_INVALID'
INVALID_DATAFRAME = 'INVALID_DATAFRAME'
INVALID_EXTENSION = 'INVALID_EXTENSION'
INVALID_FILE_FORMAT = 'INVALID_FILE_FORMAT'
INVALID_HED_FORMAT = 'INVALID_HED_FORMAT'
SCHEMA_DUPLICATE_LIBRARY = 'SCHEMA_LIBRARY_INVALID'
SCHEMA_DUPLICATE_NAMES = 'SCHEMA_DUPLICATE_NAMES'
SCHEMA_HEADER_INVALID = 'SCHEMA_HEADER_INVALID'
SCHEMA_INVALID = 'SCHEMA_INVALID'
SCHEMA_LIBRARY_INVALID = 'SCHEMA_LIBRARY_INVALID'
SCHEMA_LOAD_FAILED = 'SCHEMA_LOAD_FAILED'
SCHEMA_SECTION_MISSING = 'SCHEMA_SECTION_MISSING'
SCHEMA_TAG_TSV_BAD_PARENT = 'SCHEMA_TAG_TSV_BAD_PARENT'
SCHEMA_VERSION_INVALID = 'SCHEMA_VERSION_INVALID'
URL_ERROR = 'URL_ERROR'
WIKI_DELIMITERS_INVALID = 'WIKI_DELIMITERS_INVALID'
WIKI_LINE_INVALID = 'WIKI_LINE_INVALID'
WIKI_LINE_START_INVALID = 'WIKI_LINE_START_INVALID'
WIKI_SEPARATOR_INVALID = 'WIKI_SEPARATOR_INVALID'

HedFileError

class HedFileError(code, message, filename, issues=None)[source]

Bases: Exception

Exception raised when a file cannot be parsed due to being malformed, file IO, etc.

add_note()

Exception.add_note(note) – add a note to the exception

args
with_traceback()

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

Error reporting

ErrorHandler

class ErrorHandler(check_for_warnings=True)[source]

Bases: object

Class to hold error context and having general error functions.

add_context_and_filter(issues)[source]

Filter out warnings if requested, while adding context to issues.

issues(list):

list: A list containing a single dictionary representing a single error.

static aggregate_code_counts(file_code_dict: dict) dict[source]

Aggregate the counts of codes across multiple files.

Parameters:

file_code_dict (dict) – A dictionary where keys are filenames and values are dictionaries of code counts.

Returns:

A dictionary with the aggregated counts of codes across all files.

Return type:

dict

static filter_issues_by_count(issues: list[dict], count: int, by_file: bool = False) tuple[list[dict], dict[str, int]][source]

Filter the issues list to only include the first count issues of each code.

Parameters:
  • issues (list[dict]) – A list of dictionaries containing the full issue list.

  • count (int) – The number of issues to keep for each code.

  • by_file (bool) – If True, group by file name.

Returns:

A tuple containing:
  • A list of dictionaries representing the filtered issue list.

  • A dictionary with the codes as keys and the number of occurrences as values.

Return type:

tuple[list[dict], dict[str, int]]

static filter_issues_by_severity(issues_list: list[dict], severity: int) list[dict][source]

Gather all issues matching or below a given severity.

Parameters:
  • issues_list (list[dict]) – A list of dictionaries containing the full issue list.

  • severity (int) – The level of issues to keep.

Returns:

A list of dictionaries containing the issue list after filtering by severity.

Return type:

list[dict]

static format_error(error_type: str, *args, actual_error=None, **kwargs) list[dict][source]

Format an error based on the parameters, which vary based on what type of error this is.

Parameters:
  • error_type (str) – The type of error for this. Registered with @hed_error or @hed_tag_error.

  • args (args) – Any remaining non-keyword args after those required by the error type.

  • actual_error (str or None) – Code to actually add to report out.

  • kwargs (kwargs) – The other keyword args to pass down to the error handling func.

Returns:

A list containing a single dictionary representing a single error.

Return type:

list[dict]

Notes

The actual error is useful for errors that are shared like invalid character.

static format_error_from_context(error_type: str, error_context: list, *args, actual_error: str | None, **kwargs) list[dict][source]

Format an error based on the error type.

Parameters:
  • error_type (str) – The type of error. Registered with @hed_error or @hed_tag_error.

  • error_context (list) – Contains the error context to use for this error.

  • args (args) – Any remaining non-keyword args.

  • actual_error (str or None) – Error code to actually add to report out.

  • kwargs (kwargs) – Keyword parameters to pass down to the error handling func.

Returns:

A list containing a single dictionary.

Return type:

list[dict]

Notes

  • Generally the error_context is returned from _add_context_to_error.

  • The actual_error is useful for errors that are shared like invalid character.

  • This can’t filter out warnings like the other ones.

format_error_with_context(*args, **kwargs)[source]
static get_code_counts(issues: list[dict]) dict[str, int][source]

Count the occurrences of each error code in the issues list.

Parameters:

issues (list[dict]) – A list of dictionaries containing the issues.

Returns:

A dictionary with error codes as keys and their occurrence counts as values.

Return type:

dict[str, int]

pop_error_context()[source]

Remove the last scope from the error context.

Notes

Modifies the error context of this reporter.

push_error_context(context_type, context)[source]

Push a new error context to narrow down error scope.

Parameters:
  • context_type (str) – A value from ErrorContext representing the type of scope.

  • context (str, int, or HedString) – The main value for the context_type.

Notes

The context depends on the context_type. For ErrorContext.FILE_NAME this would be the actual filename.

static replace_tag_references(list_or_dict)[source]

Utility function to remove any references to tags, strings, etc. from any type of nested list or dict.

Use this if you want to save out issues to a file.

If you’d prefer a copy returned, use ErrorHandler.replace_tag_references(list_or_dict.copy()).

Parameters:

list_or_dict (list or dict) – An arbitrarily nested list/dict structure

reset_error_context()[source]

Reset all error context information to defaults.

Notes

This function is mainly for testing and should not be needed with proper usage.

val_error_unknown(**kwargs) str[source]

Default error handler if no error of this type was registered.

Parameters:
  • args (args) – List of non-keyword parameters (varies).

  • kwargs (kwargs) – Keyword parameters (varies)

Returns:

The error message.

Return type:

str

Error functions

get_printable_issue_string(issues, title=None, severity=None, skip_filename=True, add_link=False, show_details=False) str[source]

Return a string with issues list flatted into single string, one per line.

Parameters:
  • issues (list) – Issues to print.

  • title (str) – Optional title that will always show up first if present(even if there are no validation issues).

  • severity (int) – Return only warnings >= severity.

  • skip_filename (bool) – If True, don’t add the filename context to the printable string.

  • add_link (bool) – Add a link at the end of message to the appropriate error if True

  • show_details (bool) – If True, show details about the issues.

Returns:

A string containing printable version of the issues or ‘’.

Return type:

str

sort_issues(issues, reverse=False) list[dict][source]

Sort a list of issues by the error context values.

Parameters:
  • issues (list) – A list of dictionaries representing the issues to be sorted.

  • reverse (bool, optional) – If True, sorts the list in descending order. Default is False.

Returns:

The sorted list of issues.

Return type:

list[dict]

separate_issues(issues_list: list[dict]) tuple[list[dict], list[dict]][source]

Separate a list of issues into errors and warnings.

Parameters:

issues_list (list[dict]) – A list of issue dictionaries. The ‘severity’ key is optional; issues that omit it are treated as errors (ErrorSeverity.ERROR).

Returns:

A tuple of (errors, warnings) where errors contains

issues with severity <= ErrorSeverity.ERROR and warnings contains issues with severity > ErrorSeverity.ERROR.

Return type:

tuple[list[dict], list[dict]]

iter_errors(issues)[source]

An iterator over issues that flattens the context into each issue dictionary.

This function takes a list of issues and transforms each one into a “flat” dictionary. A flat dictionary contains all the information about a single error, including its context, in a single, non-nested dictionary. This is useful for reporting or logging errors in a simple, straightforward format.

For example, context information like file name or row number, which might be stored in a nested structure or separate from the issue dictionary, is merged into the top level of the dictionary.

It also adds a ‘url’ key with a link to the documentation for known HED error codes. Any complex objects like HedTag or HedString are converted to their string representations.

Parameters:

issues (list) – A list of issue dictionaries to iterate over.

Yields:

dict – A flattened dictionary representing a single error.

Error types

ValidationErrors

class ValidationErrors[source]

Bases: object

CHARACTER_INVALID = 'CHARACTER_INVALID'
COMMA_MISSING = 'COMMA_MISSING'
CURLY_BRACE_UNSUPPORTED_HERE = 'CURLY_BRACE_UNSUPPORTED_HERE'
DEFINITION_INVALID = 'DEFINITION_INVALID'
DEF_EXPAND_INVALID = 'DEF_EXPAND_INVALID'
DEF_INVALID = 'DEF_INVALID'
DUPLICATE_COLUMN_BETWEEN_SOURCES = 'DUPLICATE_COLUMN_BETWEEN_SOURCES'
DUPLICATE_COLUMN_IN_LIST = 'DUPLICATE_COLUMN_IN_LIST'
ELEMENT_DEPRECATED = 'ELEMENT_DEPRECATED'
HED_BLANK_COLUMN = 'HED_BLANK_COLUMN'
HED_COLUMN_MISSING = 'HED_COLUMN_MISSING'
HED_DEF_EXPAND_INVALID = 'HED_DEF_EXPAND_INVALID'
HED_DEF_EXPAND_UNMATCHED = 'HED_DEF_EXPAND_UNMATCHED'
HED_DEF_EXPAND_VALUE_EXTRA = 'HED_DEF_EXPAND_VALUE_EXTRA'
HED_DEF_EXPAND_VALUE_MISSING = 'HED_DEF_EXPAND_VALUE_MISSING'
HED_DEF_UNMATCHED = 'HED_DEF_UNMATCHED'
HED_DEF_VALUE_EXTRA = 'HED_DEF_VALUE_EXTRA'
HED_DEF_VALUE_MISSING = 'HED_DEF_VALUE_MISSING'
HED_GROUP_EMPTY = 'HED_GROUP_EMPTY'
HED_LIBRARY_UNMATCHED = 'HED_LIBRARY_UNMATCHED'
HED_MISSING_REQUIRED_COLUMN = 'HED_MISSING_REQUIRED_COLUMN'
HED_MULTIPLE_TOP_TAGS = 'HED_MULTIPLE_TOP_TAGS'
HED_PLACEHOLDER_OUT_OF_CONTEXT = 'HED_PLACEHOLDER_OUT_OF_CONTEXT'
HED_RESERVED_TAG_GROUP_ERROR = 'HED_RESERVED_TAG_GROUP_ERROR'
HED_RESERVED_TAG_REPEATED = 'HED_RESERVED_TAG_REPEATED'
HED_TAGS_NOT_ALLOWED = 'HED_TAGS_NOT_ALLOWED'
HED_TAG_GROUP_TAG = 'HED_TAG_GROUP_TAG'
HED_TAG_REPEATED = 'HED_TAG_REPEATED'
HED_TAG_REPEATED_GROUP = 'HED_TAG_REPEATED_GROUP'
HED_TOP_LEVEL_TAG = 'HED_TOP_LEVEL_TAG'
HED_UNKNOWN_COLUMN = 'HED_UNKNOWN_COLUMN'
INVALID_PARENT_NODE = 'invalidParent'
INVALID_TAG_CHARACTER = 'INVALID_TAG_CHARACTER'
INVALID_VALUE_CLASS_CHARACTER = 'INVALID_VALUE_CLASS_CHARACTER'
INVALID_VALUE_CLASS_VALUE = 'INVALID_VALUE_CLASS_VALUE'
NODE_NAME_EMPTY = 'NODE_NAME_EMPTY'
NO_VALID_TAG_FOUND = 'invalidTag'
ONSETS_UNORDERED = 'ONSETS_UNORDERED'
PARENTHESES_MISMATCH = 'PARENTHESES_MISMATCH'
PLACEHOLDER_INVALID = 'PLACEHOLDER_INVALID'
REQUIRED_TAG_MISSING = 'REQUIRED_TAG_MISSING'
SIDECAR_AND_OTHER_COLUMNS = 'SIDECAR_AND_OTHER_COLUMNS'
SIDECAR_INVALID = 'SIDECAR_INVALID'
SIDECAR_KEY_MISSING = 'SIDECAR_KEY_MISSING'
STYLE_WARNING = 'STYLE_WARNING'
TAG_EMPTY = 'TAG_EMPTY'
TAG_EXPRESSION_REPEATED = 'TAG_EXPRESSION_REPEATED'
TAG_EXTENDED = 'TAG_EXTENDED'
TAG_EXTENSION_INVALID = 'TAG_EXTENSION_INVALID'
TAG_GROUP_ERROR = 'TAG_GROUP_ERROR'
TAG_INVALID = 'TAG_INVALID'
TAG_NAMESPACE_PREFIX_INVALID = 'TAG_NAMESPACE_PREFIX_INVALID'
TAG_NOT_UNIQUE = 'TAG_NOT_UNIQUE'
TAG_REQUIRES_CHILD = 'TAG_REQUIRES_CHILD'
TEMPORAL_TAG_ERROR = 'TEMPORAL_TAG_ERROR'
TILDES_UNSUPPORTED = 'TILDES_UNSUPPORTED'
TSV_COLUMN_MISSING = 'TSV_COLUMN_MISSING'
UNITS_INVALID = 'UNITS_INVALID'
VALUE_INVALID = 'VALUE_INVALID'
VERSION_DEPRECATED = 'VERSION_DEPRECATED'

SchemaErrors

class SchemaErrors[source]

Bases: object

SCHEMA_DUPLICATE_FROM_LIBRARY = 'SCHEMA_LIBRARY_INVALID'
SCHEMA_DUPLICATE_NODE = 'SCHEMA_DUPLICATE_NODE'
SCHEMA_INVALID_CHILD = 'SCHEMA_INVALID_CHILD'
SCHEMA_INVALID_SIBLING = 'SCHEMA_INVALID_SIBLING'

SidecarErrors

class SidecarErrors[source]

Bases: object

BLANK_HED_STRING = 'BLANK_HED_STRING'
INVALID_POUND_SIGNS_CATEGORY = 'INVALID_POUND_SIGNS_CATEGORY'
INVALID_POUND_SIGNS_VALUE = 'INVALID_POUND_SIGNS_VALUE'
SIDECAR_BRACES_INVALID = 'SIDECAR_BRACES_INVALID'
SIDECAR_HED_USED = 'SIDECAR_HED_USED'
SIDECAR_NA_USED = 'SIDECAR_NA_USED'
UNKNOWN_COLUMN_TYPE = 'UNKNOWN_COLUMN_TYPE'
WRONG_HED_DATA_TYPE = 'WRONG_HED_DATA_TYPE'

ErrorContext

class ErrorContext[source]

Bases: object

Context this error took place in, each error potentially having multiple contexts.

COLUMN = 'ec_column'
CUSTOM_TITLE = 'ec_title'
FILE_NAME = 'ec_filename'
HED_STRING = 'ec_HedString'
LINE = 'ec_line'
ROW = 'ec_row'
SCHEMA_ATTRIBUTE = 'ec_attribute'
SCHEMA_SECTION = 'ec_section'
SCHEMA_TAG = 'ec_schema_tag'
SIDECAR_COLUMN_NAME = 'ec_sidecarColumnName'
SIDECAR_KEY_NAME = 'ec_sidecarKeyName'
TABLE_NAME = 'ec_table_name'

ErrorSeverity

class ErrorSeverity(*values)[source]

Bases: IntEnum

Severity codes for errors.

ERROR = 1
WARNING = 10
as_integer_ratio()

Return a pair of integers, whose ratio is equal to the original int.

The ratio is in lowest terms and has a positive denominator.

>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
bit_count()

Number of ones in the binary representation of the absolute value of self.

Also known as the population count.

>>> bin(13)
'0b1101'
>>> (13).bit_count()
3
bit_length()

Number of bits necessary to represent self in binary.

>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
conjugate()

Returns self, the complex conjugate of any int.

denominator

the denominator of a rational number in lowest terms

classmethod from_bytes(bytes, byteorder='big', *, signed=False)

Return the integer represented by the given array of bytes.

bytes

Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Indicates whether two’s complement is used to represent the integer.

imag

the imaginary part of a complex number

is_integer()

Returns True. Exists for duck type compatibility with float.is_integer.

numerator

the numerator of a rational number in lowest terms

real

the real part of a complex number

to_bytes(length=1, byteorder='big', *, signed=False)

Return an array of bytes representing an integer.

length

Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder’ as the byte order value. Default is to use ‘big’.

signed

Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.