cloud-custodian/cel-python

overrides as parameter to activation

kapilt opened this issue · 3 comments

evaluator access defers to activation.functions

This is going to change in the next code drop.

There needs to be a more consistent Chain of Command pattern to name resolution in an Activation. The reliance on the global functions is a bad hack. (But it works.) There are (currently) no instances of nested activations, but there will be. The five missing macros (.all(), .any(), .exists(), .exists_one(), and .map()) all require nested activations because they all have a localized bind variable. (Analogous to the bind variables in a Python generator expression. (f(bind) for bind in source) is CEL's source.map(bind, f). In Python 2, bind was global, which was wrong. It's localized.

So far, my reading of the Go code suggestions an Activation parallels the Python stack frame. Function overrides are provided when the executable "program" is created from the AST. The signatures are provided as a declaration, but the body is not provided until the final executable is built.

The Go implementation accepts function definitions as part of the compile() method that builds an executable from the CEL expression and function overrides.

The next code drop will look like this

    >>> import celpy
    >>> from typing import Callable
    >>> cel_source = """
    ... i.greet(you)
    ... """

    >>> decls = {
    ...     "i": celpy.celtypes.StringType,
    ...     "you": celpy.celtypes.StringType,
    ...     "greet": Callable}
    >>> env = celpy.Environment(annotations=decls)
    >>> ast = env.compile(cel_source)
    >>> def greet(lhs: celpy.celtypes.StringType, rhs: celpy.celtypes.StringType) -> celpy.celtypes.StringType:
    ...     return "Hello {1:s}! Nice to meet you, I'm {0:s}.\\n".format(lhs, rhs)
    >>> prgm = env.program(ast, functions=[greet])
    >>> activation = {
    ...     "i": "CEL", "you": "world"
    ... }
    >>> result = prgm.evaluate(activation)
    >>> result
    "Hello world! Nice to meet you, I'm CEL.\\n"

Check the latest release. I think this provides suitable override definitions. For examples, see the examples in https://github.com/cloud-custodian/cel-python/blob/master/docs/source/integration.rst. These show an approach that seems consistent with Go.