Skip to content

feat: Tasks returning multiple results #15

Description

@AncientPatata

Make it possible for tasks to return multiple results (as in, return different object handles), this will allow for more granulare control in certain scenarios; This can be done with a simple multiple method that takes in the different object handles to create

@task
def my_task(x):
    if x:
        return multiple(1,2,4)
    else: 
        return multiple(1,2,3)
    

When the task decorator detects this it doesn't create an Armonik result handle and just uses the already created ones.
We can also give names to the different results multiple((1,2),(3,4), names=["a","b"]) but ideally the user should treat them like tuples on their end. (won't access them by name)
We'd have to guarantee that for all the different execution paths we return the same number of results, using a method allows us to gently handle the cases of returning lists/tuples for instance. We can also use Python's inspect module during function registration to check if the constraint is respected and to also create the necessary number of result handles during invocation.

import ast
import inspect
from functools import wraps
from collections import defaultdict

class ParameterConsistencyChecker(ast.NodeVisitor):
    def __init__(self, function_names_to_check="multiple"):
        self.function_calls = defaultdict(list)
        self.function_names_to_check = function_names_to_check or set()
    
    def visit_Call(self, node):
        # Handle direct function calls (e.g., multiple(1, 2, 3))
        if isinstance(node.func, ast.Name):
            func_name = node.func.id
            if not self.function_names_to_check or func_name in self.function_names_to_check:
                arg_count = len(node.args) + len(node.keywords)
                self.function_calls[func_name].append(arg_count)
        
        # Handle attribute calls (e.g., obj.multiple(1, 2, 3))
        elif isinstance(node.func, ast.Attribute):
            func_name = node.func.attr
            if not self.function_names_to_check or func_name in self.function_names_to_check:
                arg_count = len(node.args) + len(node.keywords)
                self.function_calls[func_name].append(arg_count)
        
        # Continue visiting child nodes
        self.generic_visit(node)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions