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 generic requests, responses, fields, views #8825

Merged
merged 2 commits into from Feb 22, 2023

Conversation

jalaziz
Copy link
Contributor

@jalaziz jalaziz commented Jan 2, 2023

Description

Allow Request, Response, Field, and GenericAPIView to be subscriptable. This is a follow up to #7385 and allows the classes to be made generic for type checking.

By making these classes generic, type checkers can more easily do their job when working with DRF classes. Today,
django-stubs and djangorestframework-stubs must monkey patch types to support generic typing, but the approach is problematic with DRF since DRF eagerly loads settings resulting in issues like this.

@tomchristie
Copy link
Member

Can you explain why this is useful?

@jalaziz
Copy link
Contributor Author

jalaziz commented Jan 2, 2023

@tomchristie I've updated the PR description with more details.

@jalaziz
Copy link
Contributor Author

jalaziz commented Jan 2, 2023

To carry on the conversation from #7385. The types are being used to infer and check the types returned from methods like: get_queryset(), get_object(), etc. With it, we don't need to cast into the correct return types as it can be accurately inferred.

Django has already shipped subscription for QuerySets and other classes which helps avoid the need for monkey patching, but DRF is still missing some key classes.

@jalaziz jalaziz force-pushed the jameel/type-checking-improvements branch 2 times, most recently from c55dab3 to 581fa59 Compare January 7, 2023 22:48
@jalaziz
Copy link
Contributor Author

jalaziz commented Jan 7, 2023

Rebased to ensure the tests pass.

@auvipy auvipy requested a review from rpkilby January 9, 2023 15:25
@melotte25
Copy link

Not to be a pain, but could another reviewer such as @auvipy take a look at this? We're upgrading to the latest mypy and djangorestframework-stubs, and this would be great to get implemented to save a lot of repeat code (DRY!).

Thank you!

@tomchristie
Copy link
Member

By making these classes generic, type checkers can more easily do their job when working with DRF classes.

  • Could you show me a concrete type-checking issue that this change resolves?
  • Is this only useful together with the django-restframeworkstubs package?
  • Django doesn't appear to have adopted __class_getitem__ for it's generic views or for QuerySets and Managers. I'd normally expect us to follow Django's lead on this kind of design issue. Is there any context we can see there involving similar design discussions against the Django project?

@jalaziz
Copy link
Contributor Author

jalaziz commented Feb 21, 2023

By making these classes generic, type checkers can more easily do their job when working with DRF classes.

  • Could you show me a concrete type-checking issue that this change resolves?

It doesn't solve a type-checking issue per se, it solves a problem that occurs when you try to monkey-patch type support. Will try to put up an example project to show the issue, but fundamentally the issue is, unlike Django, DRF eagerly loads settings on import which results in improper settings when trying to monkey patch classes too early.

  • Is this only useful together with the django-restframeworkstubs package?

Yes and no. Today, django-restframeworkstubs provides support for typing where DRF lacks typing support. There's nothing stopping another stubs implementation or for DRF to provide native typing support.

  • Django doesn't appear to have adopted __class_getitem__ for it's generic views or for QuerySets and Managers. I'd normally expect us to follow Django's lead on this kind of design issue. Is there any context we can see there involving similar design discussions against the Django project?

Django does support __class_getitem__ for QuerySets, Managers, and ForeignKey. It's true that support hasn't been added for generic views, but that's just a matter of someone contributing support, I believe.

@jalaziz
Copy link
Contributor Author

jalaziz commented Feb 22, 2023

@tomchristie here's a test repo exhibiting some issues: https://github.com/jalaziz/drf-test-repo

As it stands, we end up with no pagination because of the eager settings issue (despite pagination being set):

> curl -H 'Accept: application/json; indent=4' http://127.0.0.1:8000/users/
[]

For this repo, the workaround is to move the monkey patching to after the REST_FRAMEWORK definition, but that doesn't work for more complicate setups with nested settings files.

@jalaziz jalaziz changed the title Allow generic requets, responses, fields, views Allow generic requests, responses, fields, views Feb 22, 2023
Allow Request, Response, Field, and GenericAPIView to be subscriptable.
This allows the classes to be made generic for type checking.

This is especially useful since monkey patching DRF can be problematic
as seen in this [issue][1].

[1]: typeddjango/djangorestframework-stubs#299
@jalaziz jalaziz force-pushed the jameel/type-checking-improvements branch from 581fa59 to c066dfe Compare February 22, 2023 04:42
Copy link
Member

@tomchristie tomchristie left a comment

Choose a reason for hiding this comment

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

Django does support __class_getitem__ for QuerySets, Managers, and ForeignKey.

This wins the case for you.

@tomchristie
Copy link
Member

Merging the latest master branch might resolve the failing pre-commit check...?

@auvipy auvipy added this to the 3.15 milestone Feb 22, 2023
@auvipy auvipy merged commit 15c613a into encode:master Feb 22, 2023
@auvipy
Copy link
Member

auvipy commented Feb 22, 2023

all green now! thanks

@auvipy auvipy removed the request for review from rpkilby February 22, 2023 15:39
@auvipy
Copy link
Member

auvipy commented Feb 22, 2023

Not to be a pain, but could another reviewer such as @auvipy take a look at this? We're upgrading to the latest mypy and djangorestframework-stubs, and this would be great to get implemented to save a lot of repeat code (DRY!).

Thank you!

sorry I missed the notification

@mschoettle
Copy link

@tomchristie I ran into the issue explained in the PR description. Are there any plans to make a release containing this fix?

@mschoettle
Copy link

Or maybe @auvipy can answer the question about a release?

@auvipy
Copy link
Member

auvipy commented Dec 6, 2023

Nope I can't. I don't have release access yet.

@pchabros
Copy link

It's still not released?

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

Successfully merging this pull request may close these issues.

None yet

6 participants