Quellcode für text_lint.operations.lookups.parsers.lookup_expressions

"""Lookup expression parser."""

from typing import List, Tuple

from text_lint.config import (
    LOOKUP_SENTINEL,
    LOOKUP_SEPERATOR,
    LOOKUP_STATIC_VALUE_MARKER,
)
from text_lint.exceptions.lookups import LookupSyntaxInvalid
from text_lint.exceptions.schema import (
    LookupExpressionInvalid,
    LookupExpressionInvalidDuplicatePositional,
    LookupExpressionInvalidSequence,
)
from text_lint.operations.lookups import lookup_registry
from text_lint.operations.lookups.bases.lookup_base import AliasLookupParams
from text_lint.operations.lookups.parsers.lookups import parse_lookup


[Doku] class ParsedLookup: """A parsed lookup operation with its parameters."""
[Doku] def __init__( self, name: str, params: "AliasLookupParams", ) -> None: """Instantiate ParsedLookup instances. :param name: The name of the lookup operation. :param params: A list of parameters for this lookup operation. """ self.name = name self.params = params
LOOKUPS_SENTINEL_VALUE = [ParsedLookup(name=LOOKUP_SENTINEL, params=[])]
[Doku] def parse_lookup_expression(value: str) -> Tuple[str, List["ParsedLookup"]]: """Extract the save ids, lookups and parameters from a lookup expression. :param value: The lookup expression to parse. :returns: A tuple of the data source and lookup operation instances. :raises: LookupExpressionInvalid, LookupExpressionInvalidSequence, LookupExpressionInvalidDuplicatePositional """ if value.startswith(LOOKUP_STATIC_VALUE_MARKER): return value, LOOKUPS_SENTINEL_VALUE split_value = value.split(LOOKUP_SEPERATOR) segments = split_value[1:] source = split_value[0] lookups: List["ParsedLookup"] = [] if not segments: return source, LOOKUPS_SENTINEL_VALUE current_segment = "" found_non_positional_lookup = False while segments: if current_segment: current_segment += LOOKUP_SEPERATOR current_segment += segments.pop(0) try: name, params = parse_lookup(current_segment) if name in lookup_registry: registry_reference = lookup_registry[name] if not registry_reference.is_positional: found_non_positional_lookup = True else: if found_non_positional_lookup: raise LookupExpressionInvalidSequence(value) if name in [previously_added.name for previously_added in lookups]: raise LookupExpressionInvalidDuplicatePositional(name) lookups.append(ParsedLookup(name=name, params=params)) current_segment = "" except LookupSyntaxInvalid: pass if (value and not lookups) or current_segment: raise LookupExpressionInvalid(value) return source, lookups