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

Allow returning Response from admin @action callbacks #1331

Merged

Conversation

christianbundy
Copy link
Contributor

@christianbundy christianbundy commented Jan 22, 2023

Problem: The Django docs say that you can "return an HttpResponse (or subclass) from your action", but the stubs currently say that actions can only return None.

Solution: Update stubs to return HttpResponse | None instead.

Related issues

Closes #1330

Documentation: https://docs.djangoproject.com/en/4.1/ref/contrib/admin/actions/#actions-that-provide-intermediate-pages

@intgr
Copy link
Collaborator

intgr commented Jan 23, 2023

Pinging @flaeppe for visibility.

@intgr
Copy link
Collaborator

intgr commented Jan 23, 2023

Thanks for the PR!

Please add a test case to tests/typecheck/contrib/admin/test_decorators.yml as well. Preferrably into the existing test_admin_decorators_action testcase, as more tests slow down the test suite.

@intgr
Copy link
Collaborator

intgr commented Jan 23, 2023

The failures from test suite aren't really issues, you just need to update the expected messages in the test cases. https://github.com/typeddjango/django-stubs/actions/runs/3983617421/jobs/6832674566

btw you can run individual tests locally with e.g. pytest -k errors_for_invalid_action_signature

Copy link
Contributor

@ngnpope ngnpope left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to have some tests to prevent future regressions.

django-stubs/contrib/admin/decorators.pyi Outdated Show resolved Hide resolved
django-stubs/contrib/admin/decorators.pyi Show resolved Hide resolved
@christianbundy
Copy link
Contributor Author

Thanks y'all! I appreciate the quick reviews.

Just pushed some changes to resolve these issues, please let me know what you think.

@@ -17,21 +17,21 @@ _QuerySet = TypeVar("_QuerySet", bound=QuerySet)
# This is deliberately different from _DisplayT defined in contrib.admin.options
_DisplayCallable: TypeAlias = Union[Callable[[_ModelAdmin, _Model], Any], Callable[[_Model], Any]] # noqa: Y037
_DisplayCallableT = TypeVar("_DisplayCallableT", bound=_DisplayCallable)
_ActionCallable: TypeAlias = Callable[[_ModelAdmin, _Request, _QuerySet], HttpResponseBase | None] # noqa: Y037
_ActionCallableT = TypeVar("_ActionCallableT", bound=_ActionCallable)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there was a good reason why these Callable[...] were duplicated before at each overload.

I'm not sure why exactly -- maybe mypy doesn't support TypeVars inside TypeVars -- but after your changes, this no longer raises an error with mypy at the location of the decorator:

    @admin.action(description="Some text here", permissions=["test"])
    def freestanding_action_fancy(modeladmin: int, request: int, queryset: int) -> None: ...

I suppose this logic could also use a few negative test cases -- checking that mypy correctly flags incorrect usage of the parameters or return types.

Copy link
Member

@flaeppe flaeppe Jan 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, TypeVar can't be bound to a TypeAlias, it'll resolve to Any before it's matched with generic arguments of a class or a callable.

A few non-happy test cases should make that obvious.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I've reverted the previous change and added more tests to highlight this issue. I've left _DisplayCallableT alone, but I'd imagine it probably has a similar problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see… Yes, if it's a problem, then the equivalent for display is also surely broken.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether it'd be worthwhile to enable disallow_any_generics for this repo -- I put together a quick repro, and it looks like if we enable the rule we'll get warnings for this: https://mypy-play.net/?mypy=latest&python=3.11&flags=disallow-any-generics&gist=bf198a38181d36c2105ce3fef468d702

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe, but best looked into separately later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid the fallout from disallow_any_generics will be enormous. But I may be wrong :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found 630 errors in 155 files (checked 675 source files)

You aren't wrong. 😬 Here's a quick stab at it though: #1339

@christianbundy christianbundy requested review from intgr and ngnpope and removed request for intgr January 24, 2023 01:26
Copy link
Collaborator

@intgr intgr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks great! I'll merge this later unless someone else has additional feedback.

@intgr intgr changed the title Fix admin action return type Allow returning Response from admin @action callbacks Jan 24, 2023
@intgr intgr merged commit 832163d into typeddjango:master Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Recent change to admin action decorators bans return values
4 participants