workfloworchestrator / orchestrator-core

The workflow orchestrator core repository
Apache License 2.0
40 stars 14 forks source link

[Bug]: `list[Any]` as type annotation for step function arguments throws AttributeError #588

Open Sparrow1029 opened 6 months ago

Sparrow1029 commented 6 months ago

Contact Details

awray2@es.net

What happened?

When a function wrapped with the @step decorator defines an argument of type list[typing.Any], the _build_arguments function in orchestrator/utils/state.py hits this code block:

https://github.com/workfloworchestrator/orchestrator-core/blob/0418589847e7560718cabfc9b3a756c3392e56d0/orchestrator/utils/state.py#L184-L189

Because typing.Any is compatible with any type, and any method call is considered valid, the code attempts to serialize the list objects into SubscriptionModels via the from_subscription method, which throws an attribute error.

Version

2.0.0

What python version are you seeing the problem on?

Python 3.11

Relevant log output

│                                                                                                  │
│ /usr/local/lib/python3.11/site-packages/orchestrator/utils/state.py:189 in <listcomp>            │
│                                                                                                  │
│   186 │   │   │   │   subscription_ids = map(_get_sub_id, state.get(name, []))                   │
│   187 │   │   │   │   subscriptions = [                                                          │
│   188 │   │   │   │   │   # Actual type is first argument from list type                         │
│ ❱ 189 │   │   │   │   │   get_args(param.annotation)[0].from_subscription(subscription_id)       │
│   190 │   │   │   │   │   for subscription_id in subscription_ids                                │
│   191 │   │   │   │   ]                                                                          │
│   192 │   │   │   │   arguments.append(subscriptions)                                            │
│                                                                                                  │
│ ╭───────────────────────── locals ──────────────────────────╮                                    │
│ │              .0 = <map object at 0xffff817f2d70>          │                                    │
│ │           param = <Parameter "esdb_resources: List[Any]"> │                                    │
│ │ subscription_id = None                                    │                                    │
│ ╰───────────────────────────────────────────────────────────╯                                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
AttributeError: type object 'Any' has no attribute 'from_subscription
pboers1988 commented 6 months ago

@Sparrow1029 Seems like you hit a cornercase. Is the type you are trying to serialise actually Any? If possible I would suggest to use the actual type you want. I think the preferred solution to this bug, would be to raise a readable error and suggest the user to use the "actual" type they want or otherwise use the "state" paramater, and do state.get("variable"). Correct casting from the database can only go so far.

I've created an internal issue to write a fix.

Sparrow1029 commented 6 months ago

@pboers1988 You are correct that Any was not the actual type (it was supposed to be dict[str, ...] I think). For sure not using Any is the solution, but since I ran into it, figured I'd report it. Providing a meaningful error message is the right approach for a fix. Thanks for your response -- also I'm happy to take the task and make an MR!

anieuwland commented 5 months ago

Providing a meaningful error message is the right approach for a fix.

We agree that this is the best solution. Would be great to receive an MR for this, thanks!