Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import abc
from typing import Any, Final, Optional

from localstack.services.stepfunctions.asl.component.common.string.string_expression import (
StringVariableSample,
)
from localstack.services.stepfunctions.asl.component.eval_component import EvalComponent
from localstack.services.stepfunctions.asl.eval.environment import Environment
from localstack.services.stepfunctions.asl.utils.json_path import extract_json


class Argument(EvalComponent, abc.ABC):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc: A docstring explaining the motivation behind the argument abstraction would be very helpful here.

"""
Represents an Intrinsic Function argument that can be evaluated and whose
result is pushed onto the stack.

Subclasses must override `_eval_argument()` to evaluate the specific value
of the argument they represent. This abstract class manages the type and
environment handling by appending the evaluated result to the environment's
stack in `_eval_body`.

The `_eval_body` method calls `_eval_argument()` and pushes the resulting
value to the stack.
"""

@abc.abstractmethod
def _eval_argument(self, env: Environment) -> Any: ...

def _eval_body(self, env: Environment) -> None:
argument = self._eval_argument(env=env)
env.stack.append(argument)


class ArgumentLiteral(Argument):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These Argument* implementations seem identical apart from inheriting the new Argument abstraction.
I think they are easier to understand them grouped here rather than spread across individual files 👍

definition_value: Final[Optional[Any]]

def __init__(self, definition_value: Optional[Any]):
self.definition_value = definition_value

def _eval_argument(self, env: Environment) -> Any:
return self.definition_value


class ArgumentJsonPath(Argument):
json_path: Final[str]

def __init__(self, json_path: str):
self.json_path = json_path

def _eval_argument(self, env: Environment) -> Any:
inp = env.stack[-1]
value = extract_json(self.json_path, inp)
return value


class ArgumentContextPath(ArgumentJsonPath):
def __init__(self, context_path: str):
json_path = context_path[1:]
super().__init__(json_path=json_path)

def _eval_argument(self, env: Environment) -> Any:
value = extract_json(self.json_path, env.states.context_object.context_object_data)
return value


class ArgumentFunction(Argument):
function: Final[EvalComponent]

def __init__(self, function: EvalComponent):
self.function = function

def _eval_argument(self, env: Environment) -> Any:
self.function.eval(env=env)
output_value = env.stack.pop()
return output_value


class ArgumentVar(Argument):
string_variable_sample: Final[StringVariableSample]

def __init__(self, string_variable_sample: StringVariableSample):
super().__init__()
self.string_variable_sample = string_variable_sample

def _eval_argument(self, env: Environment) -> Any:
self.string_variable_sample.eval(env=env)
value = env.stack.pop()
return value


class ArgumentList(Argument):
arguments: Final[list[Argument]]
size: Final[int]

def __init__(self, arguments: list[Argument]):
self.arguments = arguments
self.size = len(arguments)

def _eval_argument(self, env: Environment) -> Any:
values = list()
for argument in self.arguments:
argument.eval(env=env)
argument_value = env.stack.pop()
values.append(argument_value)
return values

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@
from typing import Final

from localstack.services.stepfunctions.asl.component.eval_component import EvalComponent
from localstack.services.stepfunctions.asl.component.intrinsic.argument.function_argument_list import (
FunctionArgumentList,
)
from localstack.services.stepfunctions.asl.component.intrinsic.argument.argument import ArgumentList
from localstack.services.stepfunctions.asl.component.intrinsic.functionname.function_name import (
FunctionName,
)


class Function(EvalComponent, abc.ABC):
name: FunctionName
argument_list: Final[ArgumentList]

def __init__(self, name: FunctionName, arg_list: FunctionArgumentList):
def __init__(self, name: FunctionName, argument_list: ArgumentList):
self.name = name
self.arg_list: Final[FunctionArgumentList] = arg_list
self.argument_list = argument_list
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any

from localstack.services.stepfunctions.asl.component.intrinsic.argument.function_argument_list import (
FunctionArgumentList,
from localstack.services.stepfunctions.asl.component.intrinsic.argument.argument import (
ArgumentList,
)
from localstack.services.stepfunctions.asl.component.intrinsic.function.statesfunction.states_function import (
StatesFunction,
Expand All @@ -16,13 +16,13 @@


class Array(StatesFunction):
def __init__(self, arg_list: FunctionArgumentList):
def __init__(self, argument_list: ArgumentList):
super().__init__(
states_name=StatesFunctionName(function_type=StatesFunctionNameType.Array),
arg_list=arg_list,
argument_list=argument_list,
)

def _eval_body(self, env: Environment) -> None:
self.arg_list.eval(env=env)
self.argument_list.eval(env=env)
values: list[Any] = env.stack.pop()
env.stack.append(values)
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from localstack.services.stepfunctions.asl.component.intrinsic.argument.function_argument_list import (
FunctionArgumentList,
from localstack.services.stepfunctions.asl.component.intrinsic.argument.argument import (
ArgumentList,
)
from localstack.services.stepfunctions.asl.component.intrinsic.function.statesfunction.states_function import (
StatesFunction,
Expand Down Expand Up @@ -28,18 +28,18 @@ class ArrayContains(StatesFunction):
#
# Returns:
# true
def __init__(self, arg_list: FunctionArgumentList):
def __init__(self, argument_list: ArgumentList):
super().__init__(
states_name=StatesFunctionName(function_type=StatesFunctionNameType.ArrayContains),
arg_list=arg_list,
argument_list=argument_list,
)
if arg_list.size != 2:
if argument_list.size != 2:
raise ValueError(
f"Expected 2 arguments for function type '{type(self)}', but got: '{arg_list}'."
f"Expected 2 arguments for function type '{type(self)}', but got: '{argument_list}'."
)

def _eval_body(self, env: Environment) -> None:
self.arg_list.eval(env=env)
self.argument_list.eval(env=env)
args = env.stack.pop()

array = args[0]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from localstack.services.stepfunctions.asl.component.intrinsic.argument.function_argument_list import (
FunctionArgumentList,
from localstack.services.stepfunctions.asl.component.intrinsic.argument.argument import (
ArgumentList,
)
from localstack.services.stepfunctions.asl.component.intrinsic.function.statesfunction.states_function import (
StatesFunction,
Expand Down Expand Up @@ -28,18 +28,18 @@ class ArrayGetItem(StatesFunction):
#
# Returns
# 6
def __init__(self, arg_list: FunctionArgumentList):
def __init__(self, argument_list: ArgumentList):
super().__init__(
states_name=StatesFunctionName(function_type=StatesFunctionNameType.ArrayGetItem),
arg_list=arg_list,
argument_list=argument_list,
)
if arg_list.size != 2:
if argument_list.size != 2:
raise ValueError(
f"Expected 2 arguments for function type '{type(self)}', but got: '{arg_list}'."
f"Expected 2 arguments for function type '{type(self)}', but got: '{argument_list}'."
)

def _eval_body(self, env: Environment) -> None:
self.arg_list.eval(env=env)
self.argument_list.eval(env=env)
args = env.stack.pop()

index = args.pop()
Expand Down
Loading
Loading