Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: 'type' object is not subscriptable #80

Open
mdantonio opened this issue Jun 5, 2022 · 8 comments
Open

TypeError: 'type' object is not subscriptable #80

mdantonio opened this issue Jun 5, 2022 · 8 comments
Labels
bug Something isn't working documentation Improvements or additions to documentation

Comments

@mdantonio
Copy link

Hello!

I have a problem with the new Task annotations.
I installed version 0.13.0 and started receiving typing errors on Task annotations (from #75)

Missing type parameters for generic type "Task"

So added the expected annotations, like:

from celery.app.task import Task
from typing import Any

@app.task(bind=True)
def my_task(self: Task[Any, Any]):

But now celery (version 5.2.7) fails at runtime with:

    self: Task[Any, Any],
          │    │    └ typing.Any
          │    └ typing.Any
          └ <class 'celery.app.task.Task'>

TypeError: 'type' object is not subscriptable

What I'm missing? 😢

@sbdchd
Copy link
Owner

sbdchd commented Jun 6, 2022

Oh at runtime, yeah I need to update the docs, you'll need to monkey patch Task to accept a generic argument:

 Task.__class_getitem__ = classmethod(lambda cls, *args, **kwargs: cls)  # type: ignore [attr-defined]

@sbdchd sbdchd added bug Something isn't working documentation Improvements or additions to documentation labels Jun 6, 2022
@sbdchd
Copy link
Owner

sbdchd commented Jun 6, 2022

Another option is to do something like:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    class AnyTask[Any, Any]: ...
else:
    AnyTask = Task

from celery.app.task import Task
from typing import Any

@app.task(bind=True)
def my_task(self: AnyTask): ...

@craiga
Copy link

craiga commented Jun 6, 2022

Would it be possible for this library to provide something like django_stubs_ext to do this for us?

@sbdchd
Copy link
Owner

sbdchd commented Jun 6, 2022

Yeah that’s possible but then we’d need to have a second package and it’s only a couple lines of code to copy

@henribru
Copy link
Contributor

henribru commented Jun 8, 2022

In most cases you can get away with just sticking from __future__ import annotations at the top of your file. As long as the subscripting is in a "type annotation position" that will stop it from being evaluated at runtime. It won't help if it's in a "runtime position" though, like if you inherit from Task or use it in typing.cast or something.

@mdantonio
Copy link
Author

Oh at runtime, yeah I need to update the docs, you'll need to monkey patch Task to accept a generic argument:

 Task.__class_getitem__ = classmethod(lambda cls, *args, **kwargs: cls)  # type: ignore [attr-defined]

Ok, thank you for the clarification 👍

@NixBiks
Copy link

NixBiks commented Jan 1, 2023

Is it the same if I want to use from celery.result import AsyncResult? Is it then safe to do the following in order to allow for generics?

 AsyncResult.__class_getitem__ = classmethod(lambda cls, *args, **kwargs: cls)  # type: ignore [attr-defined]

@sbdchd
Copy link
Owner

sbdchd commented Jan 1, 2023

Yeah monkey patching __class_getitem__ should always be safe in Celery as they don't use that method at all

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

5 participants