mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-08 13:04:47 +08:00
request.user has type of AUTH_USER_MODEL
This commit is contained in:
@@ -17,8 +17,10 @@ from typing import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from django.contrib.sessions.backends.base import SessionBase
|
from django.contrib.sessions.backends.base import SessionBase
|
||||||
|
from django.db.models.base import Model
|
||||||
from django.utils.datastructures import CaseInsensitiveMapping, ImmutableList, MultiValueDict
|
from django.utils.datastructures import CaseInsensitiveMapping, ImmutableList, MultiValueDict
|
||||||
|
|
||||||
|
from django.contrib.auth.base_user import AbstractBaseUser
|
||||||
from django.core.files import uploadedfile, uploadhandler
|
from django.core.files import uploadedfile, uploadhandler
|
||||||
from django.urls import ResolverMatch
|
from django.urls import ResolverMatch
|
||||||
|
|
||||||
@@ -49,6 +51,7 @@ class HttpRequest(BytesIO):
|
|||||||
resolver_match: ResolverMatch = ...
|
resolver_match: ResolverMatch = ...
|
||||||
content_type: Optional[str] = ...
|
content_type: Optional[str] = ...
|
||||||
content_params: Optional[Dict[str, str]] = ...
|
content_params: Optional[Dict[str, str]] = ...
|
||||||
|
user: AbstractBaseUser
|
||||||
session: SessionBase
|
session: SessionBase
|
||||||
encoding: Optional[str] = ...
|
encoding: Optional[str] = ...
|
||||||
upload_handlers: UploadHandlerList = ...
|
upload_handlers: UploadHandlerList = ...
|
||||||
|
|||||||
@@ -36,3 +36,4 @@ RELATED_FIELDS_CLASSES = {
|
|||||||
|
|
||||||
MIGRATION_CLASS_FULLNAME = 'django.db.migrations.migration.Migration'
|
MIGRATION_CLASS_FULLNAME = 'django.db.migrations.migration.Migration'
|
||||||
OPTIONS_CLASS_FULLNAME = 'django.db.models.options.Options'
|
OPTIONS_CLASS_FULLNAME = 'django.db.models.options.Options'
|
||||||
|
HTTPREQUEST_CLASS_FULLNAME = 'django.http.request.HttpRequest'
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ def lookup_fully_qualified_typeinfo(api: TypeChecker, fullname: str) -> Optional
|
|||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
||||||
def lookup_class_typeinfo(api: TypeChecker, klass: type) -> TypeInfo:
|
def lookup_class_typeinfo(api: TypeChecker, klass: type) -> Optional[TypeInfo]:
|
||||||
fullname = get_class_fullname(klass)
|
fullname = get_class_fullname(klass)
|
||||||
field_info = lookup_fully_qualified_typeinfo(api, fullname)
|
field_info = lookup_fully_qualified_typeinfo(api, fullname)
|
||||||
return field_info
|
return field_info
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from mypy.types import Type as MypyType
|
|||||||
|
|
||||||
from mypy_django_plugin.django.context import DjangoContext
|
from mypy_django_plugin.django.context import DjangoContext
|
||||||
from mypy_django_plugin.lib import fullnames, helpers
|
from mypy_django_plugin.lib import fullnames, helpers
|
||||||
from mypy_django_plugin.transformers import fields, forms, init_create, querysets, settings, meta
|
from mypy_django_plugin.transformers import fields, forms, init_create, querysets, settings, meta, request
|
||||||
from mypy_django_plugin.transformers.models import process_model_class
|
from mypy_django_plugin.transformers.models import process_model_class
|
||||||
|
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ class NewSemanalDjangoPlugin(Plugin):
|
|||||||
|
|
||||||
# for `get_user_model()`
|
# for `get_user_model()`
|
||||||
if self.django_context.settings:
|
if self.django_context.settings:
|
||||||
if file.fullname() == 'django.contrib.auth':
|
if (file.fullname() == 'django.contrib.auth') or (file.fullname() in {'django.http', 'django.http.request'}):
|
||||||
auth_user_model_name = self.django_context.settings.AUTH_USER_MODEL
|
auth_user_model_name = self.django_context.settings.AUTH_USER_MODEL
|
||||||
try:
|
try:
|
||||||
auth_user_module = self.django_context.apps_registry.get_model(auth_user_model_name).__module__
|
auth_user_module = self.django_context.apps_registry.get_model(auth_user_model_name).__module__
|
||||||
@@ -204,6 +204,11 @@ class NewSemanalDjangoPlugin(Plugin):
|
|||||||
return partial(settings.get_type_of_settings_attribute,
|
return partial(settings.get_type_of_settings_attribute,
|
||||||
django_context=self.django_context)
|
django_context=self.django_context)
|
||||||
|
|
||||||
|
info = self._get_typeinfo_or_none(class_name)
|
||||||
|
if info and info.has_base(fullnames.HTTPREQUEST_CLASS_FULLNAME):
|
||||||
|
return partial(request.set_auth_user_model_as_type_for_request_user, django_context=self.django_context)
|
||||||
|
|
||||||
|
|
||||||
# def get_type_analyze_hook(self, fullname: str
|
# def get_type_analyze_hook(self, fullname: str
|
||||||
# ( ):
|
# ( ):
|
||||||
# info = self._get_typeinfo_or_none(fullname)
|
# info = self._get_typeinfo_or_none(fullname)
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ def get_referred_to_model_fullname(ctx: FunctionContext, django_context: DjangoC
|
|||||||
return to_arg_type.ret_type.type.fullname()
|
return to_arg_type.ret_type.type.fullname()
|
||||||
|
|
||||||
outer_model_info = ctx.api.scope.active_class()
|
outer_model_info = ctx.api.scope.active_class()
|
||||||
# if not outer_model_info or not outer_model_info.has_base(fullnames.MODEL_CLASS_FULLNAME):
|
|
||||||
# # not inside models.Model class
|
|
||||||
# return None
|
|
||||||
assert isinstance(outer_model_info, TypeInfo)
|
assert isinstance(outer_model_info, TypeInfo)
|
||||||
|
|
||||||
to_arg_expr = helpers.get_call_argument_by_name(ctx, 'to')
|
to_arg_expr = helpers.get_call_argument_by_name(ctx, 'to')
|
||||||
|
|||||||
15
mypy_django_plugin/transformers/request.py
Normal file
15
mypy_django_plugin/transformers/request.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from mypy.plugin import AttributeContext
|
||||||
|
from mypy.types import Instance, Type as MypyType
|
||||||
|
|
||||||
|
from mypy_django_plugin.django.context import DjangoContext
|
||||||
|
from mypy_django_plugin.lib import helpers
|
||||||
|
|
||||||
|
|
||||||
|
def set_auth_user_model_as_type_for_request_user(ctx: AttributeContext, django_context: DjangoContext) -> MypyType:
|
||||||
|
auth_user_model = django_context.settings.AUTH_USER_MODEL
|
||||||
|
model_cls = django_context.apps_registry.get_model(auth_user_model)
|
||||||
|
model_info = helpers.lookup_class_typeinfo(ctx.api, model_cls)
|
||||||
|
if model_info is None:
|
||||||
|
return ctx.default_attr_type
|
||||||
|
|
||||||
|
return Instance(model_info, [])
|
||||||
16
test-data/typecheck/test_request.yml
Normal file
16
test-data/typecheck/test_request.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
- case: request_object_has_user_of_type_auth_user_model
|
||||||
|
disable_cache: true
|
||||||
|
main: |
|
||||||
|
from django.http.request import HttpRequest
|
||||||
|
reveal_type(HttpRequest().user) # N: Revealed type is 'myapp.models.MyUser'
|
||||||
|
installed_apps:
|
||||||
|
- myapp
|
||||||
|
additional_settings:
|
||||||
|
- AUTH_USER_MODEL='myapp.MyUser'
|
||||||
|
files:
|
||||||
|
- path: myapp/__init__.py
|
||||||
|
- path: myapp/models.py
|
||||||
|
content: |
|
||||||
|
from django.db import models
|
||||||
|
class MyUser(models.Model):
|
||||||
|
pass
|
||||||
Reference in New Issue
Block a user