This commit is contained in:
Jesse Bannon 2024-06-03 14:19:09 -07:00
parent c32dfb065b
commit 9964cb48f1
3 changed files with 41 additions and 28 deletions

View file

@ -143,6 +143,24 @@ class Script:
f"{nested_custom_function.num_input_args}"
)
def _get_lambda_function_names_to_evaluate(self, function: BuiltInFunctionType) -> Set[str]:
lambda_function_names: Set[str] = set()
for lamb in SyntaxTree(function.args).lambdas:
if lamb in function.args:
lambda_function_names.add(lamb.value)
# See if the arg outputs a lambda (from an if).
# If so, add the possible lambda to be checked
for arg in function.args:
if (
isinstance(arg, BuiltInFunctionType)
and arg.output_type() == Lambda
and lamb in arg.args
):
lambda_function_names.add(lamb.value)
return lambda_function_names
def _ensure_lambda_usage_num_input_arguments_valid(
self, prefix: str, name: str, definition: SyntaxTree
):
@ -158,20 +176,7 @@ class Script:
if not (lambda_type := spec.is_lambda_like):
return
lambda_function_names: Set[str] = set()
for lamb in SyntaxTree(function.args).lambdas:
if lamb in function.args:
lambda_function_names.add(lamb.value)
# See if the arg outputs a lambda (from an if).
# If so, add the possible lambda to be checked
for arg in function.args:
if (
isinstance(arg, BuiltInFunctionType)
and arg.output_type() == Lambda
and lamb in arg.args
):
lambda_function_names.add(lamb.value)
lambda_function_names = self._get_lambda_function_names_to_evaluate(function=function)
# Only case len(lambda_function_names) > 1 is when used in if-statements
for lambda_function_name in lambda_function_names:

View file

@ -43,7 +43,7 @@ class VariableDependency(ABC):
output.append(arg)
elif instance and isinstance(arg, ttype):
output.append(arg)
elif type(arg) == ttype:
elif type(arg) == ttype: # pylint: disable=unidiomatic-typecheck
output.append(arg)
if isinstance(arg, VariableDependency):

View file

@ -53,6 +53,25 @@ def get_optional_type(optional_type: Type) -> Type[NamedType]:
return [arg for arg in optional_type.__args__ if arg != type(None)][0]
def _is_union_compatible(
arg_type: Type[NamedType],
expected_union_type: Type[Resolvable | Optional[Resolvable]],
) -> bool:
if issubclass(arg_type, (NamedCustomFunction, Variable)):
return True # custom-function/variable can be anything, so pass for now
# if the input arg is a union, do a direct comparison
if is_union(arg_type):
return arg_type == expected_union_type
# otherwise, iterate the union to see if it's compatible
for union_type in expected_union_type.__args__:
if issubclass(arg_type, union_type):
return True
return False
def _is_type_compatible(
arg_type: Type[NamedType],
expected_arg_type: Type[Resolvable | Optional[Resolvable]],
@ -63,22 +82,11 @@ def _is_type_compatible(
True if arg is compatible with expected_arg_type. False otherwise.
"""
if is_union(expected_arg_type):
if issubclass(arg_type, (NamedCustomFunction, Variable)):
return True # custom-function/variable can be anything, so pass for now
return _is_union_compatible(arg_type=arg_type, expected_union_type=expected_arg_type)
# if the input arg is a union, do a direct comparison
if is_union(arg_type):
return arg_type == expected_arg_type
# otherwise, iterate the union to see if it's compatible
for union_type in expected_arg_type.__args__:
if issubclass(arg_type, union_type):
return True
return False
# If the input is a union and the expected type is not, see if
# each possible union input is compatible with the expected type
elif is_union(arg_type):
if is_union(arg_type):
for union_type in arg_type.__args__:
if not _is_type_compatible(union_type, expected_arg_type):
return False