Skip to content
Snippets Groups Projects
Select Git revision
  • 96e32e55d54b6584fec2752abecd23f99fe8e2be
  • master default protected
  • 9.0
  • 8.0
  • nt-tools
  • 7.8
  • 7.6
  • 7.4
  • 7.2
  • 7.0
  • 0.6
  • rosuav/latex-markdown-renderer
  • rxnpatch/rxnpatch
  • marcus/gobject-introspection
  • rxnpatch/8.0
  • rosuav/pre-listening-ports
  • rosuav/async-annotations
  • rosuav/pgsql-ssl
  • rxnpatch/rxnpatch-broken/2023-10-06T094250
  • grubba/fdlib
  • grubba/wip/sakura/8.0
  • v8.0.2020
  • v8.0.2018
  • v8.0.2016
  • v8.0.2014
  • v8.0.2012
  • v8.0.2008
  • v8.0.2006
  • v8.0.2004
  • v8.0.2002
  • v8.0.2000
  • v8.0.1998
  • v8.0.1996
  • v8.0.1994
  • v8.0.1992
  • v8.0.1990
  • v8.0.1988
  • v8.0.1986
  • rxnpatch/clusters/8.0/2025-04-29T124414
  • rxnpatch/2025-04-29T124414
  • v8.0.1984
41 results

cpp.h

Blame
  • lookup.py 5.53 KiB
    r"""
    Jq(1) <https://jqlang.github.io/jq/> like expressions for python.
    
    Something similar to Jq, but built on python objects.
    All procedures eventually return the expecetd value, or a
    user-supplied default value.
    
    
    Example
    -------
    ::
    
        lookup(object) \
                .ref('docstring') \
                .ref('tags') \
                .select(Ref('tag_name') == 'summary')) \
                .idx(0) \
                .ref('text') \
                .exec()
    
    .. todo::
      ``select``
      Selects all values from a list which matches a given expression.
      This would however require us to manage multiple values at once.
    """
    
    from typing import Any, Union
    
    
    class Expression:
        """
        A test expression.
    
        ::
    
            x.find(Ref("key") == "summary")
    
        Would focus in on the first list element which has the key "key"
        with a value of "summary".
    
        This is the root-class, and doesn't make sense to initialize directly.
        """
    
        def run(self, value: Any) -> bool:
            """Evaluate expression, returing true if the value matches the predicate."""
            return False
    
    
    class RefEqExpr(Expression):
        """
        Equality expression.
    
        Assumes that the left part is a RefExpr and the right part is a value.
    
        Checks that the left reference exists in the given value, and that
        it's value is equal to the right one.
        """
    
        def __init__(self, left: 'RefExpr', right: Any):
            self.left = left
            self.right = right
    
        def run(self, value: Any) -> bool:
            """
            Evaluate the expression.
    
            Returns true if the left hand side key is present in *value*,
            and if the value under that key in *value* matches the right
            hand side.
            """
            if self.left.key not in value:
                return False
            else:
                return bool(value[self.left.key] == self.right)
    
    
    class RefExpr(Expression):
        """
        A key reference expression.
    
        By itself, checks if the given key exists in the given value.
        Intended to be used for dictionaries, but will work on anything
        implementing `in`.
        """
    
        def __init__(self, key: str):
            self.key = key
    
        def __eq__(self, other: Any) -> 'RefEqExpr':  # type: ignore
            """
            Return a new expression checking equality between left and right.
    
            Left side will be ourself, while the right side can in theory
            be anything (see RefEqExpr for details).
    
            Typing is removed here, since the base object specifies the type as
                def __eq__(self, x: Any) -> bool:
                    ...
            Which we aren't allowed to deviate from according to the
            Liskov substitution principle. However, at least sqlalchemy
            uses the exact same "trick" for the exact same effect. So
            there is a president.
    
            """
            return RefEqExpr(self, other)
    
        def run(self, value: Any) -> bool:
            """Return true if our key is present in *value*."""
            return self.key in value
    
    
    class _NullLookup:
        """
        A failed lookup.
    
        Shares the same interface as true "true" lookup class, but all
        methods imidiattely propagate the failure state.
    
        This saves us from null in the code.
        """
    
        def get(self, _: str) -> '_NullLookup':
            """Propagate null."""
            return self
    
        def ref(self, _: str) -> '_NullLookup':
            """Propagate null."""
            return self
    
        def idx(self, _: int) -> '_NullLookup':
            """Propagate null."""
            return self
    
        def find(self, _: Expression) -> '_NullLookup':
            """Propagate null."""
            return self
    
        def value(self, dflt: Any = None) -> Any:
            """Return the default value."""
            return dflt
    
    
    class _TrueLookup:
        """Easily lookup values in nested data structures."""
    
        def __init__(self, object: Any):
            self.object = object
    
        def get(self, key: str) -> Union['_TrueLookup', '_NullLookup']:
            """Select object field by name."""
            try:
                return _TrueLookup(getattr(self.object, key))
            except Exception:
                return _NullLookup()
    
        def ref(self, key: str) -> Union['_TrueLookup', '_NullLookup']:
            """Select object by dictionary key."""
            try:
                return _TrueLookup(self.object[key])
            except TypeError:
                # Not a dictionary
                return _NullLookup()
            except KeyError:
                # Key not in dictionary
                return _NullLookup()
    
        def idx(self, idx: int) -> Union['_TrueLookup', '_NullLookup']:
            """Select array index."""
            try:
                return _TrueLookup(self.object[idx])
            except TypeError:
                # Not a list
                return _NullLookup()
            except IndexError:
                # Index out of range
                return _NullLookup()
    
        def find(self, expr: Expression) -> Union['_TrueLookup', '_NullLookup']:
            """Find the first element in list matching expression."""
            for item in self.object:
                if expr.run(item):
                    return _TrueLookup(item)
            return _NullLookup()
    
        def value(self, dflt: Any = None) -> Any:
            """
            Return the found value.
    
            If no value is found, either return None, or the second argument.
            """
            return self.object
    
    
    # Implemented as a union between our two different types, since the
    # split is an implementation detail to easier handle null values.
    Lookup = Union[_TrueLookup, _NullLookup]
    """Lookup type."""
    
    
    def lookup(base: Any) -> Lookup:
        """
        Create a new lookup base object.
    
        All queries should start here.
    
        :param base: Can be anything which has meaningful subfields.
        """
        return _TrueLookup(base)
    
    
    Ref = RefExpr