Skip to content

_TaskDecorator has no __wrapped__ attribute in v2.3.0 #23688

Closed

Description

@ddeepwell

Apache Airflow version

2.3.0 (latest released)

What happened

I run a unit test on a task which is defined using the task decorator. In the unit test, I unwrap the task decorator with the __wrapped__ attribute, but this no longer works in v2.3.0. It works in v2.2.5.

What you think should happen instead

I expect the wrapped function to be returned. This was what occurred in v2.2.5

When running pytest on the airflow v2.3.0 the following error is thrown:
AttributeError: '_TaskDecorator' object has no attribute '__wrapped__'

How to reproduce

Here's a rough outline of the code.

A module hello.py contains the task definition:

from airflow.decorators import task

@task
def hello_airflow():
    print('hello airflow')

and the test contains

from hello import hello_airflow

def test_hello_airflow():
    hello_airflow.__wrapped__()

Then run pytest

Operating System

Rocky Linux 8.5 (Green Obsidian)

Versions of Apache Airflow Providers

No response

Deployment

Virtualenv installation

Deployment details

No response

Anything else

No response

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Code of Conduct

Activity

  1. boring-cyborg commented on May 12, 2022

    @boring-cyborg

    Thanks for opening your first issue here! Be sure to follow the issue template!

  2. uranusjr commented on May 12, 2022

    @uranusjr
    Member

    Unfortunately the decorator using functools.wraps() under the hood (which is responsible for __wrapped__) is an implementation detail, and we never thought about keeping compatibility. It could still be added easily enough though (just add a @property on _TaskDecorator) and I guess no-one would really complain. Would you mind working on a PR for this?

  3. added and removed
    kind:bugThis is a clearly a bug
    on May 12, 2022
  4. ddeepwell commented on May 12, 2022

    @ddeepwell
    Author

    I would be happy to work on this, but I don't really know where to begin.

  5. uranusjr commented on May 12, 2022

    @uranusjr
    Member

    Simply search in airflow/decorators/base.py:

    1. In class _TaskDecorator (the one with a leading underscore), add

      @property
      def __wrapped__(self) -> Function:
          return self.function
    2. In class TaskDecorator (the one without an underscore), add

      @property
      def __wrapped__(self) -> Function:
          ...

    The first class adds the actual property (so you can access this in tests), while the other declares the interface. The second one is not strictly necessary, but it’s good to provide it for editor autocompletion and stuff.

  6. snjypl commented on May 17, 2022

    @snjypl
    Contributor

    @uranusjr @ddeepwel do you mind if i create a PR for this?

  7. uranusjr commented on May 17, 2022

    @uranusjr
    Member

    Go ahead

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions