Source code for hed.models.definition_entry

"""A single definition."""

import copy
from typing import Union

from hed.models.hed_group import HedGroup


[docs] class DefinitionEntry: """Stores the resolved contents of a single HED Definition. A ``DefinitionEntry`` is created when a ``Definition/`` tag group is parsed and stored in a :class:`~hed.models.DefinitionDict`. It captures: - **name** — the lower-cased label portion (without ``Definition/``). - **contents** — the inner :class:`~hed.models.HedGroup` of the definition (``None`` if the definition body is empty). - **takes_value** — whether exactly one tag inside contains a ``#`` placeholder (i.e. the definition expects a run-time value via ``Def/name/value``). - **source_context** — the error-context stack captured at parse time, used to produce precise error messages when the definition is later expanded. **Use this class directly when you need to:** - Iterate over a :class:`~hed.models.DefinitionDict` and inspect individual definition bodies or their placeholder status. - Build tooling that expands, serialises, or analyses HED definitions programmatically. **Most users never need this class** — :meth:`~hed.models.DefinitionDict.get_def_entry` and :meth:`~hed.models.DefinitionDict.expand_def_tag` handle the common workflows. """ def __init__(self, name, contents, takes_value, source_context): """Initialize info for a single definition. Parameters: name (str): The label portion of this name (not including Definition/). contents (HedGroup): The contents of this definition (which could be None). takes_value (bool): If True, expects ONE tag to have a single # sign in it. source_context (list, None): List (stack) of dictionaries giving context for reporting errors. """ self.name = name.casefold() if contents: contents = contents.copy() contents.sort() if contents: contents = contents.copy() self.contents = contents self.takes_value = takes_value self.source_context = source_context
[docs] def get_definition(self, replace_tag, placeholder_value=None, return_copy_of_tag=False) -> Union["HedGroup", None]: """Return a copy of the definition with the tag expanded and the placeholder plugged in. Returns None if placeholder_value passed when it doesn't take value, or vice versa. Parameters: replace_tag (HedTag): The def HED tag to replace with an expanded version. placeholder_value (str or None): If present and required, will replace any pound signs in the definition contents. return_copy_of_tag (bool): Set to True for validation. Returns: Union[HedGroup, None]: The contents of this definition(including the def tag itself). Raises: ValueError: Something internally went wrong with finding the placeholder tag. This should not be possible. """ if self.takes_value == (not placeholder_value): return None if return_copy_of_tag: replace_tag = replace_tag.copy() output_contents = [replace_tag] if self.contents: output_group = copy.deepcopy(self.contents) if placeholder_value: placeholder_tag = output_group.find_placeholder_tag() if not placeholder_tag: raise ValueError("Internal error related to placeholders in definition mapping") placeholder_tag.replace_placeholder(placeholder_value) output_contents = [replace_tag, output_group] output_contents = HedGroup( replace_tag._hed_string, startpos=replace_tag.span[0], endpos=replace_tag.span[1], contents=output_contents ) return output_contents
def __str__(self): return str(self.contents) def __eq__(self, other): """Check equality based on name, contents, and takes_value. Parameters: other (DefinitionEntry): Another DefinitionEntry to compare with. Returns: bool: True if name, contents, and takes_value are equal, False otherwise. """ if not isinstance(other, DefinitionEntry): return False return self.name == other.name and self.contents == other.contents and self.takes_value == other.takes_value