sdaberdaku opened a new issue, #30599:
URL: https://github.com/apache/airflow/issues/30599

   ### Apache Airflow version
   
   2.5.3
   
   ### What happened
   
   Pleas consider the following scenario
   ```python
   from typing import TYPE_CHECKING
   if TYPE_CHECKING:
       from my_package import MyClass
   
   @task
   def foo(a: int, b: str, c: "MyClass"): 
       pass
   ```
   In this case, the DAG parsing will fail with a NameError from the 
`_infer_multiple_outputs` method of `_TaskDecorator` class in 
`airflow/decorators/base.py`.
   
   Please note that this is a common pattern when managing multiple tasks with 
varying dependencies and docker containers, and `my_package` might not be 
available in some of them.
   
   ### What you think should happen instead
   
   The problem relies in the following method using 
typing_extensions.get_type_hints:
   ```python
   @multiple_outputs.default
   def _infer_multiple_outputs(self):
       try:
           return_type = 
typing_extensions.get_type_hints(self.function).get("return", Any)
       except TypeError:  # Can't evaluate return type.
           return False
       ttype = getattr(return_type, "__origin__", return_type)
       return ttype == dict or ttype == Dict
   ``` 
   which will result in the following error at DAG parse time:
   `E   NameError: name 'MyClass' is not defined`
   
   
   To fix this, the method could just use the `__annotations__` attribute of 
`self.function` instead which does not complain about the existence of the 
annotated types, like so:
   ```python
   @multiple_outputs.default
   def _infer_multiple_outputs(self):
       try:
           return_type = self.function.__annotations__.get("return", Any)
       except TypeError:  # Can't evaluate return type.
           return False
       ttype = getattr(return_type, "__origin__", return_type)
       return ttype == dict or ttype == Dict
   ```
   This should work fine since we are interested in the return type annotation 
anyway.
   
   One quick fix for the programmers having this issue could simply be to add 
an `else` clause to their `if TYPE_CHECKING` statement, like so:
    ```python
   if TYPE_CHECKING:
       from my_package import MyClass
   else:
       from typing import Any as MyClass
   ```
   
   ### How to reproduce
   
   ```python
   from airflow.annotations import task
   from typing import TYPE_CHECKING
   if TYPE_CHECKING:
       from my_package import MyClass
   
   @task
   def foo(a: int, b: str, c: "MyClass"): 
       pass
   ```
   
   ### Operating System
   
   Linux Mint 21
   
   ### Versions of Apache Airflow Providers
   
   _No response_
   
   ### Deployment
   
   Official Apache Airflow Helm Chart
   
   ### Deployment details
   
   _No response_
   
   ### Anything else
   
   _No response_
   
   ### Are you willing to submit PR?
   
   - [X] Yes I am willing to submit a PR!
   
   ### Code of Conduct
   
   - [X] I agree to follow this project's [Code of 
Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to