Source code for elevaso_spine.fmt.sub

"""
.. module:: sub
    :platform: Unix, Windows
    :synopsis: Substitute values from dictionary
"""

# Python Standard Libraries
from collections import OrderedDict
import logging
import re
from typing import Match

# 3rd Party Libraries


# Project Specific Libraries
from elevaso_spine.itr import itr

LOGGER = logging.getLogger(__name__)

DEFAULT_SUB_VALUE_REGEX = re.compile(r"\$\{(?P<var>[_\w\d]+)\}")


[docs] def sub_value(value: object, sub_values: dict, **kwargs) -> object: """Substitute values based on a RegEx pattern and return updated object Args: value (object): Python object to look for the pattern sub_values (dict): Dictionary of possible values to substitute Kwargs: pattern (re.Pattern, Optional): RegEx Pattern to search for, defaults to DEFAULT_SUB_VALUE_REGEX default_val (object, Optional): Default value for placeholder if not found in sub_values, default to None (returns original value/item) error_not_exist (bool, Optional): Raise error if the placeholder key does not exist in sub_values, default is False copy_val (bool, Optional): True/False contents of dict/list should be copied prior to modifying, defaults to True Raises: TypeError: If sub_values type is not dict or OrderedDict Returns: object: Updated object with values substituted """ def __return_match_val(match: Match) -> str: """Return the match value Args: match (re.Match): RegEx Match Returns: str: String output """ last_val = list(filter(None, match.groups()))[-1] output = __get_sub_value( last_val, sub_values, error_not_exist, default_val ) if output and not isinstance(output, str): return str(output) return output def __sub_str(str_obj: str) -> str: """Substitute pattern with value for a given str Args: str_obj (str): String object to sub Returns: str: String output """ return pattern.sub(__return_match_val, str_obj) if ( not isinstance(sub_values, (dict, OrderedDict, list)) and sub_values is not None ): raise TypeError(f"Invalid type of {type(sub_values)} for sub_values") pattern = kwargs.pop("pattern", DEFAULT_SUB_VALUE_REGEX) default_val = kwargs.pop("default_val", None) error_not_exist = kwargs.pop("error_not_exist", False) if sub_values and len(sub_values) > 0: return itr.iterate( value, copy_val=kwargs.pop("copy_val", True), custom_type_map={str: __sub_str}, ) return value
def __get_sub_value( key: str, sub_values: dict, error_not_exist: bool = False, default_val: object = None, ) -> object: """Get the value to be substituted Args: key (str): Key to search within the dict of values sub_values (dict): Dictionary of substitution values error_not_exist (bool, Optional): Raise error if the placeholder key does not exist in sub_values, default is False default_val (object, Optional): Default value for placeholder if not found in sub_values, default to None (returns original value/item) Raises: KeyError: If error_not_exist is True and placeholder value does not exist in sub_values Returns: object from the sub_values """ try: return sub_values[key] except KeyError: if error_not_exist: raise KeyError(f"Value {key} not found") LOGGER.debug("Value %s not found, returning %s", key, default_val) return default_val