49 Commits

Author SHA1 Message Date
Maxim Kurnikov
c3d76f9a1e bump version 2019-03-10 20:03:00 +03:00
Maxim Kurnikov
fde071b883 fix classonlymethod, replace with six from typeshed 2019-03-10 19:56:54 +03:00
Seth Yastrov
324b961d74 Support returning the correct values for the different QuerySet methods when using .values() and .values_list(). (#33)
* Support returning the correct values for the different QuerySet methods when using .values() and .values_list().

* Fix slicing on QuerySet. Fix django queries test, and remove some ignored errors that are no longer needed.

* Remove accidental change in RawQuerySet.

* Readded some still-necessary ignores to aggregation django test.

* Add more tests of first/last/earliest/last/__getitem__, per mkurnikov's comments.

- Fix .iterator()

* Re-add Iterator as base-class of QuerySet.

* Make QuerySet a Collection.

* - Fix return type for QuerySet.select_for_update().
- Use correct return type for QuerySet.dates() / QuerySet.datetimes().
- Use correct type params in return type for QuerySet.__and__ / QuerySet.__or__
- Re-add Sized as base class for QuerySet.
- Add test of .all() for all _Row types.
- Add test of .get() for all _Row types.
- Remove some redundant QuerySet method tests.

* Automatically fill in second type parameter for QuerySet.

... if second parameter is omitted.
2019-03-10 12:13:50 +03:00
Seth Yastrov
86c63d790b Fix type errors on other models' managers when using objects = models.Manager() in Model. (#34)
* Fix bug where models with a class variable using a manager defined would interfere with other managers.

- Fill in the type argument for that particular instance of the manager, rather than modifying the bases of the Manager type.
- Instantiate a new Instance from determine_proper_manager_type so The code doesn't crash under mypy-mypyc.

* Use helpers.reparametrize_instance per review comment.

* Updated ignored errors in Django test for get_objects_or_404.

- For some reason, `Manager[nothing]` is now removed from expected types.
  However, I think this makes sense anyway, as Manager is a subclass of QuerySet.
2019-03-08 12:30:38 +03:00
Matt Basta
050c1b8887 Add gzip_page decorator (#41)
* Add gzip_page decorator

* Update to preserve Callable
2019-03-06 21:16:24 +03:00
Maxim Kurnikov
8978ad471f bump version 2019-03-06 12:05:24 +03:00
Richard Eames
f7dfbefbd6 Make CharField(blank=True) not be considered nullable (#39)
* Make CharField(blank=True) not be considered nullable

The documentation on [blank](https://docs.djangoproject.com/en/2.1/ref/models/fields/#blank) says that it "will allow the entry of an empty value", which for a string is just a 0-length string. This patch allows `CharField(blank=True,...)` to no longer be considered `Optional`.

closes #38

* fixed tests for `CharField(blank=True)`

* allow blank CharField to be nullable in the constructor, but the underlying type
is str (unless `null=True`)
2019-03-06 01:37:44 +03:00
Maxim Kurnikov
627daa55f5 fix extension of django.views __init__ file 2019-03-06 01:28:42 +03:00
Maxim Kurnikov
194489ee8d bump version 2019-03-05 20:21:43 +03:00
Maxim Kurnikov
1d2c7fb805 Remove _Val alias for MultiValueDict so that generic evaluate (#36)
* remove _Val alias for MultiValueDict so that generic evaluate

* fix multivaluedict init argument
2019-03-05 20:16:24 +03:00
Maxim Kurnikov
18c908bf98 set plugin_generated on new symbol nodes 2019-03-05 20:15:46 +03:00
Maxim Kurnikov
e0e8814804 Revert "dont convert to optional, if anytype"
This reverts commit 53f5d2214b.
2019-03-05 19:11:02 +03:00
Maxim Kurnikov
53f5d2214b dont convert to optional, if anytype 2019-03-05 18:43:10 +03:00
Maxim Kurnikov
9e4ed70fc5 Disable note: messages (#35)
* add global note: ignore
2019-03-01 05:15:05 +03:00
Maxim Kurnikov
18445f686f set fallback= for ini parser 2019-03-01 02:25:15 +03:00
Maxim Kurnikov
c962b8ac68 attempt to add flake8 and isort 2019-03-01 02:07:53 +03:00
Maxim Kurnikov
70c3126348 add plugin testing for python3.6 2019-02-27 18:12:29 +03:00
Maxim Kurnikov
af8ecc5520 remove django from dependencies, it's not required for static analysis 2019-02-27 18:11:54 +03:00
Maxim Kurnikov
64f8870d0b bump version 2019-02-27 17:59:04 +03:00
Maxim Kurnikov
df5c70c703 fixes for FormMixin's get_form/get_form_class 2019-02-25 04:01:36 +03:00
Maxim Kurnikov
c09a97e005 Merge pull request #29 from syastrov/queryset_in_bulk
QuerySet.in_bulk returns Dict with values of correct model type.
2019-02-22 23:23:36 +03:00
Seth Yastrov
0e30821ad3 Add possibility to pass list of test names as command-line arguments to typecheck_tests.py script. 2019-02-22 20:03:30 +01:00
Seth Yastrov
2dadd681ff Change in_bulk id_list param to Iterable rather than Sequence. 2019-02-22 20:03:20 +01:00
Seth Yastrov
2dec3b4325 Merge branch 'master' into queryset_in_bulk 2019-02-22 08:16:48 +01:00
Seth Yastrov
3b8c5d08e8 QuerySet.in_bulk fixes.
- Made id_list of type Sequence[Any], rather than Any, according to mkurnikov's review.
- Removed **kwargs.
- Made returned Dict keys of type Any rather than int or str as it depends on the provided field's type.
- Added test with examples from Django docs.
2019-02-22 08:13:31 +01:00
Maxim Kurnikov
eaee3d390f fix HttpResponse stubs by removing AnyStr 2019-02-22 03:22:11 +03:00
Maxim Kurnikov
b686751f19 fix some stubs 2019-02-22 02:55:49 +03:00
Maxim Kurnikov
73ea682356 rework django.views 2019-02-22 01:50:52 +03:00
Maxim Kurnikov
9ea25f3e56 bump version 2019-02-22 00:13:59 +03:00
Maxim Kurnikov
dacf88c692 optimize hooks a bit 2019-02-22 00:12:23 +03:00
Maxim Kurnikov
3d14d07e4e incremental = True for plugin tests should be fixed now 2019-02-21 17:35:46 +03:00
Maxim Kurnikov
6e6d1645d3 enable incremental mode for tests, disable it for one so that it would pass 2019-02-21 00:06:09 +03:00
Seth Yastrov
cda703a94b QuerySet.in_bulk returns Dict with values of correct model type.
- The keys are still Union[int, str] which doesn't cover all
possibilities, but it's not possible to cover without handling this in
the plugin, because the type of the Dict keys are dynamic depending on
which value for field_name you pass in.
2019-02-20 20:51:43 +01:00
Maxim Kurnikov
2bd018951b forms, generic views fixes 2019-02-20 22:24:26 +03:00
Maxim Kurnikov
14ea848dd7 add nested Meta inheritance support for forms 2019-02-20 21:52:28 +03:00
Maxim Kurnikov
2d3b5492f0 fix form errors in CI 2019-02-20 21:24:49 +03:00
Maxim Kurnikov
194258ab8e Merge pull request #23 from syastrov/better-types-for-transaction-atomic
Add better typings plus test for transaction.atomic.
2019-02-20 21:12:14 +03:00
Maxim Kurnikov
116aa2c539 clean up forms 2019-02-20 15:22:46 +03:00
Seth Yastrov
67c99434e5 Add better typings plus test for transaction.atomic.
- All cases are handled, including bare decorator (@transaction.atomic).
- Decorated function's signature is preserved when type-checking.
2019-02-20 06:40:22 +01:00
Maxim Kurnikov
5d8cdbcf29 fix integer set type 2019-02-20 02:38:45 +03:00
Maxim Kurnikov
78810f55b6 Merge pull request #26 from roderik333/supertype-processformview
*args and **kwargs changed from 'object' to 'str' and 'any' in post()…
2019-02-19 15:23:50 +03:00
Rune Steinnes
36662896bc *args and **kwargs changed from 'object' to 'str' and 'any' in post(), put() and get() 2019-02-19 12:48:07 +01:00
Maxim Kurnikov
e54dbb79c9 Merge pull request #24 from roderik333/replace-wsgirequest-in-loginrequiredmixin
Replaced WSGIRequest with http.HttpRequest in mixin:LoginRequiredMixin
2019-02-19 13:54:43 +03:00
Rune Steinnes
41f283552a Replaced WSGIRequest with http.HttpRequest in mixin:LoginRequiredMixin 2019-02-19 11:16:27 +01:00
Maxim Kurnikov
ab73d53ae5 add support for models defined in the same module be specified as name of class in related fields 2019-02-19 00:43:27 +03:00
Maxim Kurnikov
d24be4b35f add supported versions to README 2019-02-19 00:42:12 +03:00
Maxim Kurnikov
9d60b472df fix *args, **kwargs for views.generic.base 2019-02-18 15:45:01 +03:00
Maxim Kurnikov
632e063e22 back to incremental = True for tests 2019-02-18 02:16:13 +03:00
Maxim Kurnikov
66224416b5 bump version 2019-02-18 01:47:45 +03:00
110 changed files with 1626 additions and 1363 deletions

View File

@@ -4,20 +4,34 @@ dist: xenial
sudo: required
jobs:
include:
- name: Typecheck Django test suite
python: 3.7
script: 'python ./scripts/typecheck_tests.py'
- name: Run plugin test suite with python 3.7
python: 3.7
script: |
set -e
pytest
- name: Run plugin test suite with python 3.6
python: 3.6
script: |
set -e
pytest
- name: Typecheck Django test suite
python: 3.7
script: 'python ./scripts/typecheck_tests.py'
- name: Lint with black
python: 3.7
script: 'black --check --line-length=120 django-stubs/'
- name: Lint plugin code with flake8
python: 3.7
script: 'flake8'
- name: Lint plugin code with isort
python: 3.7
script: 'isort --check'
before_install: |
# Upgrade pip, setuptools, and wheel
pip install -U pip setuptools wheel

View File

@@ -7,6 +7,10 @@
This package contains type stubs and mypy plugin to provide more precise static types and type inference for Django framework. Django uses some Python "magic" that makes having precise types for some code patterns problematic. This is why we need to accompany the stubs with mypy plugins. The final goal is to be able to get precise types for most common patterns.
Supports Python 3.6/3.7, and Django 2.1.x series.
Could be run on earlier versions of Django, but expect some missing imports warnings.
## Installation
```

View File

@@ -1,3 +1,5 @@
black
pytest-mypy-plugins
flake8
isort==4.3.4
-e .

View File

@@ -5,7 +5,7 @@ by the DJANGO_SETTINGS_MODULE environment variable.
# This is defined here as a do-nothing function because we can't import
# django.utils.translation -- that module depends on the settings.
from typing import Any, Dict, List, Optional, Pattern, Tuple, Protocol, Union, Callable, TYPE_CHECKING
from typing import Any, Dict, List, Optional, Pattern, Tuple, Protocol, Union, Callable, TYPE_CHECKING, Sequence
####################
# CORE #
@@ -377,7 +377,7 @@ CACHE_MIDDLEWARE_ALIAS = "default"
AUTH_USER_MODEL: str = ...
AUTHENTICATION_BACKENDS: List[str] = ...
AUTHENTICATION_BACKENDS: Sequence[str] = ...
LOGIN_URL = "/accounts/login/"

View File

@@ -1,5 +1,5 @@
from collections import OrderedDict
from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Tuple, Type, Union, Iterator
from typing import Any, Callable, Dict, Iterator, List, Optional, Sequence, Set, Tuple, Type, Union
from django.contrib.admin.filters import ListFilter
from django.contrib.admin.models import LogEntry
@@ -8,7 +8,6 @@ from django.contrib.admin.views.main import ChangeList
from django.contrib.auth.forms import AdminPasswordChangeForm
from django.contrib.contenttypes.models import ContentType
from django.core.checks.messages import Error
from django.core.handlers.wsgi import WSGIRequest
from django.core.paginator import Paginator
from django.db.models.base import Model
from django.db.models.fields.related import ForeignKey, ManyToManyField, RelatedField
@@ -17,12 +16,13 @@ from django.db.models.query import QuerySet
from django.forms.fields import TypedChoiceField
from django.forms.models import ModelChoiceField, ModelMultipleChoiceField
from django.forms.widgets import Media
from django.http.request import HttpRequest
from django.http.response import HttpResponse, HttpResponseBase, HttpResponseRedirect, JsonResponse
from django.template.response import TemplateResponse
from django.urls.resolvers import URLPattern
from django.utils.safestring import SafeText
from django.db.models.fields import Field
from django.template.response import TemplateResponse
IS_POPUP_VAR: str
TO_FIELD_VAR: str
@@ -58,40 +58,40 @@ class BaseModelAdmin:
def check(self, **kwargs: Any) -> List[Union[str, Error]]: ...
def __init__(self) -> None: ...
def formfield_for_dbfield(
self, db_field: Field, request: Optional[WSGIRequest], **kwargs: Any
self, db_field: Field, request: Optional[HttpRequest], **kwargs: Any
) -> Optional[Field]: ...
def formfield_for_choice_field(
self, db_field: Field, request: Optional[WSGIRequest], **kwargs: Any
self, db_field: Field, request: Optional[HttpRequest], **kwargs: Any
) -> TypedChoiceField: ...
def get_field_queryset(
self, db: None, db_field: RelatedField, request: Optional[WSGIRequest]
self, db: None, db_field: RelatedField, request: Optional[HttpRequest]
) -> Optional[QuerySet]: ...
def formfield_for_foreignkey(
self, db_field: ForeignKey, request: Optional[WSGIRequest], **kwargs: Any
self, db_field: ForeignKey, request: Optional[HttpRequest], **kwargs: Any
) -> Optional[ModelChoiceField]: ...
def formfield_for_manytomany(
self, db_field: ManyToManyField, request: Optional[WSGIRequest], **kwargs: Any
self, db_field: ManyToManyField, request: Optional[HttpRequest], **kwargs: Any
) -> ModelMultipleChoiceField: ...
def get_autocomplete_fields(self, request: WSGIRequest) -> Tuple: ...
def get_autocomplete_fields(self, request: HttpRequest) -> Tuple: ...
def get_view_on_site_url(self, obj: Optional[Model] = ...) -> Optional[str]: ...
def get_empty_value_display(self) -> SafeText: ...
def get_exclude(self, request: WSGIRequest, obj: Optional[Model] = ...) -> Any: ...
def get_fields(self, request: WSGIRequest, obj: Optional[Model] = ...) -> Sequence[Union[Callable, str]]: ...
def get_exclude(self, request: HttpRequest, obj: Optional[Model] = ...) -> Any: ...
def get_fields(self, request: HttpRequest, obj: Optional[Model] = ...) -> Sequence[Union[Callable, str]]: ...
def get_fieldsets(
self, request: WSGIRequest, obj: Optional[Model] = ...
self, request: HttpRequest, obj: Optional[Model] = ...
) -> List[Tuple[Optional[str], Dict[str, Any]]]: ...
def get_ordering(self, request: WSGIRequest) -> Union[List[str], Tuple]: ...
def get_readonly_fields(self, request: WSGIRequest, obj: Optional[Model] = ...) -> Union[List[str], Tuple]: ...
def get_prepopulated_fields(self, request: WSGIRequest, obj: Optional[Model] = ...) -> Dict[str, Tuple[str]]: ...
def get_queryset(self, request: WSGIRequest) -> QuerySet: ...
def get_sortable_by(self, request: WSGIRequest) -> Union[List[Callable], List[str], Tuple]: ...
def get_ordering(self, request: HttpRequest) -> Union[List[str], Tuple]: ...
def get_readonly_fields(self, request: HttpRequest, obj: Optional[Model] = ...) -> Union[List[str], Tuple]: ...
def get_prepopulated_fields(self, request: HttpRequest, obj: Optional[Model] = ...) -> Dict[str, Tuple[str]]: ...
def get_queryset(self, request: HttpRequest) -> QuerySet: ...
def get_sortable_by(self, request: HttpRequest) -> Union[List[Callable], List[str], Tuple]: ...
def lookup_allowed(self, lookup: str, value: str) -> bool: ...
def to_field_allowed(self, request: WSGIRequest, to_field: str) -> bool: ...
def has_add_permission(self, request: WSGIRequest, obj: Optional[Model] = ...) -> bool: ...
def has_change_permission(self, request: WSGIRequest, obj: Optional[Model] = ...) -> bool: ...
def has_delete_permission(self, request: WSGIRequest, obj: Optional[Model] = ...) -> bool: ...
def has_view_permission(self, request: WSGIRequest, obj: Optional[Model] = ...) -> bool: ...
def has_module_permission(self, request: WSGIRequest) -> bool: ...
def to_field_allowed(self, request: HttpRequest, to_field: str) -> bool: ...
def has_add_permission(self, request: HttpRequest, obj: Optional[Model] = ...) -> bool: ...
def has_change_permission(self, request: HttpRequest, obj: Optional[Model] = ...) -> bool: ...
def has_delete_permission(self, request: HttpRequest, obj: Optional[Model] = ...) -> bool: ...
def has_view_permission(self, request: HttpRequest, obj: Optional[Model] = ...) -> bool: ...
def has_module_permission(self, request: HttpRequest) -> bool: ...
class ModelAdmin(BaseModelAdmin):
formfield_overrides: Any
@@ -127,54 +127,54 @@ class ModelAdmin(BaseModelAdmin):
opts: Options = ...
admin_site: AdminSite = ...
def __init__(self, model: Type[Model], admin_site: Optional[AdminSite]) -> None: ...
def get_inline_instances(self, request: WSGIRequest, obj: Optional[Model] = ...) -> List[InlineModelAdmin]: ...
def get_inline_instances(self, request: HttpRequest, obj: Optional[Model] = ...) -> List[InlineModelAdmin]: ...
def get_urls(self) -> List[URLPattern]: ...
@property
def urls(self) -> List[URLPattern]: ...
@property
def media(self) -> Media: ...
def get_model_perms(self, request: WSGIRequest) -> Dict[str, bool]: ...
def get_model_perms(self, request: HttpRequest) -> Dict[str, bool]: ...
def get_form(self, request: Any, obj: Optional[Any] = ..., change: bool = ..., **kwargs: Any): ...
def get_changelist(self, request: WSGIRequest, **kwargs: Any) -> Type[ChangeList]: ...
def get_changelist_instance(self, request: WSGIRequest) -> ChangeList: ...
def get_object(self, request: WSGIRequest, object_id: str, from_field: None = ...) -> Optional[Model]: ...
def get_changelist(self, request: HttpRequest, **kwargs: Any) -> Type[ChangeList]: ...
def get_changelist_instance(self, request: HttpRequest) -> ChangeList: ...
def get_object(self, request: HttpRequest, object_id: str, from_field: None = ...) -> Optional[Model]: ...
def get_changelist_form(self, request: Any, **kwargs: Any): ...
def get_changelist_formset(self, request: Any, **kwargs: Any): ...
def get_formsets_with_inlines(self, request: WSGIRequest, obj: Optional[Model] = ...) -> Iterator[Any]: ...
def get_formsets_with_inlines(self, request: HttpRequest, obj: Optional[Model] = ...) -> Iterator[Any]: ...
def get_paginator(
self,
request: WSGIRequest,
request: HttpRequest,
queryset: QuerySet,
per_page: int,
orphans: int = ...,
allow_empty_first_page: bool = ...,
) -> Paginator: ...
def log_addition(self, request: WSGIRequest, object: Model, message: Any) -> LogEntry: ...
def log_change(self, request: WSGIRequest, object: Model, message: Any) -> LogEntry: ...
def log_deletion(self, request: WSGIRequest, object: Model, object_repr: str) -> LogEntry: ...
def log_addition(self, request: HttpRequest, object: Model, message: Any) -> LogEntry: ...
def log_change(self, request: HttpRequest, object: Model, message: Any) -> LogEntry: ...
def log_deletion(self, request: HttpRequest, object: Model, object_repr: str) -> LogEntry: ...
def action_checkbox(self, obj: Model) -> SafeText: ...
def get_actions(self, request: WSGIRequest) -> OrderedDict: ...
def get_actions(self, request: HttpRequest) -> OrderedDict: ...
def get_action_choices(
self, request: WSGIRequest, default_choices: List[Tuple[str, str]] = ...
self, request: HttpRequest, default_choices: List[Tuple[str, str]] = ...
) -> List[Tuple[str, str]]: ...
def get_action(self, action: Union[Callable, str]) -> Tuple[Callable, str, str]: ...
def get_list_display(self, request: WSGIRequest) -> Sequence[str]: ...
def get_list_display_links(self, request: WSGIRequest, list_display: Sequence[str]) -> Optional[Sequence[str]]: ...
def get_list_filter(self, request: WSGIRequest) -> Sequence[str]: ...
def get_list_select_related(self, request: WSGIRequest) -> Sequence[str]: ...
def get_search_fields(self, request: WSGIRequest) -> List[str]: ...
def get_list_display(self, request: HttpRequest) -> Sequence[str]: ...
def get_list_display_links(self, request: HttpRequest, list_display: Sequence[str]) -> Optional[Sequence[str]]: ...
def get_list_filter(self, request: HttpRequest) -> Sequence[str]: ...
def get_list_select_related(self, request: HttpRequest) -> Sequence[str]: ...
def get_search_fields(self, request: HttpRequest) -> List[str]: ...
def get_search_results(
self, request: WSGIRequest, queryset: QuerySet, search_term: str
self, request: HttpRequest, queryset: QuerySet, search_term: str
) -> Tuple[QuerySet, bool]: ...
def get_preserved_filters(self, request: WSGIRequest) -> str: ...
def _get_edited_object_pks(self, request: WSGIRequest, prefix: str) -> List[str]: ...
def _get_list_editable_queryset(self, request: WSGIRequest, prefix: str) -> QuerySet: ...
def get_preserved_filters(self, request: HttpRequest) -> str: ...
def _get_edited_object_pks(self, request: HttpRequest, prefix: str) -> List[str]: ...
def _get_list_editable_queryset(self, request: HttpRequest, prefix: str) -> QuerySet: ...
def construct_change_message(
self, request: WSGIRequest, form: AdminPasswordChangeForm, formsets: None, add: bool = ...
self, request: HttpRequest, form: AdminPasswordChangeForm, formsets: None, add: bool = ...
) -> List[Dict[str, Dict[str, List[str]]]]: ...
def message_user(
self,
request: WSGIRequest,
request: HttpRequest,
message: str,
level: Union[int, str] = ...,
extra_tags: str = ...,
@@ -182,8 +182,8 @@ class ModelAdmin(BaseModelAdmin):
) -> None: ...
def save_form(self, request: Any, form: Any, change: Any): ...
def save_model(self, request: Any, obj: Any, form: Any, change: Any) -> None: ...
def delete_model(self, request: WSGIRequest, obj: Model) -> None: ...
def delete_queryset(self, request: WSGIRequest, queryset: QuerySet) -> None: ...
def delete_model(self, request: HttpRequest, obj: Model) -> None: ...
def delete_queryset(self, request: HttpRequest, queryset: QuerySet) -> None: ...
def save_formset(self, request: Any, form: Any, formset: Any, change: Any) -> None: ...
def save_related(self, request: Any, form: Any, formsets: Any, change: Any) -> None: ...
def render_change_form(
@@ -196,52 +196,51 @@ class ModelAdmin(BaseModelAdmin):
obj: Optional[Any] = ...,
): ...
def response_add(
self, request: WSGIRequest, obj: Model, post_url_continue: Optional[str] = ...
self, request: HttpRequest, obj: Model, post_url_continue: Optional[str] = ...
) -> HttpResponse: ...
def response_change(self, request: WSGIRequest, obj: Model) -> HttpResponse: ...
def response_post_save_add(self, request: WSGIRequest, obj: Model) -> HttpResponseRedirect: ...
def response_post_save_change(self, request: WSGIRequest, obj: Model) -> HttpResponseRedirect: ...
def response_action(self, request: WSGIRequest, queryset: QuerySet) -> Optional[HttpResponseBase]: ...
def response_delete(self, request: WSGIRequest, obj_display: str, obj_id: int) -> HttpResponse: ...
def response_change(self, request: HttpRequest, obj: Model) -> HttpResponse: ...
def response_post_save_add(self, request: HttpRequest, obj: Model) -> HttpResponseRedirect: ...
def response_post_save_change(self, request: HttpRequest, obj: Model) -> HttpResponseRedirect: ...
def response_action(self, request: HttpRequest, queryset: QuerySet) -> Optional[HttpResponseBase]: ...
def response_delete(self, request: HttpRequest, obj_display: str, obj_id: int) -> HttpResponse: ...
def render_delete_form(self, request: Any, context: Any): ...
def get_inline_formsets(
self, request: WSGIRequest, formsets: List[Any], inline_instances: List[Any], obj: Optional[Model] = ...
self, request: HttpRequest, formsets: List[Any], inline_instances: List[Any], obj: Optional[Model] = ...
) -> List[Any]: ...
def get_changeform_initial_data(self, request: WSGIRequest) -> Dict[str, str]: ...
def get_changeform_initial_data(self, request: HttpRequest) -> Dict[str, str]: ...
def changeform_view(
self,
request: WSGIRequest,
request: HttpRequest,
object_id: Optional[str] = ...,
form_url: str = ...,
extra_context: Optional[Dict[str, bool]] = ...,
) -> Any: ...
def autocomplete_view(self, request: WSGIRequest) -> JsonResponse: ...
def add_view(self, request: WSGIRequest, form_url: str = ..., extra_context: None = ...) -> HttpResponse: ...
def autocomplete_view(self, request: HttpRequest) -> JsonResponse: ...
def add_view(self, request: HttpRequest, form_url: str = ..., extra_context: None = ...) -> HttpResponse: ...
def change_view(
self, request: WSGIRequest, object_id: str, form_url: str = ..., extra_context: Optional[Dict[str, bool]] = ...
self, request: HttpRequest, object_id: str, form_url: str = ..., extra_context: Optional[Dict[str, bool]] = ...
) -> HttpResponse: ...
def changelist_view(
self, request: WSGIRequest, extra_context: Optional[Dict[str, str]] = ...
self, request: HttpRequest, extra_context: Optional[Dict[str, str]] = ...
) -> TemplateResponse: ...
def get_deleted_objects(
self, objs: QuerySet, request: WSGIRequest
self, objs: QuerySet, request: HttpRequest
) -> Tuple[List[Any], Dict[Any, Any], Set[Any], List[Any]]: ...
def delete_view(self, request: WSGIRequest, object_id: str, extra_context: None = ...) -> Any: ...
def history_view(self, request: WSGIRequest, object_id: str, extra_context: None = ...) -> HttpResponse: ...
def delete_view(self, request: HttpRequest, object_id: str, extra_context: None = ...) -> Any: ...
def history_view(self, request: HttpRequest, object_id: str, extra_context: None = ...) -> HttpResponse: ...
class InlineModelAdmin(BaseModelAdmin):
model: Any = ...
fk_name: Any = ...
formset: Any = ...
extra: int = ...
min_num: Any = ...
max_num: Any = ...
template: Any = ...
verbose_name: Any = ...
verbose_name_plural: Any = ...
min_num: Optional[int] = ...
max_num: Optional[int] = ...
template: str = ...
verbose_name: Optional[str] = ...
verbose_name_plural: Optional[str] = ...
can_delete: bool = ...
show_change_link: bool = ...
checks_class: Any = ...
classes: Any = ...
admin_site: Any = ...
parent_model: Any = ...
@@ -250,18 +249,10 @@ class InlineModelAdmin(BaseModelAdmin):
def __init__(self, parent_model: Union[Type[Model], Model], admin_site: AdminSite) -> None: ...
@property
def media(self) -> Media: ...
def get_extra(self, request: WSGIRequest, obj: Optional[Model] = ..., **kwargs: Any) -> int: ...
def get_min_num(self, request: WSGIRequest, obj: Optional[Model] = ..., **kwargs: Any) -> None: ...
def get_max_num(self, request: WSGIRequest, obj: Optional[Model] = ..., **kwargs: Any) -> Optional[int]: ...
fields: Any = ...
def get_extra(self, request: HttpRequest, obj: Optional[Model] = ..., **kwargs: Any) -> int: ...
def get_min_num(self, request: HttpRequest, obj: Optional[Model] = ..., **kwargs: Any) -> Optional[int]: ...
def get_max_num(self, request: HttpRequest, obj: Optional[Model] = ..., **kwargs: Any) -> Optional[int]: ...
def get_formset(self, request: Any, obj: Optional[Any] = ..., **kwargs: Any): ...
def get_queryset(self, request: WSGIRequest) -> QuerySet: ...
def has_change_permission(self, request: WSGIRequest, obj: Optional[Model] = ...) -> bool: ...
def has_delete_permission(self, request: WSGIRequest, obj: Optional[Model] = ...) -> bool: ...
def has_view_permission(self, request: WSGIRequest, obj: Optional[Model] = ...) -> bool: ...
class StackedInline(InlineModelAdmin):
template: str = ...
class TabularInline(InlineModelAdmin):
template: str = ...
class StackedInline(InlineModelAdmin): ...
class TabularInline(InlineModelAdmin): ...

View File

@@ -44,7 +44,6 @@ class UserCreationForm(forms.ModelForm):
password2: Any = ...
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
def clean_password2(self) -> str: ...
def save(self, commit: bool = ...) -> User: ...
class UserChangeForm(forms.ModelForm):
auto_id: str

View File

@@ -1,6 +1,6 @@
from typing import Any, Callable, List, Optional
from django.core.handlers.wsgi import WSGIRequest
from django import http
from django.http.response import HttpResponse, HttpResponseRedirect
class AccessMixin:
@@ -14,15 +14,15 @@ class AccessMixin:
def handle_no_permission(self) -> HttpResponseRedirect: ...
class LoginRequiredMixin(AccessMixin):
def dispatch(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
class PermissionRequiredMixin(AccessMixin):
permission_required: Any = ...
def get_permission_required(self) -> List[str]: ...
def has_permission(self) -> bool: ...
def dispatch(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
class UserPassesTestMixin(AccessMixin):
def test_func(self) -> None: ...
def get_test_func(self) -> Callable: ...
def dispatch(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...

View File

@@ -1,10 +1,10 @@
from typing import Any
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class RedirectFallbackMiddleware(MiddlewareMixin):
response_gone_class: Any = ...
response_redirect_class: Any = ...
def process_response(self, request: WSGIRequest, response: HttpResponse) -> HttpResponse: ...
def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse: ...

View File

@@ -1,20 +1,19 @@
from datetime import datetime
from typing import Any, Dict, Optional
from typing import Any, Dict, Optional, Type
from django.contrib.sessions.backends.base import SessionBase
from django.db import models
class BaseSessionManager(models.Manager):
creation_counter: int
model: None
name: None
def encode(self, session_dict: Dict[str, int]) -> str: ...
def save(self, session_key: str, session_dict: Dict[str, int], expire_date: datetime) -> AbstractBaseSession: ...
class AbstractBaseSession(models.Model):
session_key: Any = ...
session_data: Any = ...
expire_date: Any = ...
expire_date: datetime
session_data: str
session_key: str
objects: Any = ...
@classmethod
def get_session_store_class(cls) -> None: ...
def get_session_store_class(cls) -> Optional[Type[SessionBase]]: ...
def get_decoded(self) -> Dict[str, int]: ...

View File

@@ -1,18 +1,4 @@
from typing import Any, Optional, Type
from django.contrib.sessions.backends.db import SessionStore
from django.contrib.sessions.base_session import AbstractBaseSession, BaseSessionManager
class SessionManager(BaseSessionManager):
creation_counter: int
model: None
name: None
use_in_migrations: bool = ...
class Session(AbstractBaseSession):
expire_date: datetime.datetime
session_data: str
session_key: str
objects: Any = ...
@classmethod
def get_session_store_class(cls) -> Type[SessionStore]: ...
class SessionManager(BaseSessionManager): ...
class Session(AbstractBaseSession): ...

View File

@@ -1,4 +1,4 @@
from typing import Any, Dict, Optional
from typing import Dict
from django.core.signing import JSONSerializer as BaseJSONSerializer
from django.db.models.base import Model

View File

@@ -11,7 +11,7 @@ PING_URL: str
class SitemapNotFound(Exception): ...
def ping_google(sitemap_url: None = ..., ping_url: str = ...) -> None: ...
def ping_google(sitemap_url: Optional[str] = ..., ping_url: str = ...) -> None: ...
class Sitemap:
limit: int = ...
@@ -22,14 +22,14 @@ class Sitemap:
def paginator(self) -> Paginator: ...
def get_urls(
self, page: Union[int, str] = ..., site: Optional[Union[Site, RequestSite]] = ..., protocol: Optional[str] = ...
) -> List[Dict[str, Optional[Union[datetime, Model, str]]]]: ...
) -> List[Dict[str, Any]]: ...
class GenericSitemap(Sitemap):
priority: None = ...
changefreq: None = ...
priority: Optional[float] = ...
changefreq: Optional[str] = ...
queryset: QuerySet = ...
date_field: None = ...
protocol: None = ...
protocol: Optional[str] = ...
def __init__(
self,
info_dict: Dict[str, Union[datetime, QuerySet, str]],

View File

@@ -1,20 +1,21 @@
from collections import OrderedDict
from typing import Any, Callable, Dict, Optional, Type, Union
from typing import Callable, Dict, Optional, Type, Union
from django.http.request import HttpRequest
from django.template.response import TemplateResponse
from django.contrib.sitemaps import GenericSitemap, Sitemap
from django.core.handlers.wsgi import WSGIRequest
from django.template.response import TemplateResponse
def x_robots_tag(func: Callable) -> Callable: ...
def index(
request: WSGIRequest,
request: HttpRequest,
sitemaps: Dict[str, Union[Type[Sitemap], Sitemap]],
template_name: str = ...,
content_type: str = ...,
sitemap_url_name: str = ...,
) -> TemplateResponse: ...
def sitemap(
request: WSGIRequest,
request: HttpRequest,
sitemaps: Union[Dict[str, Type[Sitemap]], Dict[str, GenericSitemap], OrderedDict],
section: Optional[str] = ...,
template_name: str = ...,

View File

@@ -1,7 +1,7 @@
from collections import OrderedDict
from typing import Any, Callable, Dict, Union
from django.core.cache.backends.base import BaseCache as BaseCache
from .backends.base import BaseCache as BaseCache
DEFAULT_CACHE_ALIAS: str

View File

@@ -1,5 +1,5 @@
from typing import Any, List, Optional, Union
from typing import Any, Iterable, Optional
TEMPLATE_FRAGMENT_KEY_TEMPLATE: str
def make_template_fragment_key(fragment_name: str, vary_on: Optional[Union[List[int], List[str]]] = ...) -> str: ...
def make_template_fragment_key(fragment_name: str, vary_on: Optional[Iterable[Any]] = ...) -> str: ...

View File

@@ -1,6 +1,5 @@
from typing import Any, Dict, Iterator, List, Optional, Tuple, Type, Union
from typing import Any, Dict, Iterator, List, Mapping, Optional, Tuple, Union
from django.db.models.base import Model
from django.forms.utils import ErrorDict
class FieldDoesNotExist(Exception): ...
@@ -31,20 +30,13 @@ class ValidationError(Exception):
message: Any = ...
code: Any = ...
params: Any = ...
def __init__(
self,
message: Any,
code: Optional[str] = ...,
params: Optional[
Union[Dict[str, Union[Tuple[str], Type[Model], Model, str]], Dict[str, Union[int, str]]]
] = ...,
) -> None: ...
def __init__(self, message: Any, code: Optional[str] = ..., params: Optional[Mapping[str, Any]] = ...) -> None: ...
@property
def message_dict(self) -> Dict[str, List[str]]: ...
@property
def messages(self) -> List[str]: ...
def update_error_dict(
self, error_dict: Union[Dict[str, List[ValidationError]], ErrorDict]
self, error_dict: Mapping[str, Any]
) -> Union[Dict[str, List[ValidationError]], ErrorDict]: ...
def __iter__(self) -> Iterator[Union[Tuple[str, List[str]], str]]: ...

View File

@@ -1,15 +1,12 @@
from datetime import datetime
from io import StringIO, TextIOWrapper
from typing import Any, List, Optional, Tuple, Union
from typing import Any, IO, List, Optional, Tuple
from django.core.files.base import File
from django.utils.functional import LazyObject
class Storage:
def open(self, name: str, mode: str = ...) -> File: ...
def save(
self, name: Optional[str], content: Union[StringIO, TextIOWrapper, File], max_length: Optional[int] = ...
) -> str: ...
def save(self, name: Optional[str], content: IO[Any], max_length: Optional[int] = ...) -> str: ...
def get_valid_name(self, name: str) -> str: ...
def get_available_name(self, name: str, max_length: Optional[int] = ...) -> str: ...
def generate_filename(self, filename: str) -> str: ...

View File

@@ -39,10 +39,10 @@ class InMemoryUploadedFile(UploadedFile):
charset: Optional[str],
content_type_extra: Dict[str, str] = ...,
) -> None: ...
def chunks(self, chunk_size: int = None) -> Iterator[bytes]: ...
def multiple_chunks(self, chunk_size: int = None) -> bool: ...
def chunks(self, chunk_size: Optional[int] = ...) -> Iterator[bytes]: ...
def multiple_chunks(self, chunk_size: Optional[int] = ...) -> bool: ...
class SimpleUploadedFile(InMemoryUploadedFile):
def __init__(self, name: str, content: bytes, content_type: str = "") -> None: ...
def __init__(self, name: str, content: Optional[Union[bytes, str]], content_type: str = ...) -> None: ...
@classmethod
def from_dict(cls: Any, file_dict: Dict[str, Union[str, bytes]]) -> None: ...

View File

@@ -1,6 +1,6 @@
from typing import Any, Callable
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import HttpResponse, HttpResponseBase
logger: Any
@@ -13,5 +13,5 @@ class BaseHandler:
def load_middleware(self) -> None: ...
def make_view_atomic(self, view: Callable) -> Callable: ...
def get_exception_response(self, request: Any, resolver: Any, status_code: Any, exception: Any): ...
def get_response(self, request: WSGIRequest) -> HttpResponseBase: ...
def process_exception_by_middleware(self, exception: Exception, request: WSGIRequest) -> HttpResponse: ...
def get_response(self, request: HttpRequest) -> HttpResponseBase: ...
def process_exception_by_middleware(self, exception: Exception, request: HttpRequest) -> HttpResponse: ...

View File

@@ -1,12 +1,12 @@
from typing import Any, Callable
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.urls.resolvers import URLResolver
def convert_exception_to_response(get_response: Callable) -> Callable: ...
def response_for_exception(request: WSGIRequest, exc: Exception) -> HttpResponse: ...
def response_for_exception(request: HttpRequest, exc: Exception) -> HttpResponse: ...
def get_exception_response(
request: WSGIRequest, resolver: URLResolver, status_code: int, exception: Exception, sender: None = ...
request: HttpRequest, resolver: URLResolver, status_code: int, exception: Exception, sender: None = ...
) -> HttpResponse: ...
def handle_uncaught_exception(request: Any, resolver: Any, exc_info: Any): ...

View File

@@ -1,15 +1,16 @@
from typing import Any, List, Optional, Tuple
from django.core.mail.backends.base import BaseEmailBackend
from django.core.mail.message import DEFAULT_ATTACHMENT_MIME_TYPE as DEFAULT_ATTACHMENT_MIME_TYPE
from django.core.mail.message import BadHeaderError as BadHeaderError
from django.core.mail.message import EmailMessage as EmailMessage
from django.core.mail.message import EmailMultiAlternatives as EmailMultiAlternatives
from django.core.mail.message import SafeMIMEMultipart as SafeMIMEMultipart
from django.core.mail.message import SafeMIMEText as SafeMIMEText
from django.core.mail.message import forbid_multi_line_headers as forbid_multi_line_headers
from django.core.mail.utils import DNS_NAME as DNS_NAME
from django.core.mail.utils import CachedDnsName as CachedDnsName
from .backends.base import BaseEmailBackend
from .message import (
BadHeaderError as BadHeaderError,
DEFAULT_ATTACHMENT_MIME_TYPE as DEFAULT_ATTACHMENT_MIME_TYPE,
EmailMessage as EmailMessage,
EmailMultiAlternatives as EmailMultiAlternatives,
SafeMIMEMultipart as SafeMIMEMultipart,
SafeMIMEText as SafeMIMEText,
forbid_multi_line_headers as forbid_multi_line_headers,
)
from .utils import CachedDnsName as CachedDnsName, DNS_NAME as DNS_NAME
def get_connection(backend: Optional[str] = ..., fail_silently: bool = ..., **kwds: Any) -> BaseEmailBackend: ...
def send_mail(
@@ -18,17 +19,17 @@ def send_mail(
from_email: Optional[str],
recipient_list: List[str],
fail_silently: bool = ...,
auth_user: None = ...,
auth_password: None = ...,
auth_user: Optional[str] = ...,
auth_password: Optional[str] = ...,
connection: Optional[BaseEmailBackend] = ...,
html_message: Optional[str] = ...,
) -> int: ...
def send_mass_mail(
datatuple: List[Tuple[str, str, str, List[str]]],
fail_silently: bool = ...,
auth_user: None = ...,
auth_password: None = ...,
connection: BaseEmailBackend = ...,
auth_user: Optional[str] = ...,
auth_password: Optional[str] = ...,
connection: Optional[BaseEmailBackend] = ...,
) -> int: ...
def mail_admins(
subject: str,
@@ -45,4 +46,4 @@ def mail_managers(
html_message: Optional[str] = ...,
) -> None: ...
outbox = [EmailMessage()]
outbox: List[EmailMessage] = ...

View File

@@ -1,8 +1,8 @@
import email
from email._policybase import Policy
from email.mime.message import MIMEMessage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from typing import Any, Dict, List, Optional, Tuple, Union
from typing import Any, Dict, List, Optional, Tuple, Union, Sequence
from django.core.mail.backends.base import BaseEmailBackend
from django.utils.safestring import SafeText
@@ -27,14 +27,14 @@ class MIMEMixin:
class SafeMIMEMessage(MIMEMixin, MIMEMessage):
defects: List[Any]
epilogue: None
policy: email._policybase.Compat32
policy: Policy
preamble: None
def __setitem__(self, name: str, val: str) -> None: ...
class SafeMIMEText(MIMEMixin, MIMEText):
defects: List[Any]
epilogue: None
policy: email._policybase.Compat32
policy: Policy
preamble: None
encoding: str = ...
def __init__(self, _text: str, _subtype: str = ..., _charset: str = ...) -> None: ...
@@ -44,7 +44,7 @@ class SafeMIMEText(MIMEMixin, MIMEText):
class SafeMIMEMultipart(MIMEMixin, MIMEMultipart):
defects: List[Any]
epilogue: None
policy: email._policybase.Compat32
policy: Policy
preamble: None
encoding: str = ...
def __init__(
@@ -71,12 +71,12 @@ class EmailMessage:
subject: str = ...,
body: Optional[str] = ...,
from_email: Optional[str] = ...,
to: Optional[Union[List[str], Tuple[str, str], str]] = ...,
bcc: Optional[Union[List[str], Tuple[str], str]] = ...,
to: Optional[Union[Sequence[str], str]] = ...,
bcc: Optional[Union[Sequence[str], str]] = ...,
connection: Optional[BaseEmailBackend] = ...,
attachments: Optional[Union[List[Tuple[str, str]], List[MIMEText]]] = ...,
headers: Optional[Dict[str, str]] = ...,
cc: Optional[Union[List[str], Tuple[str, str], str]] = ...,
cc: Optional[Union[Sequence[str], str]] = ...,
reply_to: Optional[Union[List[Optional[str]], str]] = ...,
) -> None: ...
def get_connection(self, fail_silently: bool = ...) -> BaseEmailBackend: ...

View File

@@ -11,7 +11,6 @@ class Node:
parents: Set[Any] = ...
def __init__(self, key: Tuple[str, str]) -> None: ...
def __lt__(self, other: Union[Tuple[str, str], Node]) -> bool: ...
def __hash__(self) -> int: ...
def __getitem__(self, item: int) -> str: ...
def add_child(self, child: Node) -> None: ...
def add_parent(self, parent: Node) -> None: ...
@@ -19,13 +18,9 @@ class Node:
def descendants(self) -> List[Tuple[str, str]]: ...
class DummyNode(Node):
children: Set[Any]
key: Tuple[str, str]
parents: Set[Any]
origin: Any = ...
error_message: Any = ...
def __init__(self, key: Tuple[str, str], origin: Union[Migration, str], error_message: str) -> None: ...
__class__: Any = ...
def promote(self) -> None: ...
def raise_error(self) -> None: ...

View File

@@ -1,11 +1,11 @@
from typing import Any, Dict, Optional, Set, Tuple, Union, Sequence
from typing import Any, Dict, Optional, Sequence, Set, Tuple, Union
from django.db import DefaultConnectionProxy
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.backends.sqlite3.base import DatabaseWrapper
from django.db.migrations.migration import Migration, SwappableTuple
from django.db.migrations.state import ProjectState
from django.db import DefaultConnectionProxy
MIGRATIONS_MODULE_NAME: str
class MigrationLoader:

View File

@@ -13,7 +13,6 @@ class Migration:
name: str = ...
app_label: str = ...
def __init__(self, name: str, app_label: str) -> None: ...
def __hash__(self) -> int: ...
def mutate_state(self, project_state: ProjectState, preserve: bool = ...) -> ProjectState: ...
def apply(
self, project_state: ProjectState, schema_editor: BaseDatabaseSchemaEditor, collect_sql: bool = ...
@@ -24,6 +23,6 @@ class Migration:
class SwappableTuple(tuple):
setting: str = ...
def __new__(cls: Type[SwappableTuple], value: Tuple[str, str], setting: str) -> SwappableTuple: ...
def __new__(cls, value: Tuple[str, str], setting: str) -> SwappableTuple: ...
def swappable_dependency(value: str) -> SwappableTuple: ...

View File

@@ -1,7 +1,3 @@
# Stubs for django.db.migrations.operations (Python 3.6)
#
# NOTE: This dynamically typed stub was automatically generated by stubgen.
from .fields import (
AddField as AddField,
AlterField as AlterField,

View File

@@ -1,4 +1,4 @@
from typing import Any, List, Optional, Type
from typing import Any, List
class Operation:
reversible: bool = ...
@@ -6,7 +6,6 @@ class Operation:
atomic: bool = ...
elidable: bool = ...
serialization_expand_args: Any = ...
def __new__(cls: Type[Operation], *args: Any, **kwargs: Any) -> Operation: ...
def deconstruct(self): ...
def state_forwards(self, app_label: Any, state: Any) -> None: ...
def database_forwards(self, app_label: Any, schema_editor: Any, from_state: Any, to_state: Any) -> None: ...

View File

@@ -12,7 +12,6 @@ class ModelOperation(Operation):
def name_lower(self) -> str: ...
class CreateModel(ModelOperation):
serialization_expand_args: Any = ...
fields: Sequence[Tuple[str, Field]] = ...
options: Any = ...
bases: Optional[Sequence[Union[type, str]]] = ...
@@ -63,7 +62,6 @@ class AlterModelOptions(ModelOptionOperation):
def __init__(self, name: str, options: Dict[str, Any]) -> None: ...
class AlterModelManagers(ModelOptionOperation):
serialization_expand_args: Any = ...
managers: Any = ...
def __init__(self, name: Any, managers: Any) -> None: ...

View File

@@ -1,4 +1,4 @@
from typing import Any, Callable, Optional, Sequence, Dict
from typing import Any, Callable, Dict, Optional, Sequence
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.migrations.state import StateApps
@@ -6,7 +6,6 @@ from django.db.migrations.state import StateApps
from .base import Operation
class SeparateDatabaseAndState(Operation):
serialization_expand_args: Any = ...
database_operations: Sequence[Operation] = ...
state_operations: Sequence[Operation] = ...
def __init__(
@@ -19,7 +18,6 @@ class RunSQL(Operation):
reverse_sql: Any = ...
state_operations: Any = ...
hints: Any = ...
elidable: Any = ...
def __init__(
self,
sql: Any,
@@ -30,12 +28,9 @@ class RunSQL(Operation):
) -> None: ...
class RunPython(Operation):
reduces_to_sql: bool = ...
atomic: bool = ...
code: Callable = ...
reverse_code: Optional[Callable] = ...
hints: Optional[Dict[str, Any]] = ...
elidable: bool = ...
def __init__(
self,
code: Callable,

View File

@@ -1,6 +1,5 @@
from typing import Any, Optional
from django.db.migrations.state import ProjectState
from django.db.models.fields import Field
def is_referenced_by_foreign_key(state: ProjectState, model_name_lower: str, field: Field, field_name: str) -> bool: ...

View File

@@ -1,7 +1,7 @@
from typing import Any, List, Optional
from typing import List, Optional
from django.db.migrations.operations.base import Operation
class MigrationOptimizer:
def optimize(self, operations: List[Operation], app_label: str = ...) -> List[Operation]: ...
def optimize_inner(self, operations: List[Operation], app_label: str = ...) -> List[Operation]: ...
def optimize(self, operations: List[Operation], app_label: Optional[str] = ...) -> List[Operation]: ...
def optimize_inner(self, operations: List[Operation], app_label: Optional[str] = ...) -> List[Operation]: ...

View File

@@ -1,14 +1,13 @@
from typing import Any, Dict, Optional, Set
from django.db.migrations.state import ModelState
from django.db.models.fields import Field
from .loader import MigrationLoader
class MigrationQuestioner:
defaults: Dict[Any, Any] = ...
specified_apps: Set[Any] = ...
dry_run: None = ...
defaults: Dict[str, Any] = ...
specified_apps: Set[str] = ...
dry_run: Optional[bool] = ...
def __init__(
self,
defaults: Optional[Dict[str, bool]] = ...,
@@ -23,21 +22,5 @@ class MigrationQuestioner:
def ask_merge(self, app_label: str) -> bool: ...
def ask_auto_now_add_addition(self, field_name: str, model_name: str) -> None: ...
class InteractiveMigrationQuestioner(MigrationQuestioner):
defaults: Dict[Any, Any]
dry_run: bool
specified_apps: Set[str]
def ask_not_null_addition(self, field_name: str, model_name: str) -> None: ...
def ask_not_null_alteration(self, field_name: Any, model_name: Any): ...
def ask_rename(self, model_name: Any, old_name: Any, new_name: Any, field_instance: Any): ...
def ask_rename_model(self, old_model_state: Any, new_model_state: Any): ...
def ask_merge(self, app_label: str) -> bool: ...
def ask_auto_now_add_addition(self, field_name: str, model_name: str) -> int: ...
class NonInteractiveMigrationQuestioner(MigrationQuestioner):
defaults: Dict[Any, Any]
dry_run: bool
specified_apps: Set[str]
def ask_not_null_addition(self, field_name: Any, model_name: Any) -> None: ...
def ask_not_null_alteration(self, field_name: Any, model_name: Any): ...
def ask_auto_now_add_addition(self, field_name: Any, model_name: Any) -> None: ...
class InteractiveMigrationQuestioner(MigrationQuestioner): ...
class NonInteractiveMigrationQuestioner(MigrationQuestioner): ...

View File

@@ -1,9 +1,10 @@
from typing import Any, Optional, Set, Tuple, Union
from typing import Any, Optional, Set, Tuple
from django.db import models
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.models.query import QuerySet
from django.db import models
class MigrationRecorder:
class Migration(models.Model):
app: Any = ...

View File

@@ -1,88 +1,40 @@
from typing import Any, Callable, Dict, List, Set, Tuple, Union
from django.db.models.fields import Field
class BaseSerializer:
value: Any = ...
def __init__(self, value: Any) -> None: ...
def serialize(self) -> None: ...
def serialize(self) -> Any: ...
class BaseSequenceSerializer(BaseSerializer):
def serialize(self) -> Tuple[str, Set[str]]: ...
class BaseSimpleSerializer(BaseSerializer):
value: str
def serialize(self) -> Tuple[str, Set[Any]]: ...
class DatetimeSerializer(BaseSerializer):
value: Any = ...
def serialize(self): ...
class DateSerializer(BaseSerializer):
def serialize(self): ...
class DecimalSerializer(BaseSerializer):
def serialize(self): ...
class BaseSequenceSerializer(BaseSerializer): ...
class BaseSimpleSerializer(BaseSerializer): ...
class DatetimeSerializer(BaseSerializer): ...
class DateSerializer(BaseSerializer): ...
class DecimalSerializer(BaseSerializer): ...
class DeconstructableSerializer(BaseSerializer):
@staticmethod
def serialize_deconstructed(
path: str, args: List[Any], kwargs: Dict[str, Union[Callable, int, str]]
) -> Tuple[str, Set[str]]: ...
def serialize(self): ...
class DictionarySerializer(BaseSerializer):
def serialize(self): ...
class EnumSerializer(BaseSerializer):
def serialize(self): ...
class FloatSerializer(BaseSimpleSerializer):
def serialize(self): ...
class DictionarySerializer(BaseSerializer): ...
class EnumSerializer(BaseSerializer): ...
class FloatSerializer(BaseSimpleSerializer): ...
class FrozensetSerializer(BaseSequenceSerializer): ...
class FunctionTypeSerializer(BaseSerializer):
value: Callable
def serialize(self) -> Tuple[str, Set[str]]: ...
class FunctoolsPartialSerializer(BaseSerializer):
def serialize(self): ...
class IterableSerializer(BaseSerializer):
def serialize(self): ...
class ModelFieldSerializer(DeconstructableSerializer):
value: Field
def serialize(self) -> Tuple[str, Set[str]]: ...
class ModelManagerSerializer(DeconstructableSerializer):
def serialize(self): ...
class OperationSerializer(BaseSerializer):
def serialize(self): ...
class RegexSerializer(BaseSerializer):
def serialize(self): ...
class FunctionTypeSerializer(BaseSerializer): ...
class FunctoolsPartialSerializer(BaseSerializer): ...
class IterableSerializer(BaseSerializer): ...
class ModelFieldSerializer(DeconstructableSerializer): ...
class ModelManagerSerializer(DeconstructableSerializer): ...
class OperationSerializer(BaseSerializer): ...
class RegexSerializer(BaseSerializer): ...
class SequenceSerializer(BaseSequenceSerializer): ...
class SetSerializer(BaseSequenceSerializer): ...
class SettingsReferenceSerializer(BaseSerializer):
def serialize(self): ...
class TimedeltaSerializer(BaseSerializer):
def serialize(self): ...
class TimeSerializer(BaseSerializer):
def serialize(self): ...
class SettingsReferenceSerializer(BaseSerializer): ...
class TimedeltaSerializer(BaseSerializer): ...
class TimeSerializer(BaseSerializer): ...
class TupleSerializer(BaseSequenceSerializer): ...
class TypeSerializer(BaseSerializer):
def serialize(self): ...
class UUIDSerializer(BaseSerializer):
def serialize(self): ...
class TypeSerializer(BaseSerializer): ...
class UUIDSerializer(BaseSerializer): ...
def serializer_factory(value: Any) -> BaseSerializer: ...

View File

@@ -1,9 +1,8 @@
from typing import Any, Dict, Iterator, List, Optional, Tuple, Type, DefaultDict, Union, Sequence
from typing import Any, DefaultDict, Dict, Iterator, List, Optional, Sequence, Tuple, Type, Union
from django.apps.registry import Apps
from django.db.models.base import Model
from django.db.models.manager import Manager
from django.utils.functional import cached_property
from django.db.models.fields import Field

View File

@@ -1,4 +1,4 @@
from typing import Any, Dict, Iterator, List, Optional, Set
from typing import Dict, Iterator, List, Set
from django.db.migrations.operations.base import Operation

View File

@@ -1,12 +1,10 @@
from typing import Any, Optional
from django.utils.functional import SimpleLazyObject
from typing import Any
COMPILED_REGEX_TYPE: Any
class RegexObject:
pattern: str = ...
flags: int = ...
def __init__(self, obj: SimpleLazyObject) -> None: ...
def __init__(self, obj: Any) -> None: ...
def get_migration_name_timestamp() -> str: ...

View File

@@ -1,13 +1,10 @@
from typing import Any, Optional, Set, Tuple, Type, List, Union
from typing import Any, List, Set, Tuple, Union
from django.db.migrations.migration import Migration
from django.db.migrations.operations.base import Operation
from django.db.migrations.operations.models import CreateModel
class SettingsReference(str):
def __new__(self: Type[SettingsReference], value: str, setting_name: str) -> SettingsReference: ...
setting_name: str = ...
def __init__(self, value: str, setting_name: str) -> None: ...
class OperationWriter:

View File

@@ -8,7 +8,6 @@ from django.core.exceptions import FieldDoesNotExist as FieldDoesNotExist
from django.db.models.expressions import Combinable
from django.db.models.query_utils import RegisterLookupMixin
from django.forms import Field as FormField, Widget
from typing_extensions import Literal
from .mixins import NOT_PROVIDED as NOT_PROVIDED
@@ -72,7 +71,7 @@ class Field(RegisterLookupMixin, Generic[_ST, _GT]):
def to_python(self, value: Any) -> Any: ...
class IntegerField(Field[_ST, _GT]):
_pyi_private_set_type: Union[int, Combinable, Literal[""]]
_pyi_private_set_type: Union[float, int, str, Combinable]
_pyi_private_get_type: int
class PositiveIntegerRelDbTypeMixin:

View File

@@ -5,7 +5,7 @@ from django.db.models.query import QuerySet
_T = TypeVar("_T", bound=Model, covariant=True)
class BaseManager(QuerySet[_T]):
class BaseManager(QuerySet[_T, _T]):
creation_counter: int = ...
auto_created: bool = ...
use_in_migrations: bool = ...
@@ -21,7 +21,7 @@ class BaseManager(QuerySet[_T]):
def _get_queryset_methods(cls, queryset_class: type) -> Dict[str, Any]: ...
def contribute_to_class(self, model: Type[Model], name: str) -> None: ...
def db_manager(self, using: Optional[str] = ..., hints: Optional[Dict[str, Model]] = ...) -> Manager: ...
def get_queryset(self) -> QuerySet[_T]: ...
def get_queryset(self) -> QuerySet[_T, _T]: ...
class Manager(BaseManager[_T]): ...

View File

@@ -1,3 +1,4 @@
import datetime
from typing import (
Any,
Dict,
@@ -13,6 +14,9 @@ from typing import (
TypeVar,
Union,
overload,
Generic,
NamedTuple,
Collection,
)
from django.db.models.base import Model
@@ -46,7 +50,7 @@ class FlatValuesListIterable(BaseIterable):
_T = TypeVar("_T", bound=models.Model, covariant=True)
class QuerySet(Iterable[_T], Sized):
class QuerySet(Generic[_T, _Row], Collection[_Row], Sized):
query: Query
def __init__(
self,
@@ -58,35 +62,34 @@ class QuerySet(Iterable[_T], Sized):
@classmethod
def as_manager(cls) -> Manager[Any]: ...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[_T]: ...
def __iter__(self) -> Iterator[_Row]: ...
def __contains__(self, x: object) -> bool: ...
@overload
def __getitem__(self, i: int) -> _Row: ...
@overload
def __getitem__(self, s: slice) -> QuerySet[_T, _Row]: ...
def __bool__(self) -> bool: ...
def __class_getitem__(cls, item: Type[_T]):
pass
def __getstate__(self) -> Dict[str, Any]: ...
@overload
def __getitem__(self, k: int) -> _T: ...
@overload
def __getitem__(self, k: str) -> Any: ...
@overload
def __getitem__(self, k: slice) -> QuerySet[_T]: ...
def __and__(self, other: QuerySet) -> QuerySet: ...
def __or__(self, other: QuerySet) -> QuerySet: ...
def iterator(self, chunk_size: int = ...) -> Iterator[_T]: ...
# __and__ and __or__ ignore the other QuerySet's _Row type parameter because they use the same row type as the self QuerySet.
# Technically, the other QuerySet must be of the same type _T, but _T is covariant
def __and__(self, other: QuerySet[_T, Any]) -> QuerySet[_T, _Row]: ...
def __or__(self, other: QuerySet[_T, Any]) -> QuerySet[_T, _Row]: ...
def iterator(self, chunk_size: int = ...) -> Iterator[_Row]: ...
def aggregate(self, *args: Any, **kwargs: Any) -> Dict[str, Any]: ...
def get(self, *args: Any, **kwargs: Any) -> _T: ...
def get(self, *args: Any, **kwargs: Any) -> _Row: ...
def create(self, **kwargs: Any) -> _T: ...
def bulk_create(self, objs: Iterable[Model], batch_size: Optional[int] = ...) -> List[_T]: ...
def get_or_create(self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any) -> Tuple[_T, bool]: ...
def update_or_create(
self, defaults: Optional[MutableMapping[str, Any]] = ..., **kwargs: Any
) -> Tuple[_T, bool]: ...
def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _T: ...
def latest(self, *fields: Any, field_name: Optional[Any] = ...) -> _T: ...
def first(self) -> Optional[_T]: ...
def last(self) -> Optional[_T]: ...
def in_bulk(
self, id_list: Any = ..., *, field_name: str = ..., **kwargs: Any
) -> Dict[Union[int, str], models.Model]: ...
def earliest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ...
def latest(self, *fields: Any, field_name: Optional[Any] = ...) -> _Row: ...
def first(self) -> Optional[_Row]: ...
def last(self) -> Optional[_Row]: ...
def in_bulk(self, id_list: Iterable[Any] = ..., *, field_name: str = ...) -> Dict[Any, _T]: ...
def delete(self) -> Tuple[int, Dict[str, int]]: ...
def update(self, **kwargs: Any) -> int: ...
def _update(self, values: Any) -> Optional[Any]: ...
@@ -95,31 +98,38 @@ class QuerySet(Iterable[_T], Sized):
def raw(
self, raw_query: str, params: Any = ..., translations: Optional[Dict[str, str]] = ..., using: None = ...
) -> RawQuerySet: ...
def values(self, *fields: Union[str, Combinable], **expressions: Any) -> QuerySet: ...
def values_list(self, *fields: Union[str, Combinable], flat: bool = ..., named: bool = ...) -> QuerySet: ...
# @overload
# def values_list(self, *fields: Union[str, Combinable], named: Literal[True]) -> NamedValuesListIterable: ...
# @overload
# def values_list(self, *fields: Union[str, Combinable], flat: Literal[True]) -> FlatValuesListIterable: ...
# @overload
# def values_list(self, *fields: Union[str, Combinable]) -> ValuesListIterable: ...
def dates(self, field_name: str, kind: str, order: str = ...) -> QuerySet: ...
def datetimes(self, field_name: str, kind: str, order: str = ..., tzinfo: None = ...) -> QuerySet: ...
def none(self) -> QuerySet[_T]: ...
def all(self) -> QuerySet[_T]: ...
def filter(self, *args: Any, **kwargs: Any) -> QuerySet[_T]: ...
def exclude(self, *args: Any, **kwargs: Any) -> QuerySet[_T]: ...
def complex_filter(self, filter_obj: Any) -> QuerySet[_T]: ...
def values(self, *fields: Union[str, Combinable], **expressions: Any) -> QuerySet[_T, Dict[str, Any]]: ...
@overload
def values_list(
self, *fields: Union[str, Combinable], flat: Literal[False] = ..., named: Literal[True]
) -> QuerySet[_T, NamedTuple]: ...
@overload
def values_list(
self, *fields: Union[str, Combinable], flat: Literal[True], named: Literal[False] = ...
) -> QuerySet[_T, Any]: ...
@overload
def values_list(
self, *fields: Union[str, Combinable], flat: Literal[False] = ..., named: Literal[False] = ...
) -> QuerySet[_T, Tuple]: ...
def dates(self, field_name: str, kind: str, order: str = ...) -> QuerySet[_T, datetime.date]: ...
def datetimes(
self, field_name: str, kind: str, order: str = ..., tzinfo: None = ...
) -> QuerySet[_T, datetime.datetime]: ...
def none(self) -> QuerySet[_T, _Row]: ...
def all(self) -> QuerySet[_T, _Row]: ...
def filter(self, *args: Any, **kwargs: Any) -> QuerySet[_T, _Row]: ...
def exclude(self, *args: Any, **kwargs: Any) -> QuerySet[_T, _Row]: ...
def complex_filter(self, filter_obj: Any) -> QuerySet[_T, _Row]: ...
def count(self) -> int: ...
def union(self, *other_qs: Any, all: bool = ...) -> QuerySet[_T]: ...
def intersection(self, *other_qs: Any) -> QuerySet[_T]: ...
def difference(self, *other_qs: Any) -> QuerySet[_T]: ...
def select_for_update(self, nowait: bool = ..., skip_locked: bool = ..., of: Tuple = ...) -> QuerySet: ...
def select_related(self, *fields: Any) -> QuerySet[_T]: ...
def prefetch_related(self, *lookups: Any) -> QuerySet[_T]: ...
def annotate(self, *args: Any, **kwargs: Any) -> QuerySet[_T]: ...
def order_by(self, *field_names: Any) -> QuerySet[_T]: ...
def distinct(self, *field_names: Any) -> QuerySet[_T]: ...
def union(self, *other_qs: Any, all: bool = ...) -> QuerySet[_T, _Row]: ...
def intersection(self, *other_qs: Any) -> QuerySet[_T, _Row]: ...
def difference(self, *other_qs: Any) -> QuerySet[_T, _Row]: ...
def select_for_update(self, nowait: bool = ..., skip_locked: bool = ..., of: Tuple = ...) -> QuerySet[_T, _Row]: ...
def select_related(self, *fields: Any) -> QuerySet[_T, _Row]: ...
def prefetch_related(self, *lookups: Any) -> QuerySet[_T, _Row]: ...
def annotate(self, *args: Any, **kwargs: Any) -> QuerySet[_T, _Row]: ...
def order_by(self, *field_names: Any) -> QuerySet[_T, _Row]: ...
def distinct(self, *field_names: Any) -> QuerySet[_T, _Row]: ...
def extra(
self,
select: Optional[Dict[str, Any]] = ...,
@@ -128,11 +138,11 @@ class QuerySet(Iterable[_T], Sized):
tables: Optional[List[str]] = ...,
order_by: Optional[Sequence[str]] = ...,
select_params: Optional[Sequence[Any]] = ...,
) -> QuerySet[_T]: ...
def reverse(self) -> QuerySet[_T]: ...
def defer(self, *fields: Any) -> QuerySet[_T]: ...
def only(self, *fields: Any) -> QuerySet[_T]: ...
def using(self, alias: Optional[str]) -> QuerySet[_T]: ...
) -> QuerySet[_T, _Row]: ...
def reverse(self) -> QuerySet[_T, _Row]: ...
def defer(self, *fields: Any) -> QuerySet[_T, _Row]: ...
def only(self, *fields: Any) -> QuerySet[_T, _Row]: ...
def using(self, alias: Optional[str]) -> QuerySet[_T, _Row]: ...
@property
def ordered(self) -> bool: ...
@property
@@ -161,7 +171,7 @@ class RawQuerySet(Iterable[_T], Sized):
@overload
def __getitem__(self, k: str) -> Any: ...
@overload
def __getitem__(self, k: slice) -> QuerySet[_T]: ...
def __getitem__(self, k: slice) -> RawQuerySet[_T]: ...
@property
def columns(self) -> List[str]: ...
@property

View File

@@ -1,5 +1,4 @@
from contextlib import ContextDecorator
from typing import Any, Callable, Optional, Union, Iterator, overload, ContextManager
from typing import Any, Callable, Optional, overload, TypeVar
from django.db import ProgrammingError
@@ -18,19 +17,23 @@ def get_rollback(using: None = ...) -> bool: ...
def set_rollback(rollback: bool, using: Optional[str] = ...) -> None: ...
def on_commit(func: Callable, using: None = ...) -> None: ...
class Atomic(ContextDecorator):
_C = TypeVar("_C", bound=Callable) # Any callable
# Don't inherit from ContextDecorator, so we can provide a more specific signature for __call__
class Atomic:
using: Optional[str] = ...
savepoint: bool = ...
def __init__(self, using: Optional[str], savepoint: bool) -> None: ...
# When decorating, return the decorated function as-is, rather than clobbering it as ContextDecorator does.
def __call__(self, func: _C) -> _C: ...
def __enter__(self) -> None: ...
def __exit__(self, exc_type: None, exc_value: None, traceback: None) -> None: ...
# Bare decorator
@overload
def atomic() -> Atomic: ...
def atomic(using: _C) -> _C: ...
# Decorator or context-manager with parameters
@overload
def atomic(using: Optional[str] = ...,) -> ContextManager[Atomic]: ...
@overload
def atomic(using: Callable = ...) -> Callable: ...
@overload
def atomic(using: Optional[str] = ..., savepoint: bool = ...) -> ContextManager[Atomic]: ...
def atomic(using: Optional[str] = None, savepoint: bool = True) -> Atomic: ...
def non_atomic_requests(using: Callable = ...) -> Callable: ...

View File

@@ -1,12 +1,8 @@
import decimal
from datetime import date, datetime, time, timedelta
from datetime import datetime, timedelta
from decimal import Decimal
from typing import Any, Callable, Dict, List, Optional, Tuple, Union, Type
from uuid import UUID
from typing import Any, Callable, List, Optional, Pattern, Sequence, Type, Union
from django.core.files.base import File
from django.core.validators import BaseValidator
from django.db.models.fields.files import FieldFile
from django.forms.boundfield import BoundField
from django.forms.forms import BaseForm
from django.forms.widgets import Widget
@@ -31,16 +27,16 @@ class Field:
self,
*,
required: bool = ...,
widget: Optional[Any] = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Any = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...
label_suffix: Optional[Any] = ...,
) -> None: ...
def prepare_value(self, value: Any) -> Any: ...
def to_python(self, value: Optional[Any]) -> Optional[Any]: ...
@@ -49,60 +45,60 @@ class Field:
def clean(self, value: Any) -> Any: ...
def bound_data(self, data: Any, initial: Any) -> Any: ...
def widget_attrs(self, widget: Widget) -> Any: ...
def has_changed(self, initial: Any, data: Optional[str]) -> bool: ...
def has_changed(self, initial: Any, data: Any) -> bool: ...
def get_bound_field(self, form: BaseForm, field_name: str) -> BoundField: ...
def __deepcopy__(self, memo: Dict[Any, Any]) -> Field: ...
class CharField(Field):
disabled: bool
error_messages: Dict[str, str]
required: bool
show_hidden_initial: bool
max_length: Optional[Union[int, str]] = ...
min_length: Optional[Union[int, str]] = ...
strip: bool = ...
empty_value: Optional[str] = ...
def __init__(
self,
*,
max_length: Optional[Any] = ...,
min_length: Optional[Any] = ...,
strip: bool = ...,
empty_value: str = ...,
**kwargs: Any
empty_value: Optional[str] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class IntegerField(Field):
disabled: bool
error_messages: Dict[str, str]
max_value: Optional[Any]
min_value: Optional[Any]
required: bool
show_hidden_initial: bool
default_error_messages: Any = ...
re_decimal: Any = ...
def __init__(self, *, max_value: Optional[Any] = ..., min_value: Optional[Any] = ..., **kwargs: Any) -> None: ...
def __init__(
self,
max_value: Optional[Any] = ...,
min_value: Optional[Any] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class FloatField(IntegerField):
disabled: bool
error_messages: Dict[str, str]
max_value: Optional[float]
min_value: Optional[float]
required: bool
show_hidden_initial: bool
default_error_messages: Any = ...
def validate(self, value: Optional[float]) -> None: ...
class DecimalField(IntegerField):
decimal_places: Optional[int]
disabled: bool
error_messages: Dict[str, str]
max_digits: Optional[int]
max_value: Optional[Union[decimal.Decimal, int]]
min_value: Optional[Union[decimal.Decimal, int]]
required: bool
show_hidden_initial: bool
default_error_messages: Any = ...
def __init__(
self,
*,
@@ -110,118 +106,95 @@ class DecimalField(IntegerField):
min_value: Optional[Any] = ...,
max_digits: Optional[Any] = ...,
decimal_places: Optional[Any] = ...,
**kwargs: Any
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
def validate(self, value: Optional[Decimal]) -> None: ...
class BaseTemporalField(Field):
input_formats: Any = ...
def __init__(self, *, input_formats: Optional[Any] = ..., **kwargs: Any) -> None: ...
def strptime(self, value: Any, format: Any) -> Any: ...
def __init__(
self,
input_formats: Optional[Any] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
def strptime(self, value: Any, format: str) -> Any: ...
class DateField(BaseTemporalField):
disabled: bool
error_messages: Dict[str, str]
required: bool
show_hidden_initial: bool
input_formats: Any = ...
default_error_messages: Any = ...
def strptime(self, value: str, format: str) -> date: ...
class TimeField(BaseTemporalField):
disabled: bool
error_messages: Dict[str, str]
required: bool
show_hidden_initial: bool
input_formats: Any = ...
default_error_messages: Any = ...
def strptime(self, value: str, format: str) -> time: ...
class DateTimeField(BaseTemporalField):
disabled: bool
error_messages: Dict[str, str]
required: bool
show_hidden_initial: bool
input_formats: Any = ...
default_error_messages: Any = ...
def prepare_value(self, value: Optional[datetime]) -> Optional[datetime]: ...
def strptime(self, value: str, format: str) -> datetime: ...
class DateField(BaseTemporalField): ...
class TimeField(BaseTemporalField): ...
class DateTimeField(BaseTemporalField): ...
class DurationField(Field):
disabled: bool
required: bool
show_hidden_initial: bool
default_error_messages: Any = ...
def prepare_value(self, value: Optional[Union[timedelta, str]]) -> Optional[str]: ...
class RegexField(CharField):
disabled: bool
empty_value: str
error_messages: Dict[str, str]
max_length: Optional[int]
min_length: Optional[int]
required: bool
show_hidden_initial: bool
strip: bool
def __init__(self, regex: str, **kwargs: Any) -> None: ...
regex: Any = ...
regex: str = ...
def __init__(
self,
regex: Union[str, Pattern],
max_length: Optional[Any] = ...,
min_length: Optional[Any] = ...,
strip: bool = ...,
empty_value: Optional[str] = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class EmailField(CharField):
disabled: bool
empty_value: Optional[str]
error_messages: Dict[str, str]
max_length: Optional[int]
min_length: Optional[int]
required: bool
show_hidden_initial: bool
strip: bool
default_validators: Any = ...
def __init__(self, **kwargs: Any) -> None: ...
class EmailField(CharField): ...
class FileField(Field):
disabled: bool
required: bool
show_hidden_initial: bool
default_error_messages: Any = ...
max_length: Optional[int] = ...
allow_empty_file: bool = ...
def __init__(self, *, max_length: Optional[Any] = ..., allow_empty_file: bool = ..., **kwargs: Any) -> None: ...
def bound_data(self, data: Any, initial: Optional[FieldFile]) -> Optional[Union[File, str]]: ...
def __init__(
self,
max_length: Optional[Any] = ...,
allow_empty_file: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
def clean(self, data: Any, initial: Optional[Any] = ...): ...
class ImageField(FileField):
allow_empty_file: bool
disabled: bool
max_length: Optional[int]
required: bool
show_hidden_initial: bool
default_validators: Any = ...
default_error_messages: Any = ...
class URLField(CharField):
disabled: bool
empty_value: Optional[str]
error_messages: Dict[str, str]
max_length: Optional[int]
min_length: Optional[int]
required: bool
show_hidden_initial: bool
strip: bool
default_error_messages: Any = ...
default_validators: Any = ...
def __init__(self, **kwargs: Any) -> None: ...
class BooleanField(Field):
disabled: bool
error_messages: Dict[str, str]
required: bool
show_hidden_initial: bool
def validate(self, value: bool) -> None: ...
class NullBooleanField(BooleanField):
disabled: bool
required: bool
show_hidden_initial: bool
def validate(self, value: Optional[bool]) -> None: ...
class ImageField(FileField): ...
class URLField(CharField): ...
class BooleanField(Field): ...
class NullBooleanField(BooleanField): ...
class CallableChoiceIterator:
choices_func: Callable = ...
@@ -229,125 +202,191 @@ class CallableChoiceIterator:
def __iter__(self) -> None: ...
class ChoiceField(Field):
disabled: bool
error_messages: Dict[str, str]
required: bool
show_hidden_initial: bool
default_error_messages: Any = ...
choices: Any = ...
def __init__(self, *, choices: Any = ..., **kwargs: Any) -> None: ...
def validate(self, value: Any) -> None: ...
def __init__(
self,
choices: Any = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
def valid_value(self, value: str) -> bool: ...
class TypedChoiceField(ChoiceField):
disabled: bool
required: bool
show_hidden_initial: bool
coerce: Union[Callable, Type[Union[bool, float, str]]] = ...
coerce: Union[Callable, Type[Any]] = ...
empty_value: Optional[str] = ...
def __init__(self, *, coerce: Any = ..., empty_value: str = ..., **kwargs: Any) -> None: ...
def __init__(
self,
coerce: Any = ...,
empty_value: Optional[str] = ...,
choices: Any = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class MultipleChoiceField(ChoiceField):
disabled: bool
error_messages: Dict[str, str]
required: bool
show_hidden_initial: bool
hidden_widget: Any = ...
default_error_messages: Any = ...
def validate(self, value: List[str]) -> None: ...
class MultipleChoiceField(ChoiceField): ...
class TypedMultipleChoiceField(MultipleChoiceField):
disabled: bool
required: bool
show_hidden_initial: bool
coerce: Union[Callable, Type[float]] = ...
empty_value: Optional[List[Any]] = ...
def __init__(self, *, coerce: Any = ..., **kwargs: Any) -> None: ...
def validate(self, value: List[str]) -> None: ...
def __init__(
self,
coerce: Any = ...,
empty_value: Optional[str] = ...,
choices: Any = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class ComboField(Field):
disabled: bool
required: bool
show_hidden_initial: bool
fields: Any = ...
def __init__(self, fields: List[CharField], **kwargs: Any) -> None: ...
def __init__(
self,
fields: Sequence[Field],
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class MultiValueField(Field):
disabled: bool
required: bool
show_hidden_initial: bool
default_error_messages: Any = ...
require_all_fields: bool = ...
fields: Any = ...
def __init__(self, fields: Tuple[Field, Field], *, require_all_fields: bool = ..., **kwargs: Any) -> None: ...
def validate(self, value: Union[datetime, str]) -> None: ...
def __init__(
self,
fields: Sequence[Field],
require_all_fields: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
def compress(self, data_list: Any) -> Any: ...
class FilePathField(ChoiceField):
allow_files: bool
allow_folders: bool
disabled: bool
match: Optional[str]
path: str
recursive: bool
required: bool
show_hidden_initial: bool
choices: Any = ...
match_re: Any = ...
def __init__(
self,
path: str,
*,
match: Optional[Any] = ...,
recursive: bool = ...,
allow_files: bool = ...,
allow_folders: bool = ...,
**kwargs: Any
choices: Any = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class SplitDateTimeField(MultiValueField):
disabled: bool
require_all_fields: bool
required: bool
show_hidden_initial: bool
hidden_widget: Any = ...
default_error_messages: Any = ...
def __init__(
self, *, input_date_formats: Optional[Any] = ..., input_time_formats: Optional[Any] = ..., **kwargs: Any
self,
input_date_formats: Optional[Any] = ...,
input_time_formats: Optional[Any] = ...,
fields: Sequence[Field] = ...,
require_all_fields: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
def compress(self, data_list: List[Optional[datetime]]) -> Optional[datetime]: ...
class GenericIPAddressField(CharField):
disabled: bool
empty_value: str
error_messages: Dict[str, str]
max_length: None
min_length: None
required: bool
show_hidden_initial: bool
strip: bool
unpack_ipv4: bool = ...
default_validators: List[Callable] = ...
def __init__(self, *, protocol: str = ..., unpack_ipv4: bool = ..., **kwargs: Any) -> None: ...
def __init__(
self,
protocol: str = ...,
unpack_ipv4: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class SlugField(CharField):
disabled: bool
empty_value: str
max_length: Optional[int]
min_length: None
required: bool
show_hidden_initial: bool
strip: bool
allow_unicode: bool = ...
def __init__(self, *, allow_unicode: bool = ..., **kwargs: Any) -> None: ...
def __init__(
self,
allow_unicode: bool = ...,
required: bool = ...,
widget: Optional[Union[Widget, Type[Widget]]] = ...,
label: Optional[Any] = ...,
initial: Optional[Any] = ...,
help_text: str = ...,
error_messages: Optional[Any] = ...,
show_hidden_initial: bool = ...,
validators: Sequence[Any] = ...,
localize: bool = ...,
disabled: bool = ...,
label_suffix: Optional[Any] = ...,
) -> None: ...
class UUIDField(CharField):
disabled: bool
empty_value: str
max_length: None
min_length: None
required: bool
show_hidden_initial: bool
strip: bool
default_error_messages: Any = ...
def prepare_value(self, value: UUID) -> str: ...
class UUIDField(CharField): ...

View File

@@ -1,48 +1,46 @@
from collections import OrderedDict
from datetime import datetime
from typing import Any, Dict, Iterator, List, Mapping, Optional, Tuple, Type, Union
from typing import Any, Dict, Iterator, List, Mapping, Optional, Sequence, Type, Union
from django.core.exceptions import ValidationError as ValidationError
from django.core.files.base import File
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db.models.query import QuerySet
from django.forms.boundfield import BoundField
from django.forms.fields import Field
from django.forms.renderers import BaseRenderer
from django.forms.utils import ErrorDict, ErrorList
from django.forms.widgets import Media, MediaDefiningClass
from django.utils.safestring import SafeText
class DeclarativeFieldsMetaclass(MediaDefiningClass):
def __new__(
mcs: Type[DeclarativeFieldsMetaclass], name: str, bases: Tuple[Type[BaseForm]], attrs: OrderedDict
) -> Type[BaseForm]: ...
def __new__(mcs, name: str, bases: Sequence[Type[BaseForm]], attrs: Dict[str, Any]) -> Type[BaseForm]: ...
class BaseForm:
default_renderer: Any = ...
field_order: Any = ...
prefix: Any = ...
use_required_attribute: bool = ...
is_bound: Any = ...
data: Any = ...
files: Any = ...
is_bound: bool = ...
data: Dict[str, Any] = ...
files: Optional[Dict[str, Any]] = ...
auto_id: Any = ...
initial: Any = ...
error_class: Any = ...
label_suffix: Any = ...
empty_permitted: Any = ...
fields: Any = ...
renderer: Any = ...
initial: Dict[str, Any] = ...
error_class: Type[ErrorList] = ...
prefix: str = ...
label_suffix: str = ...
empty_permitted: bool = ...
fields: Dict[str, Any] = ...
renderer: BaseRenderer = ...
cleaned_data: Any = ...
def __init__(
self,
data: Optional[Mapping[str, Any]] = ...,
files: Optional[Mapping[str, File]] = ...,
files: Optional[Mapping[str, Any]] = ...,
auto_id: Optional[Union[bool, str]] = ...,
prefix: Optional[str] = ...,
initial: Optional[Mapping[str, Any]] = ...,
error_class: Type[ErrorList] = ...,
label_suffix: None = ...,
label_suffix: Optional[str] = ...,
empty_permitted: bool = ...,
field_order: None = ...,
field_order: Optional[Any] = ...,
use_required_attribute: Optional[bool] = ...,
renderer: Any = ...,
) -> None: ...
@@ -60,7 +58,6 @@ class BaseForm:
def non_field_errors(self) -> ErrorList: ...
def add_error(self, field: Optional[str], error: Union[ValidationError, str]) -> None: ...
def has_error(self, field: Any, code: Optional[Any] = ...): ...
cleaned_data: Any = ...
def full_clean(self) -> None: ...
def clean(self) -> Dict[str, Optional[Union[datetime, SimpleUploadedFile, QuerySet, str]]]: ...
def has_changed(self) -> bool: ...

View File

@@ -1,8 +1,4 @@
import collections
from typing import Any, List, Optional, Union, Dict, Type
from django.forms.renderers import BaseRenderer
from django.forms.utils import ErrorList
from typing import Any, Dict, Mapping, Optional, Sequence, Sized
from django.forms import Form
@@ -17,21 +13,9 @@ DEFAULT_MIN_NUM: int = ...
DEFAULT_MAX_NUM: int = ...
class ManagementForm(Form):
auto_id: Union[bool, str]
cleaned_data: Dict[str, Optional[int]]
data: Dict[str, Union[List[int], int, str]]
empty_permitted: bool
error_class: Type[ErrorList]
fields: collections.OrderedDict
files: Dict[Any, Any]
initial: Dict[str, int]
is_bound: bool
label_suffix: str
prefix: str
renderer: BaseRenderer
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
class BaseFormSet:
class BaseFormSet(Sized, Mapping[str, Any]):
is_bound: Any = ...
prefix: Any = ...
auto_id: Any = ...
@@ -57,6 +41,7 @@ class BaseFormSet:
def management_form(self): ...
def total_form_count(self): ...
def initial_form_count(self): ...
@property
def forms(self): ...
def get_form_kwargs(self, index: Any): ...
@property
@@ -101,4 +86,4 @@ def formset_factory(
min_num: Optional[Any] = ...,
validate_min: bool = ...,
): ...
def all_valid(formsets: List[Any]) -> bool: ...
def all_valid(formsets: Sequence[Any]) -> bool: ...

View File

@@ -1,10 +1,11 @@
from collections import OrderedDict
from datetime import date, datetime
from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Type, Union, Sequence
from typing import Any, Callable, Dict, Iterator, List, MutableMapping, Optional, Sequence, Tuple, Type, Union, Mapping
from unittest.mock import MagicMock
from uuid import UUID
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.files.base import File
from django.db import models
from django.db.models import ForeignKey
from django.db.models.base import Model
from django.db.models.manager import Manager
@@ -14,25 +15,22 @@ from django.forms.fields import CharField, ChoiceField, Field
from django.forms.forms import BaseForm, DeclarativeFieldsMetaclass
from django.forms.formsets import BaseFormSet
from django.forms.utils import ErrorList
from django.forms.widgets import Input, Widget, Select
from django.http.request import QueryDict
from django.utils.datastructures import MultiValueDict
from django.forms.widgets import Input, Widget
from typing_extensions import Literal
ALL_FIELDS: str
_Fields = Union[List[Union[Callable, str]], Tuple[str]]
_Fields = Union[List[Union[Callable, str]], Sequence[str], Literal["__all__"]]
_Labels = Dict[str, str]
_ErrorMessages = Dict[str, Dict[str, str]]
def model_to_dict(
instance: Model,
fields: Optional[_Fields] = ...,
exclude: Optional[Union[List[Union[Callable, str]], Tuple[str]]] = ...,
) -> Dict[str, Optional[Union[bool, date, float]]]: ...
instance: Model, fields: Optional[_Fields] = ..., exclude: Optional[_Fields] = ...
) -> Dict[str, Any]: ...
def fields_for_model(
model: Type[Model],
fields: Optional[_Fields] = ...,
exclude: Optional[Union[List[Union[Callable, str]], Tuple]] = ...,
exclude: Optional[_Fields] = ...,
widgets: Optional[Union[Dict[str, Type[Input]], Dict[str, Widget]]] = ...,
formfield_callback: Optional[Union[Callable, str]] = ...,
localized_fields: Optional[Union[Tuple[str], str]] = ...,
@@ -42,12 +40,12 @@ def fields_for_model(
field_classes: Optional[Dict[str, Type[CharField]]] = ...,
*,
apply_limit_choices_to: bool = ...
) -> OrderedDict: ...
) -> Dict[str, Any]: ...
class ModelFormOptions:
model: Optional[Type[Model]] = ...
fields: Optional[_Fields] = ...
exclude: Optional[Union[List[Union[Callable, str]], Tuple, str]] = ...
exclude: Optional[_Fields] = ...
widgets: Optional[Dict[str, Union[Widget, Input]]] = ...
localized_fields: Optional[Union[Tuple[str], str]] = ...
labels: Optional[_Labels] = ...
@@ -57,46 +55,44 @@ class ModelFormOptions:
def __init__(self, options: Optional[type] = ...) -> None: ...
class ModelFormMetaclass(DeclarativeFieldsMetaclass):
def __new__(
mcs: Type[ModelFormMetaclass], name: str, bases: Tuple[Type[ModelForm]], attrs: OrderedDict
) -> Type[ModelForm]: ...
def __new__(mcs, name: str, bases: Sequence[Type[Any]], attrs: Dict[str, Any]) -> Type[ModelForm]: ...
class BaseModelForm(BaseForm):
instance: Any = ...
def __init__(
self,
data: Optional[Union[Dict[str, Any], QueryDict]] = ...,
files: Optional[Union[Dict[str, SimpleUploadedFile], MultiValueDict]] = ...,
data: Optional[Mapping[str, Any]] = ...,
files: Optional[Mapping[str, File]] = ...,
auto_id: Union[bool, str] = ...,
prefix: None = ...,
initial: Optional[Union[Dict[str, List[int]], Dict[str, int]]] = ...,
prefix: Optional[str] = ...,
initial: Optional[Dict[str, Any]] = ...,
error_class: Type[ErrorList] = ...,
label_suffix: None = ...,
label_suffix: Optional[str] = ...,
empty_permitted: bool = ...,
instance: Optional[Model] = ...,
use_required_attribute: None = ...,
use_required_attribute: Optional[bool] = ...,
renderer: Any = ...,
) -> None: ...
def clean(self) -> Dict[str, Any]: ...
def validate_unique(self) -> None: ...
save_m2m: Any = ...
def save(self, commit: bool = ...) -> Model: ...
def save(self, commit: bool = ...) -> Any: ...
class ModelForm(BaseModelForm): ...
def modelform_factory(
model: Type[Model],
form: Type[ModelForm] = ...,
fields: Optional[Union[List[str], str]] = ...,
exclude: None = ...,
formfield_callback: Optional[str] = ...,
widgets: None = ...,
localized_fields: None = ...,
labels: None = ...,
help_texts: None = ...,
error_messages: None = ...,
field_classes: None = ...,
) -> Any: ...
fields: Optional[_Fields] = ...,
exclude: Optional[_Fields] = ...,
formfield_callback: Optional[Union[str, Callable[[models.Field], Field]]] = ...,
widgets: Optional[MutableMapping[str, Widget]] = ...,
localized_fields: Optional[Sequence[str]] = ...,
labels: Optional[MutableMapping[str, str]] = ...,
help_texts: Optional[MutableMapping[str, str]] = ...,
error_messages: Optional[MutableMapping[str, Dict[str, Any]]] = ...,
field_classes: Optional[MutableMapping[str, Type[Field]]] = ...,
) -> Type[ModelForm]: ...
class BaseModelFormSet(BaseFormSet):
model: Any = ...
@@ -144,17 +140,17 @@ def modelformset_factory(
can_order: bool = ...,
min_num: Optional[int] = ...,
max_num: Optional[int] = ...,
fields: Optional[Union[str, Sequence[str]]] = ...,
exclude: Optional[Sequence[str]] = ...,
fields: Optional[_Fields] = ...,
exclude: Optional[_Fields] = ...,
widgets: Optional[Dict[str, Any]] = ...,
validate_max: bool = ...,
localized_fields: None = ...,
localized_fields: Optional[Sequence[str]] = ...,
labels: Optional[Dict[str, str]] = ...,
help_texts: Optional[Dict[str, str]] = ...,
error_messages: Optional[Dict[str, Dict[str, str]]] = ...,
validate_min: bool = ...,
field_classes: Optional[Dict[str, Any]] = ...,
) -> Any: ...
field_classes: Optional[Dict[str, Type[Field]]] = ...,
) -> Type[BaseModelFormSet]: ...
class BaseInlineFormSet(BaseModelFormSet):
instance: Any = ...
@@ -183,8 +179,8 @@ def inlineformset_factory(
form: Type[ModelForm] = ...,
formset: Type[BaseInlineFormSet] = ...,
fk_name: Optional[str] = ...,
fields: Optional[Union[str, Sequence[str]]] = ...,
exclude: Optional[Sequence[str]] = ...,
fields: Optional[_Fields] = ...,
exclude: Optional[_Fields] = ...,
extra: int = ...,
can_order: bool = ...,
can_delete: bool = ...,
@@ -192,14 +188,14 @@ def inlineformset_factory(
formfield_callback: Optional[Callable] = ...,
widgets: Optional[Dict[str, Any]] = ...,
validate_max: bool = ...,
localized_fields: None = ...,
localized_fields: Optional[Sequence[str]] = ...,
labels: Optional[Dict[str, str]] = ...,
help_texts: Optional[Dict[str, str]] = ...,
error_messages: Optional[Dict[str, Dict[str, str]]] = ...,
min_num: Optional[int] = ...,
validate_min: bool = ...,
field_classes: Optional[Dict[str, Any]] = ...,
) -> Any: ...
) -> Type[BaseInlineFormSet]: ...
class InlineForeignKeyField(Field):
disabled: bool
@@ -241,7 +237,7 @@ class ModelChoiceField(ChoiceField):
self,
queryset: Optional[Union[Manager, QuerySet]],
*,
empty_label: str = ...,
empty_label: Optional[str] = ...,
required: bool = ...,
widget: Optional[Any] = ...,
label: Optional[Any] = ...,

View File

@@ -1,16 +1,16 @@
from collections import UserList
from datetime import datetime
from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union, Sequence
from typing import Any, Dict, List, Optional, Sequence, Union
from django.core.exceptions import ValidationError
from django.utils.safestring import SafeText
def pretty_name(name: str) -> str: ...
def flatatt(attrs: Dict[str, Optional[str]]) -> SafeText: ...
def flatatt(attrs: Dict[str, Any]) -> SafeText: ...
class ErrorDict(dict):
def as_data(self) -> Dict[str, List[ValidationError]]: ...
def get_json_data(self, escape_html: bool = ...) -> Dict[str, List[Dict[str, str]]]: ...
def get_json_data(self, escape_html: bool = ...) -> Dict[str, Any]: ...
def as_json(self, escape_html: bool = ...) -> str: ...
def as_ul(self) -> str: ...
def as_text(self) -> str: ...
@@ -19,16 +19,15 @@ class ErrorList(UserList):
data: List[Union[ValidationError, str]]
error_class: str = ...
def __init__(
self, initlist: Optional[Union[ErrorList, Sequence[str]]] = ..., error_class: Optional[str] = ...
self,
initlist: Optional[Union[ErrorList, Sequence[Union[str, Exception]]]] = ...,
error_class: Optional[str] = ...,
) -> None: ...
def as_data(self) -> List[ValidationError]: ...
def get_json_data(self, escape_html: bool = ...) -> List[Dict[str, str]]: ...
def as_json(self, escape_html: bool = ...) -> str: ...
def as_ul(self) -> str: ...
def as_text(self) -> str: ...
def __reduce_ex__(
self, *args: Any, **kwargs: Any
) -> Tuple[Callable, Tuple[Type[ErrorList]], Dict[str, Union[List[ValidationError], str]], None, None]: ...
def from_current_timezone(value: datetime) -> datetime: ...
def to_current_timezone(value: datetime) -> datetime: ...

View File

@@ -1,17 +1,16 @@
from datetime import time
from decimal import Decimal
from itertools import chain
from typing import Any, Callable, Dict, Iterator, List, Optional, Set, Tuple, Type, Union, Iterable, Sequence
from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Sequence, Set, Tuple, Type, Union
from django.contrib.admin.options import BaseModelAdmin
from django.core.files.base import File
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db.models.fields.files import FieldFile
from django.forms.forms import BaseForm
from django.forms.renderers import EngineMixin
from django.utils.datastructures import MultiValueDict
from django.utils.safestring import SafeText
_OptAttrs = Dict[str, str]
class MediaOrderConflictWarning(RuntimeWarning): ...
class Media:
@@ -32,9 +31,7 @@ class Media:
def __add__(self, other: Media) -> Media: ...
class MediaDefiningClass(type):
def __new__(
mcs: Type[MediaDefiningClass], name: str, bases: Tuple, attrs: Any
) -> Type[Union[BaseModelAdmin, BaseForm, Widget]]: ...
def __new__(mcs, name: str, bases: Sequence[Any], attrs: Dict[str, Any]) -> type: ...
class Widget:
needs_multipart_form: bool = ...
@@ -61,10 +58,10 @@ class Widget:
self, base_attrs: Dict[str, Union[float, str]], extra_attrs: Optional[Dict[str, Union[bool, str]]] = ...
) -> Dict[str, Union[Decimal, float, str]]: ...
def value_from_datadict(
self, data: dict, files: Union[Dict[str, SimpleUploadedFile], MultiValueDict], name: str
self, data: dict, files: Union[Dict[str, Iterable[Any]], MultiValueDict], name: str
) -> Any: ...
def value_omitted_from_data(
self, data: Dict[str, Any], files: Union[Dict[str, SimpleUploadedFile], MultiValueDict], name: str
self, data: Dict[str, Any], files: Union[Dict[str, Iterable[Any]], MultiValueDict], name: str
) -> bool: ...
def id_for_label(self, id_: str) -> str: ...
def use_required_attribute(self, initial: Any) -> bool: ...
@@ -80,6 +77,7 @@ class URLInput(Input): ...
class PasswordInput(Input):
render_value: bool = ...
def __init__(self, attrs: Optional[_OptAttrs] = ..., render_value: bool = ...): ...
class HiddenInput(Input):
choices: Iterable[Tuple[str, str]]
@@ -105,6 +103,7 @@ class DateTimeBaseInput(TextInput):
format_key: str = ...
supports_microseconds: bool = ...
format: Optional[str] = ...
def __init__(self, attrs: Optional[_OptAttrs] = ..., format: Optional[str] = ...): ...
class DateInput(DateTimeBaseInput): ...
class DateTimeInput(DateTimeBaseInput): ...
@@ -112,9 +111,7 @@ class TimeInput(DateTimeBaseInput): ...
class CheckboxInput(Input):
check_test: Callable = ...
def __init__(self, attrs: Optional[Dict[str, str]] = ..., check_test: Optional[Callable] = ...) -> None: ...
_OptAttrs = Dict[str, Any]
def __init__(self, attrs: Optional[_OptAttrs] = ..., check_test: Optional[Callable] = ...) -> None: ...
class ChoiceWidget(Widget):
allow_multiple_selected: bool = ...
@@ -165,7 +162,7 @@ class CheckboxSelectMultiple(ChoiceWidget):
class MultiWidget(Widget):
template_name: str = ...
widgets: List[Widget] = ...
def __init__(self, widgets: Sequence[Widget], attrs: Optional[_OptAttrs] = ...) -> None: ...
def __init__(self, widgets: Sequence[Union[Widget, Type[Widget]]], attrs: Optional[_OptAttrs] = ...) -> None: ...
@property
def is_hidden(self) -> bool: ...
def decompress(self, value: Any) -> Optional[Any]: ...
@@ -209,7 +206,7 @@ class SelectDateWidget(Widget):
def __init__(
self,
attrs: Optional[_OptAttrs] = ...,
years: Optional[Union[Tuple[Union[int, str]], range]] = ...,
months: None = ...,
empty_label: Optional[Union[Tuple[str, str], str]] = ...,
years: Optional[Iterable[Union[int, str]]] = ...,
months: Optional[Dict[int, str]] = ...,
empty_label: Optional[Union[str, Sequence[str]]] = ...,
) -> None: ...

View File

@@ -1,9 +1,8 @@
import datetime
from io import BytesIO
from json import JSONEncoder
from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple, Type, Union, overload, AnyStr, IO
from typing import Any, Dict, Iterable, Iterator, List, Optional, Tuple, Type, Union, overload
import six
from django.core.handlers.wsgi import WSGIRequest
from django.http.cookie import SimpleCookie
from django.test.client import Client
@@ -13,7 +12,7 @@ from django.urls import ResolverMatch
class BadHeaderError(ValueError): ...
class HttpResponseBase(Iterable[AnyStr]):
class HttpResponseBase(Iterable[Any]):
status_code: int = ...
cookies: SimpleCookie = ...
reason_phrase: str = ...
@@ -60,7 +59,7 @@ class HttpResponseBase(Iterable[AnyStr]):
def seekable(self) -> bool: ...
def writable(self) -> bool: ...
def writelines(self, lines: Iterable[object]): ...
def __iter__(self) -> Iterator[AnyStr]: ...
def __iter__(self) -> Iterator[Any]: ...
class HttpResponse(HttpResponseBase):
client: Client
@@ -70,7 +69,6 @@ class HttpResponse(HttpResponseBase):
request: Dict[str, Any]
resolver_match: ResolverMatch
sameorigin: bool
status_code: int
templates: List[Template]
test_server_port: str
test_was_secure_request: bool
@@ -88,21 +86,13 @@ class HttpResponse(HttpResponseBase):
def json(self) -> Dict[str, Any]: ...
class StreamingHttpResponse(HttpResponseBase):
def __init__(self, streaming_content: Iterable[AnyStr] = ..., *args: Any, **kwargs: Any) -> None: ...
@property
def content(self) -> AnyStr: ...
@content.setter
def content(self, value: AnyStr) -> None: ...
@property
def streaming_content(self) -> Iterator[AnyStr]: ...
@streaming_content.setter
def streaming_content(self, value: Iterable[AnyStr]) -> None: ...
def __iter__(self) -> Iterator[AnyStr]: ...
def getvalue(self) -> AnyStr: ...
content: Any
streaming_content: Iterator[Any]
def __init__(self, streaming_content: Iterable[Any] = ..., *args: Any, **kwargs: Any) -> None: ...
def getvalue(self) -> Any: ...
class FileResponse(StreamingHttpResponse):
client: Client
closed: bool
context: None
file_to_stream: Optional[BytesIO]
request: Dict[str, str]
@@ -119,8 +109,6 @@ class FileResponse(StreamingHttpResponse):
class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ... # type: List[str]
def __init__(self, redirect_to: str, *args: Any, **kwargs: Any) -> None: ...
@property
def url(self) -> str: ...
class HttpResponseRedirect(HttpResponseRedirectBase): ...
class HttpResponsePermanentRedirect(HttpResponseRedirectBase): ...

View File

@@ -1,4 +1,4 @@
from typing import Any, Optional, Union
from typing import Any, Optional, Union, Callable
from django.http.request import HttpRequest
from django.http.response import HttpResponse, HttpResponseBase
@@ -26,4 +26,6 @@ class CacheMiddleware(UpdateCacheMiddleware, FetchFromCacheMiddleware):
cache_alias: str = ...
cache_timeout: float = ...
cache: BaseCache = ...
def __init__(self, get_response: None = ..., cache_timeout: Optional[float] = ..., **kwargs: Any) -> None: ...
def __init__(
self, get_response: Optional[Callable] = ..., cache_timeout: Optional[float] = ..., **kwargs: Any
) -> None: ...

View File

@@ -1,10 +1,10 @@
from typing import Any
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import HttpResponseBase
from django.utils.deprecation import MiddlewareMixin
re_accepts_gzip: Any
class GZipMiddleware(MiddlewareMixin):
def process_response(self, request: WSGIRequest, response: HttpResponseBase) -> HttpResponseBase: ...
def process_response(self, request: HttpRequest, response: HttpResponseBase) -> HttpResponseBase: ...

View File

@@ -1,7 +1,7 @@
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import HttpResponseBase
from django.utils.deprecation import MiddlewareMixin
class ConditionalGetMiddleware(MiddlewareMixin):
def process_response(self, request: WSGIRequest, response: HttpResponseBase) -> HttpResponseBase: ...
def process_response(self, request: HttpRequest, response: HttpResponseBase) -> HttpResponseBase: ...
def needs_etag(self, response: HttpResponseBase) -> bool: ...

View File

@@ -1,10 +1,10 @@
from typing import Any
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import HttpResponseBase
from django.utils.deprecation import MiddlewareMixin
class LocaleMiddleware(MiddlewareMixin):
response_redirect_class: Any = ...
def process_request(self, request: WSGIRequest) -> None: ...
def process_response(self, request: WSGIRequest, response: HttpResponseBase) -> HttpResponseBase: ...
def process_request(self, request: HttpRequest) -> None: ...
def process_response(self, request: HttpRequest, response: HttpResponseBase) -> HttpResponseBase: ...

View File

@@ -1,6 +1,6 @@
from typing import Any, Optional, List
from typing import Any, List, Optional
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import HttpResponse, HttpResponsePermanentRedirect
from django.utils.deprecation import MiddlewareMixin
@@ -13,5 +13,5 @@ class SecurityMiddleware(MiddlewareMixin):
redirect: bool = ...
redirect_host: Optional[str] = ...
redirect_exempt: List[Any] = ...
def process_request(self, request: WSGIRequest) -> Optional[HttpResponsePermanentRedirect]: ...
def process_response(self, request: WSGIRequest, response: HttpResponse) -> HttpResponse: ...
def process_request(self, request: HttpRequest) -> Optional[HttpResponsePermanentRedirect]: ...
def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse: ...

View File

@@ -31,6 +31,6 @@ def redirect(
_T = TypeVar("_T", bound=Model)
def get_object_or_404(klass: Union[Type[_T], Manager[_T], QuerySet[_T]], *args: Any, **kwargs: Any) -> _T: ...
def get_list_or_404(klass: Union[Type[_T], Manager[_T], QuerySet[_T]], *args: Any, **kwargs: Any) -> List[_T]: ...
def get_object_or_404(klass: Union[Type[_T], Manager[_T], QuerySet[_T, _T]], *args: Any, **kwargs: Any) -> _T: ...
def get_list_or_404(klass: Union[Type[_T], Manager[_T], QuerySet[_T, _T]], *args: Any, **kwargs: Any) -> List[_T]: ...
def resolve_url(to: Union[Callable, Model, str], *args: Any, **kwargs: Any) -> str: ...

View File

@@ -9,8 +9,6 @@ from django.http.cookie import SimpleCookie
from django.http.request import HttpRequest
from django.http.response import HttpResponse, HttpResponseBase
from django.core.handlers.wsgi import WSGIRequest
BOUNDARY: str = ...
MULTIPART_CONTENT: str = ...
CONTENT_TYPE_RE: Pattern = ...
@@ -42,13 +40,13 @@ class RequestFactory:
cookies: SimpleCookie = ...
errors: BytesIO = ...
def __init__(self, *, json_encoder: Any = ..., **defaults: Any) -> None: ...
def request(self, **request: Any) -> WSGIRequest: ...
def get(self, path: str, data: Any = ..., secure: bool = ..., **extra: Any) -> WSGIRequest: ...
def request(self, **request: Any) -> HttpRequest: ...
def get(self, path: str, data: Any = ..., secure: bool = ..., **extra: Any) -> HttpRequest: ...
def post(
self, path: str, data: Any = ..., content_type: str = ..., secure: bool = ..., **extra: Any
) -> WSGIRequest: ...
def head(self, path: str, data: Any = ..., secure: bool = ..., **extra: Any) -> WSGIRequest: ...
def trace(self, path: str, secure: bool = ..., **extra: Any) -> WSGIRequest: ...
) -> HttpRequest: ...
def head(self, path: str, data: Any = ..., secure: bool = ..., **extra: Any) -> HttpRequest: ...
def trace(self, path: str, secure: bool = ..., **extra: Any) -> HttpRequest: ...
def options(
self,
path: str,
@@ -56,16 +54,16 @@ class RequestFactory:
content_type: str = ...,
secure: bool = ...,
**extra: Any
) -> WSGIRequest: ...
) -> HttpRequest: ...
def put(
self, path: str, data: Any = ..., content_type: str = ..., secure: bool = ..., **extra: Any
) -> WSGIRequest: ...
) -> HttpRequest: ...
def patch(
self, path: str, data: Any = ..., content_type: str = ..., secure: bool = ..., **extra: Any
) -> WSGIRequest: ...
) -> HttpRequest: ...
def delete(
self, path: str, data: Any = ..., content_type: str = ..., secure: bool = ..., **extra: Any
) -> WSGIRequest: ...
) -> HttpRequest: ...
def generic(
self,
method: str,
@@ -74,7 +72,7 @@ class RequestFactory:
content_type: Optional[str] = ...,
secure: bool = ...,
**extra: Any
) -> WSGIRequest: ...
) -> HttpRequest: ...
class Client:
json_encoder: Type[DjangoJSONEncoder] = ...

View File

@@ -1,5 +1,5 @@
from html.parser import HTMLParser
from typing import Any, List, Optional, Tuple, Union, TypeVar, Iterable, Sequence
from typing import Any, List, Optional, Sequence, Tuple, TypeVar, Union
_Self = TypeVar("_Self")

View File

@@ -1,22 +1,14 @@
from typing import Any, Callable, Dict, List, Tuple, Type, Union
from typing import Any
from django.test import LiveServerTestCase
class SeleniumTestCaseBase:
browsers: Any = ...
browser: Any = ...
def __new__(
cls: Type[SeleniumTestCaseBase],
name: str,
bases: Tuple[Type[SeleniumTestCase]],
attrs: Dict[str, Union[Callable, List[str], str]],
) -> Type[SeleniumTestCase]: ...
@classmethod
def import_webdriver(cls, browser: Any): ...
def create_webdriver(self): ...
class SeleniumTestCase(LiveServerTestCase):
implicit_wait: int = ...
@classmethod
def setUpClass(cls) -> None: ...
def disable_implicit_wait(self) -> None: ...

View File

@@ -18,14 +18,9 @@ from django.utils.safestring import SafeText
from django.db import connections as connections
class _AssertNumQueriesContext(CaptureQueriesContext):
connection: Any
final_queries: Optional[int]
force_debug_cursor: bool
initial_queries: int
test_case: SimpleTestCase = ...
num: int = ...
def __init__(self, test_case: Any, num: Any, connection: Any) -> None: ...
def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any): ...
class _AssertTemplateUsedContext:
test_case: SimpleTestCase = ...
@@ -40,14 +35,7 @@ class _AssertTemplateUsedContext:
def __enter__(self): ...
def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any): ...
class _AssertTemplateNotUsedContext(_AssertTemplateUsedContext):
context: ContextList
rendered_template_names: List[str]
rendered_templates: List[Template]
template_name: str
test_case: SimpleTestCase
def test(self): ...
def message(self): ...
class _AssertTemplateNotUsedContext(_AssertTemplateUsedContext): ...
class _CursorFailure:
cls_name: str = ...
@@ -59,10 +47,6 @@ class SimpleTestCase(unittest.TestCase):
client_class: Any = ...
client: Client
allow_database_queries: bool = ...
@classmethod
def setUpClass(cls) -> None: ...
@classmethod
def tearDownClass(cls) -> None: ...
def __call__(self, result: unittest.TestResult = ...) -> None: ...
def settings(self, **kwargs: Any) -> Any: ...
def modify_settings(self, **kwargs: Any) -> Any: ...
@@ -150,7 +134,6 @@ class TransactionTestCase(SimpleTestCase):
fixtures: Any = ...
multi_db: bool = ...
serialized_rollback: bool = ...
allow_database_queries: bool = ...
def assertQuerysetEqual(
self,
qs: Union[Iterator[Any], List[Model], QuerySet, RawQuerySet],
@@ -164,10 +147,6 @@ class TransactionTestCase(SimpleTestCase):
) -> Optional[_AssertNumQueriesContext]: ...
class TestCase(TransactionTestCase):
@classmethod
def setUpClass(cls) -> None: ...
@classmethod
def tearDownClass(cls) -> None: ...
@classmethod
def setUpTestData(cls) -> None: ...
@@ -181,17 +160,14 @@ def skipIfDBFeature(*features: Any) -> Callable: ...
def skipUnlessDBFeature(*features: Any) -> Callable: ...
def skipUnlessAnyDBFeature(*features: Any) -> Callable: ...
class QuietWSGIRequestHandler(WSGIRequestHandler):
def log_message(*args: Any) -> None: ...
class QuietWSGIRequestHandler(WSGIRequestHandler): ...
class FSFilesHandler(WSGIHandler):
application: Any = ...
base_url: Any = ...
def __init__(self, application: Any) -> None: ...
def file_path(self, url: Any): ...
def get_response(self, request: Any): ...
def serve(self, request: Any): ...
def __call__(self, environ: Any, start_response: Any): ...
class _StaticFilesHandler(FSFilesHandler):
def get_base_dir(self): ...
@@ -216,7 +192,6 @@ class LiveServerThread(threading.Thread):
port: int = ...,
) -> None: ...
httpd: ThreadedWSGIServer = ...
def run(self) -> None: ...
def terminate(self) -> None: ...
class LiveServerTestCase(TransactionTestCase):
@@ -225,10 +200,6 @@ class LiveServerTestCase(TransactionTestCase):
server_thread_class: Any = ...
static_handler: Any = ...
def live_server_url(cls): ...
@classmethod
def setUpClass(cls) -> None: ...
@classmethod
def tearDownClass(cls) -> None: ...
class SerializeMixin:
lockfile: Any = ...

View File

@@ -66,15 +66,15 @@ class override_system_checks(TestContextDecorator):
class CaptureQueriesContext:
connection: Any = ...
force_debug_cursor: bool = ...
initial_queries: int = ...
final_queries: Optional[int] = ...
def __init__(self, connection: Any) -> None: ...
def __iter__(self): ...
def __getitem__(self, index: int) -> Dict[str, str]: ...
def __len__(self) -> int: ...
@property
def captured_queries(self) -> List[Dict[str, str]]: ...
force_debug_cursor: bool = ...
initial_queries: int = ...
final_queries: Optional[int] = ...
def __enter__(self) -> CaptureQueriesContext: ...
def __exit__(self, exc_type: None, exc_value: None, traceback: None) -> None: ...

View File

@@ -12,8 +12,11 @@ from typing import (
Union,
overload,
Iterator,
Optional,
)
from typing_extensions import Literal
_K = TypeVar("_K")
_V = TypeVar("_V")
@@ -27,24 +30,22 @@ class OrderedSet(MutableSet[_K]):
class MultiValueDictKeyError(KeyError): ...
_Val = Union[_V, List[_V]]
class MultiValueDict(MutableMapping[_K, _V]):
@overload
def __init__(self, key_to_list_mapping: Iterable[Tuple[_K, _Val]] = ...) -> None: ...
def __init__(self, key_to_list_mapping: Mapping[_K, Optional[List[_V]]] = ...) -> None: ...
@overload
def __init__(self, key_to_list_mapping: Mapping[_K, _Val] = ...) -> None: ...
def __init__(self, key_to_list_mapping: Iterable[Tuple[_K, List[_V]]] = ...) -> None: ...
def getlist(self, key: _K, default: List[_V] = None) -> List[_V]: ...
def setlist(self, key: _K, list_: List[_V]) -> None: ...
def setlistdefault(self, key: _K, default_list: List[_V] = None) -> List[_V]: ...
def appendlist(self, key: _K, value: _V) -> None: ...
def lists(self) -> Iterable[Tuple[_K, List[_V]]]: ...
def dict(self) -> Dict[_K, _Val]: ...
def dict(self) -> Dict[_K, Union[_V, List[_V]]]: ...
def copy(self) -> MultiValueDict[_K, _V]: ...
# These overrides are needed to convince mypy that this isn't an abstract class
def __delitem__(self, item: _K) -> None: ...
def __getitem__(self, item: _K) -> _Val: ... # type: ignore
def __setitem__(self, k: _K, v: _Val) -> None: ...
def __getitem__(self, item: _K) -> Union[_V, Literal[[]]]: ... # type: ignore
def __setitem__(self, k: _K, v: Union[_V, List[_V]]) -> None: ...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[_K]: ...

View File

@@ -1,18 +1,10 @@
from typing import Any, Callable, Optional, Set, Tuple, Type, Union
from django.contrib.auth.mixins import AccessMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.middleware.cache import CacheMiddleware
from django.test.testcases import LiveServerTestCase
from django.utils.deprecation import MiddlewareMixin
from django.views.generic.base import TemplateResponseMixin, View
class classonlymethod(classmethod):
def __get__(
self,
instance: Optional[View],
cls: Type[Union[AccessMixin, SuccessMessageMixin, TemplateResponseMixin, View]] = ...,
) -> Callable: ...
class classonlymethod(classmethod): ...
def method_decorator(
decorator: Union[Callable, Set[Callable], Tuple[Callable, Callable]], name: str = ...

View File

@@ -1,144 +1,106 @@
import types
from typing import Any, Optional
from __future__ import print_function
PY2: Any
PY3: Any
PY34: Any
string_types: Any
integer_types: Any
class_types: Any
import types
import typing
import unittest
from typing import (
Any,
AnyStr,
Callable,
Dict,
ItemsView,
Iterable,
KeysView,
Mapping,
NoReturn,
Optional,
Pattern,
Text,
Tuple,
Type,
TypeVar,
Union,
ValuesView,
overload,
)
# Exports
_T = TypeVar("_T")
_K = TypeVar("_K")
_V = TypeVar("_V")
# TODO make constant, then move this stub to 2and3
# https://github.com/python/typeshed/issues/17
PY2 = False
PY3 = True
PY34 = ... # type: bool
string_types = (str,)
integer_types = (int,)
class_types = (type,)
text_type = str
binary_type = bytes
MAXSIZE: Any
text_type = unicode
binary_type = str
class X:
def __len__(self): ...
MAXSIZE = ... # type: int
class _LazyDescr:
name: Any = ...
def __init__(self, name: Any) -> None: ...
def __get__(self, obj: Any, tp: Any): ...
# def add_move
# def remove_move
class MovedModule(_LazyDescr):
mod: Any = ...
def __init__(self, name: Any, old: Any, new: Optional[Any] = ...) -> None: ...
def __getattr__(self, attr: Any): ...
class _LazyModule(types.ModuleType):
__doc__: Any = ...
def __init__(self, name: Any) -> None: ...
def __dir__(self): ...
class MovedAttribute(_LazyDescr):
mod: Any = ...
attr: Any = ...
def __init__(
self, name: Any, old_mod: Any, new_mod: Any, old_attr: Optional[Any] = ..., new_attr: Optional[Any] = ...
) -> None: ...
class _SixMetaPathImporter:
name: Any = ...
known_modules: Any = ...
def __init__(self, six_module_name: Any) -> None: ...
def find_module(self, fullname: Any, path: Optional[Any] = ...): ...
def load_module(self, fullname: Any): ...
def is_package(self, fullname: Any): ...
def get_code(self, fullname: Any): ...
get_source: Any = ...
class _MovedItems(_LazyModule):
__path__: Any = ...
moves: Any
class Module_six_moves_urllib_parse(_LazyModule): ...
class Module_six_moves_urllib_error(_LazyModule): ...
class Module_six_moves_urllib_request(_LazyModule): ...
class Module_six_moves_urllib_response(_LazyModule): ...
class Module_six_moves_urllib_robotparser(_LazyModule): ...
class Module_six_moves_urllib(types.ModuleType):
__path__: Any = ...
parse: Any = ...
error: Any = ...
request: Any = ...
response: Any = ...
robotparser: Any = ...
def __dir__(self): ...
def add_move(move: Any) -> None: ...
def remove_move(name: Any) -> None: ...
advance_iterator = next
next = advance_iterator
callable = callable
def get_unbound_function(unbound: Any): ...
create_bound_method: Any
def create_unbound_method(func: Any, cls: Any): ...
def callable(obj: object) -> bool: ...
def get_unbound_function(unbound: types.FunctionType) -> types.FunctionType: ...
def create_bound_method(func: types.FunctionType, obj: object) -> types.MethodType: ...
def create_unbound_method(func: types.FunctionType, cls: type) -> types.FunctionType: ...
Iterator = object
class Iterator:
def next(self): ...
def get_method_function(meth: types.MethodType) -> types.FunctionType: ...
def get_method_self(meth: types.MethodType) -> Optional[object]: ...
def get_function_closure(fun: types.FunctionType) -> Optional[Tuple[types._Cell, ...]]: ...
def get_function_code(fun: types.FunctionType) -> types.CodeType: ...
def get_function_defaults(fun: types.FunctionType) -> Optional[Tuple[Any, ...]]: ...
def get_function_globals(fun: types.FunctionType) -> Dict[str, Any]: ...
def iterkeys(d: Mapping[_K, _V]) -> typing.Iterator[_K]: ...
def itervalues(d: Mapping[_K, _V]) -> typing.Iterator[_V]: ...
def iteritems(d: Mapping[_K, _V]) -> typing.Iterator[Tuple[_K, _V]]: ...
callable = callable
get_method_function: Any
get_method_self: Any
get_function_closure: Any
get_function_code: Any
get_function_defaults: Any
get_function_globals: Any
# def iterlists
def iterkeys(d: Any, **kw: Any): ...
def itervalues(d: Any, **kw: Any): ...
def iteritems(d: Any, **kw: Any): ...
def iterlists(d: Any, **kw: Any): ...
viewkeys: Any
viewvalues: Any
viewitems: Any
def b(s: Any): ...
def u(s: Any): ...
def viewkeys(d: Mapping[_K, _V]) -> KeysView[_K]: ...
def viewvalues(d: Mapping[_K, _V]) -> ValuesView[_V]: ...
def viewitems(d: Mapping[_K, _V]) -> ItemsView[_K, _V]: ...
def b(s: str) -> binary_type: ...
def u(s: str) -> text_type: ...
unichr = chr
int2byte: Any
byte2int: Any
indexbytes: Any
iterbytes = iter
StringIO: Any
BytesIO: Any
unichr = unichr
int2byte = chr
def assertCountEqual(self, *args: Any, **kwargs: Any): ...
def assertRaisesRegex(self, *args: Any, **kwargs: Any): ...
def assertRegex(self, *args: Any, **kwargs: Any): ...
def int2byte(i: int) -> bytes: ...
def byte2int(bs: binary_type) -> int: ...
def indexbytes(buf: binary_type, i: int) -> int: ...
def iterbytes(buf: binary_type) -> typing.Iterator[int]: ...
def assertCountEqual(
self: unittest.TestCase, first: Iterable[_T], second: Iterable[_T], msg: Optional[str] = ...
) -> None: ...
@overload
def assertRaisesRegex(self: unittest.TestCase, msg: Optional[str] = ...) -> Any: ...
@overload
def assertRaisesRegex(self: unittest.TestCase, callable_obj: Callable[..., Any], *args: Any, **kwargs: Any) -> Any: ...
def assertRegex(
self: unittest.TestCase, text: AnyStr, expected_regex: Union[AnyStr, Pattern[AnyStr]], msg: Optional[str] = ...
) -> None: ...
exec_: Any
exec_ = exec
def reraise(tp: Any, value: Any, tb: Optional[Any] = ...) -> None: ...
def raise_from(value: Any, from_value: Any) -> None: ...
def reraise(
tp: Optional[Type[BaseException]], value: Optional[BaseException], tb: Optional[types.TracebackType] = ...
) -> NoReturn: ...
def raise_from(value: Union[BaseException, Type[BaseException]], from_value: Optional[BaseException]) -> NoReturn: ...
print_: Any
_print = print_
print_ = print
def wraps(wrapped: Any, assigned: Any = ..., updated: Any = ...): ...
wraps: Any
def with_metaclass(meta: Any, *bases: Any): ...
def add_metaclass(metaclass: Any): ...
def python_2_unicode_compatible(klass: Any): ...
__path__: Any
__package__ = __name__
memoryview = memoryview
buffer_types: Any
memoryview = memoryview
memoryview = buffer
def with_metaclass(meta: type, *bases: type) -> type: ...
def add_metaclass(metaclass: type) -> Callable[[_T], _T]: ...
def ensure_binary(s: Union[bytes, Text], encoding: str = ..., errors: str = ...) -> bytes: ...
def ensure_str(s: Union[bytes, Text], encoding: str = ..., errors: str = ...) -> str: ...
def ensure_text(s: Union[bytes, Text], encoding: str = ..., errors: str = ...) -> Text: ...
def python_2_unicode_compatible(klass: _T) -> _T: ...

View File

@@ -1,3 +0,0 @@
from django.views.generic.base import View
__all__ = ["View"]

View File

@@ -0,0 +1 @@
from .generic.base import View as View

View File

@@ -1,5 +1,3 @@
from typing import Any, Optional
from django.http.request import HttpRequest
from django.http.response import HttpResponseForbidden

View File

@@ -34,9 +34,9 @@ class SafeExceptionReporterFilter(ExceptionReporterFilter):
class ExceptionReporter:
request: Optional[HttpRequest] = ...
filter: ExceptionReporterFilter = ...
exc_type: None = ...
exc_type: Optional[Type[BaseException]] = ...
exc_value: Optional[str] = ...
tb: None = ...
tb: Optional[TracebackType] = ...
is_email: bool = ...
template_info: None = ...
template_does_not_exist: bool = ...
@@ -59,7 +59,7 @@ class ExceptionReporter:
lineno: int,
context_lines: int,
loader: Optional[SourceLoader] = ...,
module_name: Optional[str] = None,
module_name: Optional[str] = ...,
): ...
def technical_404_response(request: HttpRequest, exception: Http404) -> HttpResponse: ...

View File

@@ -1,4 +1,4 @@
from typing import Any, Callable, Optional
from typing import Callable
def xframe_options_deny(view_func: Callable) -> Callable: ...
def xframe_options_sameorigin(view_func: Callable) -> Callable: ...

View File

@@ -1,4 +1,4 @@
from typing import Any, Callable, Optional
from typing import Any, Callable
from django.middleware.csrf import CsrfViewMiddleware

View File

@@ -1,4 +1,4 @@
from typing import Any, Callable, Optional
from typing import Any, Callable
def sensitive_variables(*variables: Any) -> Callable: ...
def sensitive_post_parameters(*parameters: Any) -> Callable: ...

View File

@@ -0,0 +1,5 @@
from typing import Callable, TypeVar
_C = TypeVar("_C", bound=Callable)
def gzip_page(view_func: _C) -> _C: ...

View File

@@ -1,4 +1,4 @@
from typing import Any, Callable, Optional
from typing import Any, Callable
def vary_on_headers(*headers: Any) -> Callable: ...
def vary_on_cookie(func: Callable) -> Callable: ...

View File

@@ -1,8 +1,7 @@
from typing import Any, Optional
from typing import Optional
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import (
Http404,
HttpResponseBadRequest,
HttpResponseForbidden,
HttpResponseNotFound,
@@ -15,10 +14,10 @@ ERROR_400_TEMPLATE_NAME: str
ERROR_500_TEMPLATE_NAME: str
def page_not_found(
request: WSGIRequest, exception: Optional[Http404], template_name: str = ...
request: HttpRequest, exception: Optional[Exception], template_name: str = ...
) -> HttpResponseNotFound: ...
def server_error(request: WSGIRequest, template_name: str = ...) -> HttpResponseServerError: ...
def bad_request(request: WSGIRequest, exception: Exception, template_name: str = ...) -> HttpResponseBadRequest: ...
def server_error(request: HttpRequest, template_name: str = ...) -> HttpResponseServerError: ...
def bad_request(request: HttpRequest, exception: Exception, template_name: str = ...) -> HttpResponseBadRequest: ...
def permission_denied(
request: WSGIRequest, exception: Exception, template_name: str = ...
request: HttpRequest, exception: Exception, template_name: str = ...
) -> HttpResponseForbidden: ...

View File

@@ -1,5 +1,5 @@
from django.views.generic.base import RedirectView as RedirectView, TemplateView as TemplateView, View as View
from django.views.generic.dates import (
from .base import RedirectView as RedirectView, TemplateView as TemplateView, View as View
from .dates import (
ArchiveIndexView as ArchiveIndexView,
DateDetailView as DateDetailView,
DayArchiveView as DayArchiveView,
@@ -8,13 +8,8 @@ from django.views.generic.dates import (
WeekArchiveView as WeekArchiveView,
YearArchiveView as YearArchiveView,
)
from django.views.generic.detail import DetailView as DetailView
from django.views.generic.edit import (
CreateView as CreateView,
DeleteView as DeleteView,
FormView as FormView,
UpdateView as UpdateView,
)
from django.views.generic.list import ListView as ListView
from .detail import DetailView as DetailView
from .edit import CreateView as CreateView, DeleteView as DeleteView, FormView as FormView, UpdateView as UpdateView
from .list import ListView as ListView
class GenericViewError(Exception): ...

View File

@@ -1,48 +1,43 @@
from typing import Any, Callable, Dict, List, Optional, Tuple, Type
from typing import Any, Callable, Dict, List, Optional, Type
from django import http
logger = ... # type: Any
class ContextMixin:
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ...
class View:
http_method_names = ... # type: List[str]
request = ... # type: http.HttpRequest
args = ... # type: Tuple[object, ...]
kwargs = ... # type: Dict[str, object]
def __init__(self, **kwargs: object) -> None: ...
http_method_names: List[str] = ...
request: http.HttpRequest = ...
args: Any = ...
kwargs: Any = ...
def __init__(self, **kwargs: Any) -> None: ...
@classmethod
def as_view(cls: Any, **initkwargs: object) -> Callable[..., http.HttpResponse]: ...
def dispatch(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def http_method_not_allowed(
self, request: http.HttpRequest, *args: object, **kwargs: object
) -> http.HttpResponse: ...
def options(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def as_view(cls: Any, **initkwargs: Any) -> Callable[..., http.HttpResponse]: ...
def dispatch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
def http_method_not_allowed(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
def options(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
class TemplateResponseMixin:
template_name = ... # type: str
template_engine = ... # type: Optional[str]
response_class = ... # type: Type[http.HttpResponse]
content_type = ... # type: Optional[str]
request = ... # type: http.HttpRequest
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> http.HttpResponse: ...
template_name: str = ...
template_engine: Optional[str] = ...
response_class: Type[http.HttpResponse] = ...
content_type: Optional[str] = ...
request: http.HttpRequest = ...
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> http.HttpResponse: ...
def get_template_names(self) -> List[str]: ...
class TemplateView(TemplateResponseMixin, ContextMixin, View):
def get(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def get(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
class RedirectView(View):
permanent = ... # type: bool
url = ... # type: Optional[str]
pattern_name = ... # type: Optional[str]
query_string = ... # type: bool
def get_redirect_url(self, *args: object, **kwargs: object) -> Optional[str]: ...
def get(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def head(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def post(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def options(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def delete(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def put(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
def patch(self, request: http.HttpRequest, *args: object, **kwargs: object) -> http.HttpResponse: ...
permanent: bool = ...
url: Optional[str] = ...
pattern_name: Optional[str] = ...
query_string: bool = ...
def get_redirect_url(self, *args: Any, **kwargs: Any) -> Optional[str]: ...
def get(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
def head(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
def post(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
def delete(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
def put(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...
def patch(self, request: http.HttpRequest, *args: Any, **kwargs: Any) -> http.HttpResponse: ...

View File

@@ -8,49 +8,49 @@ from django.views.generic.detail import BaseDetailView, SingleObjectTemplateResp
from django.views.generic.list import MultipleObjectMixin, MultipleObjectTemplateResponseMixin
class YearMixin:
year_format = ... # type: str
year = ... # type: Optional[str]
kwargs = ... # type: Dict[str, object]
request = ... # type: HttpRequest
year_format: str = ...
year: Optional[str] = ...
kwargs: Dict[str, Any] = ...
request: HttpRequest = ...
def get_year_format(self) -> str: ...
def get_year(self) -> str: ...
def get_next_year(self, date: datetime.date) -> Optional[datetime.date]: ...
def get_previous_year(self, date: datetime.date) -> Optional[datetime.date]: ...
class MonthMixin:
month_format = ... # type: str
month = ... # type: Optional[str]
request = ... # type: HttpRequest
kwargs = ... # type: Dict[str, object]
month_format: str = ...
month: Optional[str] = ...
request: HttpRequest = ...
kwargs: Dict[str, Any] = ...
def get_month_format(self) -> str: ...
def get_month(self) -> str: ...
def get_next_month(self, date: datetime.date) -> Optional[datetime.date]: ...
def get_previous_month(self, date: datetime.date) -> Optional[datetime.date]: ...
class DayMixin:
day_format = ... # type: str
day = ... # type: Optional[str]
request = ... # type: HttpRequest
kwargs = ... # type: Dict[str, object]
day_format: str = ...
day: Optional[str] = ...
request: HttpRequest = ...
kwargs: Dict[str, Any] = ...
def get_day_format(self) -> str: ...
def get_day(self) -> str: ...
def get_next_day(self, date: datetime.date) -> Optional[datetime.date]: ...
def get_previous_day(self, date: datetime.date) -> Optional[datetime.date]: ...
class WeekMixin:
week_format = ... # type: str
week = ... # type: Optional[str]
request = ... # type: HttpRequest
kwargs = ... # type: Dict[str, object]
week_format: str = ...
week: Optional[str] = ...
request: HttpRequest = ...
kwargs: Dict[str, Any] = ...
def get_week_format(self) -> str: ...
def get_week(self) -> str: ...
def get_next_week(self, date: datetime.date) -> Optional[datetime.date]: ...
def get_previous_week(self, date: datetime.date) -> Optional[datetime.date]: ...
class DateMixin:
date_field = ... # type: Optional[str]
allow_future = ... # type: bool
model = ... # type: Optional[Type[models.Model]]
date_field: Optional[str] = ...
allow_future: bool = ...
model: Optional[Type[models.Model]] = ...
def get_date_field(self) -> str: ...
def get_allow_future(self) -> bool: ...
def uses_datetime_field(self) -> bool: ...
@@ -58,63 +58,33 @@ class DateMixin:
DatedItems = Tuple[Optional[Sequence[datetime.date]], Sequence[object], Dict[str, Any]]
class BaseDateListView(MultipleObjectMixin, DateMixin, View):
allow_empty = ... # type: bool
date_list_period = ... # type: str
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> HttpResponse: ...
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
date_list_period: str = ...
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> HttpResponse: ...
def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
def get_dated_items(self) -> DatedItems: ...
def get_ordering(self) -> Sequence[str]: ...
def get_dated_queryset(self, **lookup: object) -> models.query.QuerySet: ...
def get_dated_queryset(self, **lookup: Any) -> models.query.QuerySet: ...
def get_date_list_period(self) -> str: ...
def get_date_list(
self, queryset: models.query.QuerySet, date_type: str = None, ordering: str = ...
self, queryset: models.query.QuerySet, date_type: Optional[str] = ..., ordering: str = ...
) -> models.query.QuerySet: ...
class BaseArchiveIndexView(BaseDateListView):
context_object_name = ... # type: str
def get_dated_items(self) -> DatedItems: ...
class ArchiveIndexView(MultipleObjectTemplateResponseMixin, BaseArchiveIndexView):
template_name_suffix = ... # type: str
class BaseArchiveIndexView(BaseDateListView): ...
class ArchiveIndexView(MultipleObjectTemplateResponseMixin, BaseArchiveIndexView): ...
class BaseYearArchiveView(YearMixin, BaseDateListView):
date_list_period = ... # type: str
make_object_list = ... # type: bool
def get_dated_items(self) -> DatedItems: ...
make_object_list: bool = ...
def get_make_object_list(self) -> bool: ...
class YearArchiveView(MultipleObjectTemplateResponseMixin, BaseYearArchiveView):
template_name_suffix = ... # type: str
class BaseMonthArchiveView(YearMixin, MonthMixin, BaseDateListView):
date_list_period = ... # type: str
def get_dated_items(self) -> DatedItems: ...
class MonthArchiveView(MultipleObjectTemplateResponseMixin, BaseMonthArchiveView):
template_name_suffix = ... # type: str
class BaseWeekArchiveView(YearMixin, WeekMixin, BaseDateListView):
def get_dated_items(self) -> DatedItems: ...
class WeekArchiveView(MultipleObjectTemplateResponseMixin, BaseWeekArchiveView):
template_name_suffix = ... # type: str
class BaseDayArchiveView(YearMixin, MonthMixin, DayMixin, BaseDateListView):
def get_dated_items(self) -> DatedItems: ...
class DayArchiveView(MultipleObjectTemplateResponseMixin, BaseDayArchiveView):
template_name_suffix = ... # type: str
class BaseTodayArchiveView(BaseDayArchiveView):
def get_dated_items(self) -> DatedItems: ...
class TodayArchiveView(MultipleObjectTemplateResponseMixin, BaseTodayArchiveView):
template_name_suffix = ... # type: str
class BaseDateDetailView(YearMixin, MonthMixin, DayMixin, DateMixin, BaseDetailView):
def get_object(self, queryset: models.query.QuerySet = None) -> models.Model: ...
class DateDetailView(SingleObjectTemplateResponseMixin, BaseDateDetailView):
template_name_suffix = ... # type: str
class YearArchiveView(MultipleObjectTemplateResponseMixin, BaseYearArchiveView): ...
class BaseMonthArchiveView(YearMixin, MonthMixin, BaseDateListView): ...
class MonthArchiveView(MultipleObjectTemplateResponseMixin, BaseMonthArchiveView): ...
class BaseWeekArchiveView(YearMixin, WeekMixin, BaseDateListView): ...
class WeekArchiveView(MultipleObjectTemplateResponseMixin, BaseWeekArchiveView): ...
class BaseDayArchiveView(YearMixin, MonthMixin, DayMixin, BaseDateListView): ...
class DayArchiveView(MultipleObjectTemplateResponseMixin, BaseDayArchiveView): ...
class BaseTodayArchiveView(BaseDayArchiveView): ...
class TodayArchiveView(MultipleObjectTemplateResponseMixin, BaseTodayArchiveView): ...
class BaseDateDetailView(YearMixin, MonthMixin, DayMixin, DateMixin, BaseDetailView): ...
class DateDetailView(SingleObjectTemplateResponseMixin, BaseDateDetailView): ...
def timezone_today() -> datetime.date: ...

View File

@@ -1,35 +1,33 @@
from typing import Any, Dict, List, Optional, Type
from typing import Any, Dict, Optional, Type
from django.db import models
from django.http import HttpResponse, HttpRequest
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from django.db import models
from django.http import HttpRequest, HttpResponse
class SingleObjectMixin(ContextMixin):
model = ... # type: Optional[Type[models.Model]]
queryset = ... # type: Optional[models.query.QuerySet]
slug_field = ... # type: str
context_object_name = ... # type: Optional[str]
slug_url_kwarg = ... # type: str
pk_url_kwarg = ... # type: str
query_pk_and_slug = ... # type: bool
object = ... # type: models.Model
kwargs = ... # type: Dict[str, object]
def get_object(self, queryset: models.query.QuerySet = None) -> models.Model: ...
model: Optional[Type[models.Model]] = ...
queryset: Optional[models.query.QuerySet] = ...
slug_field: str = ...
context_object_name: Optional[str] = ...
slug_url_kwarg: str = ...
pk_url_kwarg: str = ...
query_pk_and_slug: bool = ...
object: models.Model = ...
kwargs: Dict[str, Any] = ...
def get_object(self, queryset: Optional[models.query.QuerySet] = ...) -> models.Model: ...
def get_queryset(self) -> models.query.QuerySet: ...
def get_slug_field(self) -> str: ...
def get_context_object_name(self, obj: Any) -> Optional[str]: ...
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
class BaseDetailView(SingleObjectMixin, View):
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> HttpResponse: ...
object = ... # type: models.Model
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> HttpResponse: ...
def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
class SingleObjectTemplateResponseMixin(TemplateResponseMixin):
template_name_field = ... # type: Optional[str]
template_name_suffix = ... # type: str
model = ... # type: Optional[Type[models.Model]]
object = ... # type: models.Model
def get_template_names(self) -> List[str]: ...
template_name_field: Optional[str] = ...
template_name_suffix: str = ...
model: Optional[Type[models.Model]] = ...
object: models.Model = ...
class DetailView(SingleObjectTemplateResponseMixin, BaseDetailView): ...

View File

@@ -1,77 +1,53 @@
from typing import Any, Callable, Dict, Optional, Sequence, Type, Union
from django.db import models
from django.forms.forms import BaseForm
from django.http import HttpRequest, HttpResponse
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from django.views.generic.detail import BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin
from typing_extensions import Literal
from django.db import models
from django.forms import Form
from django.http import HttpRequest, HttpResponse
class FormMixin(ContextMixin):
initial: Dict[str, Any] = ...
form_class: Optional[Type[Form]] = ...
form_class: Optional[Type[BaseForm]] = ...
success_url: Optional[Union[str, Callable[..., Any]]] = ...
prefix: Optional[str] = ...
request: HttpRequest = ...
def render_to_response(self, context: Dict[str, Any], **response_kwargs: object) -> HttpResponse: ...
def get_initial(self) -> Dict[str, Any]: ...
def get_prefix(self) -> Optional[str]: ...
def get_form_class(self) -> Type[Form]: ...
def get_form(self, form_class: Type[Form] = None) -> Form: ...
def get_form_class(self) -> Type[BaseForm]: ...
def get_form(self, form_class: Optional[Type[BaseForm]] = None) -> BaseForm: ...
def get_form_kwargs(self) -> Dict[str, Any]: ...
def get_success_url(self) -> str: ...
def form_valid(self, form: Form) -> HttpResponse: ...
def form_invalid(self, form: Form) -> HttpResponse: ...
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
def form_valid(self, form: BaseForm) -> HttpResponse: ...
def form_invalid(self, form: BaseForm) -> HttpResponse: ...
class ModelFormMixin(FormMixin, SingleObjectMixin):
fields: Optional[Union[Sequence[str], Literal["__all__"]]] = ...
object: models.Model = ...
def get_form_class(self) -> Type[Form]: ...
def get_form_kwargs(self) -> Dict[str, object]: ...
def get_success_url(self) -> str: ...
def form_valid(self, form: Form) -> HttpResponse: ...
class ProcessFormView(View):
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> HttpResponse: ...
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
def get_form(self, form_class: Type[Form] = None) -> Form: ...
def form_valid(self, form: Form) -> HttpResponse: ...
def form_invalid(self, form: Form) -> HttpResponse: ...
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
def post(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
def put(self, *args: Any, **kwargs: Any) -> HttpResponse: ...
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> HttpResponse: ...
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ...
def get(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
def put(self, *args: str, **kwargs: Any) -> HttpResponse: ...
class BaseFormView(FormMixin, ProcessFormView): ...
class FormView(TemplateResponseMixin, BaseFormView): ...
class BaseCreateView(ModelFormMixin, ProcessFormView):
object = ... # type: models.Model
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
def post(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
template_name_suffix = ... # type: str
class BaseUpdateView(ModelFormMixin, ProcessFormView):
object = ... # type: models.Model
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
def post(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView):
template_name_suffix = ... # type: str
class BaseCreateView(ModelFormMixin, ProcessFormView): ...
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): ...
class BaseUpdateView(ModelFormMixin, ProcessFormView): ...
class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView): ...
_object = object
class DeletionMixin:
success_url = ... # type: Optional[str]
object = ... # type: models.Model
def delete(self, request: HttpRequest, *args: _object, **kwargs: _object) -> HttpResponse: ...
def post(self, request: HttpRequest, *args: _object, **kwargs: _object) -> HttpResponse: ...
success_url: Optional[str] = ...
object: models.Model = ...
def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
def delete(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
def get_success_url(self) -> str: ...
class BaseDeleteView(DeletionMixin, BaseDetailView): ...
class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView):
template_name_suffix = ... # type: str
class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView): ...

View File

@@ -1,24 +1,25 @@
from typing import Any, Dict, List, Optional, Sequence, Tuple, Type
from typing import Any, Dict, Optional, Sequence, Tuple, Type
from django.db.models import Model
from django.core.paginator import Paginator
from django.db.models.query import QuerySet
from django.core.paginator import Paginator # type: ignore # This will be fixed when adding the paginator module
from django.http import HttpRequest, HttpResponse
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from django.db.models import Model
from django.http import HttpRequest, HttpResponse
class MultipleObjectMixin(ContextMixin):
allow_empty = ... # type: bool
queryset = ... # type: Optional[QuerySet]
model = ... # type: Optional[Type[Model]]
paginate_by = ... # type: Optional[int]
paginate_orphans = ... # type: int
context_object_name = ... # type: Optional[str]
paginator_class = ... # type: Type[Paginator]
page_kwarg = ... # type: str
ordering = ... # type: Sequence[str]
request = ... # type: HttpRequest
kwargs = ... # type: Dict[str, object]
object_list = ... # type: QuerySet
allow_empty: bool = ...
queryset: Optional[QuerySet] = ...
model: Optional[Type[Model]] = ...
paginate_by: Optional[int] = ...
paginate_orphans: int = ...
context_object_name: Optional[str] = ...
paginator_class: Type[Paginator] = ...
page_kwarg: str = ...
ordering: Sequence[str] = ...
request: HttpRequest = ...
kwargs: Dict[str, Any] = ...
object_list: QuerySet = ...
def get_queryset(self) -> QuerySet: ...
def get_ordering(self) -> Sequence[str]: ...
def paginate_queryset(self, queryset: QuerySet, page_size: int) -> Tuple[Paginator, int, QuerySet, bool]: ...
@@ -29,16 +30,13 @@ class MultipleObjectMixin(ContextMixin):
def get_paginate_orphans(self) -> int: ...
def get_allow_empty(self) -> bool: ...
def get_context_object_name(self, object_list: QuerySet) -> Optional[str]: ...
def get_context_data(self, **kwargs: object) -> Dict[str, Any]: ...
class BaseListView(MultipleObjectMixin, View):
object_list = ... # type: QuerySet
def render_to_response(self, context: Dict[str, object], **response_kwargs: object) -> HttpResponse: ...
def get(self, request: HttpRequest, *args: object, **kwargs: object) -> HttpResponse: ...
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> HttpResponse: ...
def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
class MultipleObjectTemplateResponseMixin(TemplateResponseMixin):
template_name_suffix = ... # type: str
object_list = ... # type: QuerySet
def get_template_names(self) -> List[str]: ...
template_name_suffix: str = ...
object_list: QuerySet = ...
class ListView(MultipleObjectTemplateResponseMixin, BaseListView): ...

View File

@@ -1,12 +1,14 @@
from typing import Any, Dict, List, Optional, Union
from typing import Any, Callable, Dict, List, Optional, Union
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.utils.translation.trans_real import DjangoTranslation
from django.views.generic import View
LANGUAGE_QUERY_PARAMETER: str
def set_language(request: WSGIRequest) -> HttpResponse: ...
def set_language(request: HttpRequest) -> HttpResponse: ...
def get_formats() -> Dict[str, Union[List[str], int, str]]: ...
js_catalog_template: str
@@ -15,21 +17,15 @@ def render_javascript_catalog(catalog: Optional[Any] = ..., plural: Optional[Any
def null_javascript_catalog(request: Any, domain: Optional[Any] = ..., packages: Optional[Any] = ...): ...
class JavaScriptCatalog(View):
args: Tuple
head: Callable
kwargs: Dict[Any, Any]
request: WSGIRequest
domain: str = ...
packages: List[str] = ...
translation: django.utils.translation.trans_real.DjangoTranslation = ...
def get(self, request: WSGIRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
translation: DjangoTranslation = ...
def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
def get_paths(self, packages: List[str]) -> List[str]: ...
def get_plural(self) -> None: ...
def get_catalog(self) -> Dict[str, Union[List[str], str]]: ...
def get_context_data(self, **kwargs: Any) -> Dict[str, Optional[Dict[str, Union[List[str], int, str]]]]: ...
def render_to_response(
self, context: Dict[str, Optional[Dict[str, Union[List[str], int, str]]]], **response_kwargs: Any
) -> HttpResponse: ...
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ...
def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> HttpResponse: ...
class JSONCatalog(JavaScriptCatalog):
def render_to_response(self, context: Any, **response_kwargs: Any): ...
class JSONCatalog(JavaScriptCatalog): ...

View File

@@ -1,9 +1,9 @@
from typing import Any, Optional
from django.core.handlers.wsgi import WSGIRequest
from django.http.request import HttpRequest
from django.http.response import FileResponse
def serve(request: WSGIRequest, path: str, document_root: str = ..., show_indexes: bool = ...) -> FileResponse: ...
def serve(request: HttpRequest, path: str, document_root: str = ..., show_indexes: bool = ...) -> FileResponse: ...
DEFAULT_DIRECTORY_INDEX_TEMPLATE: str
template_translatable: Any

View File

@@ -1,5 +1,5 @@
from configparser import ConfigParser
from typing import List, Optional
from typing import Optional
from dataclasses import dataclass
@@ -20,6 +20,7 @@ class Config:
fallback=None)
if django_settings:
django_settings = django_settings.strip()
return Config(django_settings_module=django_settings,
ignore_missing_settings=ini_config.get('mypy_django_plugin', 'ignore_missing_settings',
fallback=False))
ignore_missing_settings=bool(ini_config.get('mypy_django_plugin', 'ignore_missing_settings',
fallback=False)))

View File

@@ -2,10 +2,13 @@ import typing
from typing import Dict, Optional
from mypy.checker import TypeChecker
from mypy.nodes import AssignmentStmt, ClassDef, Expression, ImportedName, Lvalue, MypyFile, NameExpr, SymbolNode, \
TypeInfo
from mypy.plugin import FunctionContext
from mypy.types import AnyType, Instance, NoneTyp, Type, TypeOfAny, TypeVarType, UnionType
from mypy.nodes import (
AssignmentStmt, ClassDef, Expression, ImportedName, Lvalue, MypyFile, NameExpr, SymbolNode, TypeInfo,
)
from mypy.plugin import FunctionContext, MethodContext
from mypy.types import (
AnyType, Instance, NoneTyp, Type, TypeOfAny, TypeVarType, UnionType,
)
MODEL_CLASS_FULLNAME = 'django.db.models.base.Model'
FIELD_FULLNAME = 'django.db.models.fields.Field'
@@ -23,6 +26,12 @@ BASE_MANAGER_CLASS_FULLNAME = 'django.db.models.manager.BaseManager'
MANAGER_CLASS_FULLNAME = 'django.db.models.manager.Manager'
RELATED_MANAGER_CLASS_FULLNAME = 'django.db.models.manager.RelatedManager'
BASEFORM_CLASS_FULLNAME = 'django.forms.forms.BaseForm'
FORM_CLASS_FULLNAME = 'django.forms.forms.Form'
MODELFORM_CLASS_FULLNAME = 'django.forms.models.ModelForm'
FORM_MIXIN_CLASS_FULLNAME = 'django.views.generic.edit.FormMixin'
MANAGER_CLASSES = {
MANAGER_CLASS_FULLNAME,
RELATED_MANAGER_CLASS_FULLNAME,
@@ -54,9 +63,9 @@ def get_model_fullname(app_name: str, model_name: str,
return None
class InvalidModelString(ValueError):
def __init__(self, model_string: str):
self.model_string = model_string
class SameFileModel(Exception):
def __init__(self, model_cls_name: str):
self.model_cls_name = model_cls_name
class SelfReference(ValueError):
@@ -69,7 +78,7 @@ def get_model_fullname_from_string(model_string: str,
raise SelfReference()
if '.' not in model_string:
raise InvalidModelString(model_string)
raise SameFileModel(model_string)
app_name, model_name = model_string.split('.')
return get_model_fullname(app_name, model_name, all_modules)
@@ -124,7 +133,7 @@ def fill_typevars(tp: Instance, type_to_fill: Instance) -> Instance:
return Instance(type_to_fill.type, typevar_values)
def get_argument_by_name(ctx: FunctionContext, name: str) -> Optional[Expression]:
def get_argument_by_name(ctx: typing.Union[FunctionContext, MethodContext], name: str) -> Optional[Expression]:
"""Return the expression for the specific argument.
This helper should only be used with non-star arguments.
@@ -139,7 +148,7 @@ def get_argument_by_name(ctx: FunctionContext, name: str) -> Optional[Expression
return args[0]
def get_argument_type_by_name(ctx: FunctionContext, name: str) -> Optional[Type]:
def get_argument_type_by_name(ctx: typing.Union[FunctionContext, MethodContext], name: str) -> Optional[Type]:
"""Return the type for the specific argument.
This helper should only be used with non-star arguments.
@@ -176,8 +185,8 @@ def get_setting_expr(api: TypeChecker, setting_name: str) -> Optional[Expression
return None
def iter_over_assignments(
class_or_module: typing.Union[ClassDef, MypyFile]) -> typing.Iterator[typing.Tuple[Lvalue, Expression]]:
def iter_over_assignments(class_or_module: typing.Union[ClassDef, MypyFile]
) -> typing.Iterator[typing.Tuple[Lvalue, Expression]]:
if isinstance(class_or_module, ClassDef):
statements = class_or_module.defs.body
else:
@@ -246,7 +255,7 @@ def extract_primary_key_type_for_get(model: TypeInfo) -> Optional[Type]:
def make_optional(typ: Type):
return UnionType.make_simplified_union([typ, NoneTyp()])
return UnionType.make_union([typ, NoneTyp()])
def make_required(typ: Type) -> Type:
@@ -273,3 +282,17 @@ def has_any_of_bases(info: TypeInfo, bases: typing.Sequence[str]) -> bool:
def is_none_expr(expr: Expression) -> bool:
return isinstance(expr, NameExpr) and expr.fullname == 'builtins.None'
def get_nested_meta_node_for_current_class(info: TypeInfo) -> Optional[TypeInfo]:
metaclass_sym = info.names.get('Meta')
if metaclass_sym is not None and isinstance(metaclass_sym.node, TypeInfo):
return metaclass_sym.node
return None
def get_assigned_value_for_class(type_info: TypeInfo, name: str) -> Optional[Expression]:
for lvalue, rvalue in iter_over_assignments(type_info.defn):
if isinstance(lvalue, NameExpr) and lvalue.name == name:
return rvalue
return None

View File

@@ -1,18 +1,31 @@
from functools import partial
import os
from typing import Callable, Dict, Optional, Union, cast
from mypy.checker import TypeChecker
from mypy.nodes import MemberExpr, TypeInfo
from mypy.nodes import MemberExpr, NameExpr, TypeInfo
from mypy.options import Options
from mypy.plugin import AttributeContext, ClassDefContext, FunctionContext, MethodContext, Plugin
from mypy.types import AnyType, Instance, Type, TypeOfAny, TypeType, UnionType
from mypy.plugin import (
AttributeContext, ClassDefContext, FunctionContext, MethodContext, Plugin,
AnalyzeTypeContext)
from mypy.types import (
AnyType, CallableType, Instance, NoneTyp, Type, TypeOfAny, TypeType, UnionType,
)
from mypy_django_plugin import helpers, monkeypatch
from mypy_django_plugin.config import Config
from mypy_django_plugin.transformers import fields, init_create
from mypy_django_plugin.transformers.migrations import determine_model_cls_from_string_for_migrations, \
get_string_value_from_expr
from mypy_django_plugin.transformers.forms import (
make_meta_nested_class_inherit_from_any,
)
from mypy_django_plugin.transformers.migrations import (
determine_model_cls_from_string_for_migrations, get_string_value_from_expr,
)
from mypy_django_plugin.transformers.models import process_model_class
from mypy_django_plugin.transformers.settings import AddSettingValuesToDjangoConfObject, get_settings_metadata
from mypy_django_plugin.transformers.settings import (
AddSettingValuesToDjangoConfObject, get_settings_metadata,
)
def transform_model_class(ctx: ClassDefContext) -> None:
@@ -33,6 +46,14 @@ def transform_manager_class(ctx: ClassDefContext) -> None:
sym.node.metadata['django']['manager_bases'][ctx.cls.fullname] = 1
def transform_form_class(ctx: ClassDefContext) -> None:
sym = ctx.api.lookup_fully_qualified_or_none(helpers.BASEFORM_CLASS_FULLNAME)
if sym is not None and isinstance(sym.node, TypeInfo):
sym.node.metadata['django']['baseform_bases'][ctx.cls.fullname] = 1
make_meta_nested_class_inherit_from_any(ctx)
def determine_proper_manager_type(ctx: FunctionContext) -> Type:
api = cast(TypeChecker, ctx.api)
ret = ctx.default_return_type
@@ -45,13 +66,32 @@ def determine_proper_manager_type(ctx: FunctionContext) -> Type:
if not isinstance(ret, Instance):
return ret
has_manager_base = False
for i, base in enumerate(ret.type.bases):
if base.type.fullname() in {helpers.MANAGER_CLASS_FULLNAME,
helpers.RELATED_MANAGER_CLASS_FULLNAME,
helpers.BASE_MANAGER_CLASS_FULLNAME}:
ret.type.bases[i] = Instance(base.type, [Instance(outer_model_info, [])])
return ret
return ret
has_manager_base = True
break
if has_manager_base:
# Fill in the manager's type argument from the outer model
new_type_args = [Instance(outer_model_info, [])]
return helpers.reparametrize_instance(ret, new_type_args)
else:
return ret
def set_first_generic_param_as_default_for_second(fullname: str, ctx: AnalyzeTypeContext) -> Type:
if not ctx.type.args:
return ctx.api.named_type(fullname, [AnyType(TypeOfAny.explicit),
AnyType(TypeOfAny.explicit)])
args = ctx.type.args
if len(args) == 1:
args = [args[0], args[0]]
analyzed_args = [ctx.api.analyze_type(arg) for arg in args]
return ctx.api.named_type(fullname, analyzed_args)
def return_user_model_hook(ctx: FunctionContext) -> Type:
@@ -148,6 +188,47 @@ class ExtractSettingType:
return ctx.default_attr_type
def transform_form_view(ctx: ClassDefContext) -> None:
form_class_value = helpers.get_assigned_value_for_class(ctx.cls.info, 'form_class')
if isinstance(form_class_value, NameExpr):
helpers.get_django_metadata(ctx.cls.info)['form_class'] = form_class_value.fullname
def extract_proper_type_for_get_form_class(ctx: MethodContext) -> Type:
object_type = ctx.type
if not isinstance(object_type, Instance):
return ctx.default_return_type
form_class_fullname = helpers.get_django_metadata(object_type.type).get('form_class', None)
if not form_class_fullname:
return ctx.default_return_type
return TypeType(ctx.api.named_generic_type(form_class_fullname, []))
def extract_proper_type_for_get_form(ctx: MethodContext) -> Type:
object_type = ctx.type
if not isinstance(object_type, Instance):
return ctx.default_return_type
form_class_type = helpers.get_argument_type_by_name(ctx, 'form_class')
if form_class_type is None or isinstance(form_class_type, NoneTyp):
# extract from specified form_class in metadata
form_class_fullname = helpers.get_django_metadata(object_type.type).get('form_class', None)
if not form_class_fullname:
return ctx.default_return_type
return ctx.api.named_generic_type(form_class_fullname, [])
if isinstance(form_class_type, TypeType) and isinstance(form_class_type.item, Instance):
return form_class_type.item
if isinstance(form_class_type, CallableType) and isinstance(form_class_type.ret_type, Instance):
return form_class_type.ret_type
return ctx.default_return_type
class DjangoPlugin(Plugin):
def __init__(self, options: Options) -> None:
super().__init__(options)
@@ -176,31 +257,39 @@ class DjangoPlugin(Plugin):
def _get_current_model_bases(self) -> Dict[str, int]:
model_sym = self.lookup_fully_qualified(helpers.MODEL_CLASS_FULLNAME)
if model_sym is not None and isinstance(model_sym.node, TypeInfo):
if 'django' not in model_sym.node.metadata:
model_sym.node.metadata['django'] = {
'model_bases': {helpers.MODEL_CLASS_FULLNAME: 1}
}
return model_sym.node.metadata['django']['model_bases']
return (helpers.get_django_metadata(model_sym.node)
.setdefault('model_bases', {helpers.MODEL_CLASS_FULLNAME: 1}))
else:
return {}
def _get_current_manager_bases(self) -> Dict[str, int]:
manager_sym = self.lookup_fully_qualified(helpers.MANAGER_CLASS_FULLNAME)
if manager_sym is not None and isinstance(manager_sym.node, TypeInfo):
if 'django' not in manager_sym.node.metadata:
manager_sym.node.metadata['django'] = {
'manager_bases': {helpers.MANAGER_CLASS_FULLNAME: 1}
}
return manager_sym.node.metadata['django']['manager_bases']
model_sym = self.lookup_fully_qualified(helpers.MANAGER_CLASS_FULLNAME)
if model_sym is not None and isinstance(model_sym.node, TypeInfo):
return (helpers.get_django_metadata(model_sym.node)
.setdefault('manager_bases', {helpers.MANAGER_CLASS_FULLNAME: 1}))
else:
return {}
def _get_current_form_bases(self) -> Dict[str, int]:
model_sym = self.lookup_fully_qualified(helpers.BASEFORM_CLASS_FULLNAME)
if model_sym is not None and isinstance(model_sym.node, TypeInfo):
return (helpers.get_django_metadata(model_sym.node)
.setdefault('baseform_bases', {helpers.BASEFORM_CLASS_FULLNAME: 1,
helpers.FORM_CLASS_FULLNAME: 1,
helpers.MODELFORM_CLASS_FULLNAME: 1}))
else:
return {}
def _get_current_queryset_bases(self) -> Dict[str, int]:
model_sym = self.lookup_fully_qualified(helpers.QUERYSET_CLASS_FULLNAME)
if model_sym is not None and isinstance(model_sym.node, TypeInfo):
return (helpers.get_django_metadata(model_sym.node)
.setdefault('queryset_bases', {helpers.QUERYSET_CLASS_FULLNAME: 1}))
else:
return {}
def get_function_hook(self, fullname: str
) -> Optional[Callable[[FunctionContext], Type]]:
sym = self.lookup_fully_qualified(fullname)
if sym and isinstance(sym.node, TypeInfo) and sym.node.has_base(helpers.FIELD_FULLNAME):
return fields.adjust_return_type_of_field_instantiation
if fullname == 'django.contrib.auth.get_user_model':
return return_user_model_hook
@@ -209,27 +298,38 @@ class DjangoPlugin(Plugin):
return determine_proper_manager_type
sym = self.lookup_fully_qualified(fullname)
if sym and isinstance(sym.node, TypeInfo):
if sym is not None and isinstance(sym.node, TypeInfo):
if sym.node.has_base(helpers.FIELD_FULLNAME):
return fields.adjust_return_type_of_field_instantiation
if sym.node.metadata.get('django', {}).get('generated_init'):
return init_create.redefine_and_typecheck_model_init
def get_method_hook(self, fullname: str
) -> Optional[Callable[[MethodContext], Type]]:
manager_classes = self._get_current_manager_bases()
class_fullname, _, method_name = fullname.rpartition('.')
if class_fullname in manager_classes and method_name == 'create':
return init_create.redefine_and_typecheck_model_create
class_name, _, method_name = fullname.rpartition('.')
if method_name == 'get_form_class':
sym = self.lookup_fully_qualified(class_name)
if sym and isinstance(sym.node, TypeInfo) and sym.node.has_base(helpers.FORM_MIXIN_CLASS_FULLNAME):
return extract_proper_type_for_get_form_class
if method_name == 'get_form':
sym = self.lookup_fully_qualified(class_name)
if sym and isinstance(sym.node, TypeInfo) and sym.node.has_base(helpers.FORM_MIXIN_CLASS_FULLNAME):
return extract_proper_type_for_get_form
if fullname in {'django.apps.registry.Apps.get_model',
'django.db.migrations.state.StateApps.get_model'}:
return determine_model_cls_from_string_for_migrations
manager_classes = self._get_current_manager_bases()
class_fullname, _, method_name = fullname.rpartition('.')
if class_fullname in manager_classes and method_name == 'create':
return init_create.redefine_and_typecheck_model_create
return None
def get_base_class_hook(self, fullname: str
) -> Optional[Callable[[ClassDefContext], None]]:
if fullname in self._get_current_model_bases():
return transform_model_class
if fullname == helpers.DUMMY_SETTINGS_BASE_CLASS:
settings_modules = ['django.conf.global_settings']
if self.django_settings_module:
@@ -237,13 +337,26 @@ class DjangoPlugin(Plugin):
return AddSettingValuesToDjangoConfObject(settings_modules,
self.config.ignore_missing_settings)
if fullname in self._get_current_model_bases():
return transform_model_class
if fullname in self._get_current_manager_bases():
return transform_manager_class
if fullname in self._get_current_form_bases():
return transform_form_class
sym = self.lookup_fully_qualified(fullname)
if sym and isinstance(sym.node, TypeInfo) and sym.node.has_base(helpers.FORM_MIXIN_CLASS_FULLNAME):
return transform_form_view
return None
def get_attribute_hook(self, fullname: str
) -> Optional[Callable[[AttributeContext], Type]]:
if fullname == 'builtins.object.id':
return return_integer_type_for_id_for_non_defined_primary_key_in_models
module, _, name = fullname.rpartition('.')
sym = self.lookup_fully_qualified('django.conf.LazySettings')
if sym and isinstance(sym.node, TypeInfo):
@@ -251,11 +364,16 @@ class DjangoPlugin(Plugin):
if module == 'builtins.object' and name in metadata:
return ExtractSettingType(module_fullname=metadata[name])
if fullname == 'builtins.object.id':
return return_integer_type_for_id_for_non_defined_primary_key_in_models
return extract_and_return_primary_key_of_bound_related_field_parameter
def get_type_analyze_hook(self, fullname: str
) -> Optional[Callable[[AnalyzeTypeContext], Type]]:
queryset_bases = self._get_current_queryset_bases()
if fullname in queryset_bases:
return partial(set_first_generic_param_as_default_for_second, fullname)
return None
def plugin(version):
return DjangoPlugin

View File

@@ -1,4 +0,0 @@
from .dependencies import (add_modules_as_a_source_seed_files,
inject_modules_as_dependencies_for_django_conf_settings,
restore_original_load_graph,
restore_original_dependencies_handling)

View File

@@ -3,12 +3,14 @@ from typing import Optional, cast
from mypy.checker import TypeChecker
from mypy.nodes import ListExpr, NameExpr, StrExpr, TupleExpr, TypeInfo, Var
from mypy.plugin import FunctionContext
from mypy.types import AnyType, CallableType, Instance, TupleType, Type, TypeOfAny, UnionType
from mypy.types import (
AnyType, CallableType, Instance, TupleType, Type, TypeOfAny, UnionType,
)
from mypy_django_plugin import helpers
from mypy_django_plugin.transformers.models import iter_over_assignments
def get_valid_to_value_or_none(ctx: FunctionContext) -> Optional[Instance]:
def extract_referred_to_type(ctx: FunctionContext) -> Optional[Instance]:
api = cast(TypeChecker, ctx.api)
if 'to' not in ctx.callee_arg_names:
api.msg.fail(f'to= parameter must be set for {ctx.context.callee.fullname}',
@@ -27,6 +29,9 @@ def get_valid_to_value_or_none(ctx: FunctionContext) -> Optional[Instance]:
except helpers.SelfReference:
model_fullname = api.tscope.classes[-1].fullname()
except helpers.SameFileModel as exc:
model_fullname = api.tscope.classes[-1].module_name + '.' + exc.model_cls_name
if model_fullname is None:
return None
model_info = helpers.lookup_fully_qualified_generic(model_fullname,
@@ -52,8 +57,8 @@ def convert_any_to_type(typ: Type, referred_to_type: Type) -> Type:
converted_items = []
for item in typ.items:
converted_items.append(convert_any_to_type(item, referred_to_type))
return UnionType.make_simplified_union(converted_items,
line=typ.line, column=typ.column)
return UnionType.make_union(converted_items,
line=typ.line, column=typ.column)
if isinstance(typ, Instance):
args = []
for default_arg in typ.args:
@@ -69,19 +74,9 @@ def convert_any_to_type(typ: Type, referred_to_type: Type) -> Type:
return typ
def _extract_referred_to_type(ctx: FunctionContext) -> Optional[Type]:
try:
referred_to_type = get_valid_to_value_or_none(ctx)
except helpers.InvalidModelString as exc:
ctx.api.fail(f'Invalid value for a to= parameter: {exc.model_string!r}', ctx.context)
return None
return referred_to_type
def fill_descriptor_types_for_related_field(ctx: FunctionContext) -> Type:
default_return_type = set_descriptor_types_for_field(ctx)
referred_to_type = _extract_referred_to_type(ctx)
referred_to_type = extract_referred_to_type(ctx)
if referred_to_type is None:
return default_return_type
@@ -106,10 +101,6 @@ def get_private_descriptor_type(type_info: TypeInfo, private_field_name: str, is
def set_descriptor_types_for_field(ctx: FunctionContext) -> Instance:
default_return_type = cast(Instance, ctx.default_return_type)
is_nullable = helpers.parse_bool(helpers.get_argument_by_name(ctx, 'null'))
if not is_nullable and default_return_type.type.has_base(helpers.CHAR_FIELD_FULLNAME):
# blank=True for CharField can be interpreted as null=True
is_nullable = helpers.parse_bool(helpers.get_argument_by_name(ctx, 'blank'))
set_type = get_private_descriptor_type(default_return_type.type, '_pyi_private_set_type',
is_nullable=is_nullable)
get_type = get_private_descriptor_type(default_return_type.type, '_pyi_private_get_type',
@@ -161,7 +152,7 @@ def record_field_properties_into_outer_model_class(ctx: FunctionContext) -> None
return
field_name = None
for name_expr, stmt in iter_over_assignments(outer_model.defn):
for name_expr, stmt in helpers.iter_over_assignments(outer_model.defn):
if stmt == ctx.context and isinstance(name_expr, NameExpr):
field_name = name_expr.name
break

View File

@@ -0,0 +1,10 @@
from mypy.plugin import ClassDefContext
from mypy_django_plugin import helpers
def make_meta_nested_class_inherit_from_any(ctx: ClassDefContext) -> None:
meta_node = helpers.get_nested_meta_node_for_current_class(ctx.cls.info)
if meta_node is None:
return None
meta_node.fallback_to_any = True

View File

@@ -4,8 +4,8 @@ from mypy.checker import TypeChecker
from mypy.nodes import TypeInfo, Var
from mypy.plugin import FunctionContext, MethodContext
from mypy.types import AnyType, Instance, Type, TypeOfAny
from mypy_django_plugin import helpers
from mypy_django_plugin.helpers import extract_field_setter_type, extract_explicit_set_type_of_model_primary_key, get_fields_metadata
from mypy_django_plugin.transformers.fields import get_private_descriptor_type
@@ -106,7 +106,7 @@ def redefine_and_typecheck_model_create(ctx: MethodContext) -> Type:
def extract_choices_type(model: TypeInfo, field_name: str) -> Optional[str]:
field_metadata = get_fields_metadata(model).get(field_name, {})
field_metadata = helpers.get_fields_metadata(model).get(field_name, {})
if 'choices' in field_metadata:
return field_metadata['choices']
return None
@@ -117,7 +117,7 @@ def extract_expected_types(ctx: FunctionContext, model: TypeInfo,
api = cast(TypeChecker, ctx.api)
expected_types: Dict[str, Type] = {}
primary_key_type = extract_explicit_set_type_of_model_primary_key(model)
primary_key_type = helpers.extract_explicit_set_type_of_model_primary_key(model)
if not primary_key_type:
# no explicit primary key, set pk to Any and add id
primary_key_type = AnyType(TypeOfAny.special_form)
@@ -143,7 +143,7 @@ def extract_expected_types(ctx: FunctionContext, model: TypeInfo,
expected_types[name + '_id'] = AnyType(TypeOfAny.from_unimported_type)
elif isinstance(typ, Instance):
field_type = extract_field_setter_type(typ)
field_type = helpers.extract_field_setter_type(typ)
if field_type is None:
continue
@@ -156,8 +156,9 @@ def extract_expected_types(ctx: FunctionContext, model: TypeInfo,
if is_nullable:
referred_to_model = helpers.make_required(typ.args[1])
if isinstance(referred_to_model, Instance) and referred_to_model.type.has_base(helpers.MODEL_CLASS_FULLNAME):
pk_type = extract_explicit_set_type_of_model_primary_key(referred_to_model.type)
if isinstance(referred_to_model, Instance) and referred_to_model.type.has_base(
helpers.MODEL_CLASS_FULLNAME):
pk_type = helpers.extract_explicit_set_type_of_model_primary_key(referred_to_model.type)
if not pk_type:
# extract set type of AutoField
autofield_info = api.lookup_typeinfo('django.db.models.fields.AutoField')
@@ -170,7 +171,7 @@ def extract_expected_types(ctx: FunctionContext, model: TypeInfo,
expected_types[name + '_id'] = related_primary_key_type
field_metadata = get_fields_metadata(model).get(name, {})
field_metadata = helpers.get_fields_metadata(model).get(name, {})
if field_type:
# related fields could be None in __init__ (but should be specified before save())
if helpers.has_any_of_bases(typ.type, (helpers.FOREIGN_KEY_FULLNAME,
@@ -178,7 +179,15 @@ def extract_expected_types(ctx: FunctionContext, model: TypeInfo,
field_type = helpers.make_optional(field_type)
# if primary_key=True and default specified
elif field_metadata.get('primary_key', False) and field_metadata.get('default_specified', False):
elif field_metadata.get('primary_key', False) and field_metadata.get('default_specified',
False):
field_type = helpers.make_optional(field_type)
# if CharField(blank=True,...) and not nullable, then field can be None in __init__
elif (
helpers.has_any_of_bases(typ.type, (helpers.CHAR_FIELD_FULLNAME,)) and is_init and
field_metadata.get('blank', False) and not field_metadata.get('null', False)
):
field_type = helpers.make_optional(field_type)
expected_types[name] = field_type

View File

@@ -4,6 +4,7 @@ from mypy.checker import TypeChecker
from mypy.nodes import Expression, StrExpr, TypeInfo
from mypy.plugin import MethodContext
from mypy.types import Instance, Type, TypeType
from mypy_django_plugin import helpers

View File

@@ -2,14 +2,16 @@ from abc import ABCMeta, abstractmethod
from typing import Dict, Iterator, List, Optional, Tuple, cast
import dataclasses
from mypy.nodes import ARG_STAR, ARG_STAR2, Argument, CallExpr, ClassDef, Context, Expression, IndexExpr, \
Lvalue, MDEF, MemberExpr, MypyFile, NameExpr, StrExpr, SymbolTableNode, TypeInfo, Var
from mypy.nodes import (
ARG_STAR, ARG_STAR2, MDEF, Argument, CallExpr, ClassDef, Expression, IndexExpr, Lvalue, MemberExpr, MypyFile,
NameExpr, StrExpr, SymbolTableNode, TypeInfo, Var,
)
from mypy.plugin import ClassDefContext
from mypy.plugins.common import add_method
from mypy.semanal import SemanticAnalyzerPass2
from mypy.types import AnyType, Instance, NoneTyp, TypeOfAny
from mypy_django_plugin import helpers
from mypy_django_plugin.helpers import iter_over_assignments
@dataclasses.dataclass
@@ -21,20 +23,12 @@ class ModelClassInitializer(metaclass=ABCMeta):
def from_ctx(cls, ctx: ClassDefContext):
return cls(api=cast(SemanticAnalyzerPass2, ctx.api), model_classdef=ctx.cls)
def get_nested_meta_node(self) -> Optional[TypeInfo]:
metaclass_sym = self.model_classdef.info.names.get('Meta')
if metaclass_sym is not None and isinstance(metaclass_sym.node, TypeInfo):
return metaclass_sym.node
return None
def get_meta_attribute(self, name: str) -> Optional[Expression]:
meta_node = self.get_nested_meta_node()
meta_node = helpers.get_nested_meta_node_for_current_class(self.model_classdef.info)
if meta_node is None:
return None
for lvalue, rvalue in iter_over_assignments(meta_node.defn):
if isinstance(lvalue, NameExpr) and lvalue.name == name:
return rvalue
return helpers.get_assigned_value_for_class(meta_node, name)
def is_abstract_model(self) -> bool:
is_abstract_expr = self.get_meta_attribute('abstract')
@@ -48,7 +42,7 @@ class ModelClassInitializer(metaclass=ABCMeta):
var._fullname = self.model_classdef.info.fullname() + '.' + name
var.is_inferred = True
var.is_initialized_in_class = True
self.model_classdef.info.names[name] = SymbolTableNode(MDEF, var)
self.model_classdef.info.names[name] = SymbolTableNode(MDEF, var, plugin_generated=True)
@abstractmethod
def run(self) -> None:
@@ -56,7 +50,7 @@ class ModelClassInitializer(metaclass=ABCMeta):
def iter_call_assignments(klass: ClassDef) -> Iterator[Tuple[Lvalue, CallExpr]]:
for lvalue, rvalue in iter_over_assignments(klass):
for lvalue, rvalue in helpers.iter_over_assignments(klass):
if isinstance(rvalue, CallExpr):
yield lvalue, rvalue
@@ -64,7 +58,7 @@ def iter_call_assignments(klass: ClassDef) -> Iterator[Tuple[Lvalue, CallExpr]]:
def iter_over_one_to_n_related_fields(klass: ClassDef) -> Iterator[Tuple[NameExpr, CallExpr]]:
for lvalue, rvalue in iter_call_assignments(klass):
if (isinstance(lvalue, NameExpr)
and isinstance(rvalue.callee, MemberExpr)):
and isinstance(rvalue.callee, MemberExpr)):
if rvalue.callee.fullname in {helpers.FOREIGN_KEY_FULLNAME,
helpers.ONETOONE_FIELD_FULLNAME}:
yield lvalue, rvalue
@@ -80,7 +74,7 @@ class SetIdAttrsForRelatedFields(ModelClassInitializer):
class InjectAnyAsBaseForNestedMeta(ModelClassInitializer):
def run(self) -> None:
meta_node = self.get_nested_meta_node()
meta_node = helpers.get_nested_meta_node_for_current_class(self.model_classdef.info)
if meta_node is None:
return None
meta_node.fallback_to_any = True
@@ -115,8 +109,8 @@ class AddDefaultObjectsManager(ModelClassInitializer):
if isinstance(callee_expr, IndexExpr):
callee_expr = callee_expr.analyzed.expr
if isinstance(callee_expr, (MemberExpr, NameExpr)) \
and isinstance(callee_expr.node, TypeInfo) \
and callee_expr.node.has_base(helpers.BASE_MANAGER_CLASS_FULLNAME):
and isinstance(callee_expr.node, TypeInfo) \
and callee_expr.node.has_base(helpers.BASE_MANAGER_CLASS_FULLNAME):
managers.append((manager_name, callee_expr.node))
return managers
@@ -155,7 +149,7 @@ class AddIdAttributeIfPrimaryKeyTrueIsNotSet(ModelClassInitializer):
for _, rvalue in iter_call_assignments(self.model_classdef):
if ('primary_key' in rvalue.arg_names
and self.api.parse_bool(rvalue.args[rvalue.arg_names.index('primary_key')])):
and self.api.parse_bool(rvalue.args[rvalue.arg_names.index('primary_key')])):
break
else:
self.add_new_node_to_model_class('id', self.api.builtin_type('builtins.object'))
@@ -173,10 +167,9 @@ class AddRelatedManagers(ModelClassInitializer):
all_modules=self.api.modules)
except helpers.SelfReference:
ref_to_fullname = defn.fullname
except helpers.InvalidModelString as exc:
self.api.fail(f'Invalid value for a to= parameter: {exc.model_string!r}',
Context(line=rvalue.line))
return None
except helpers.SameFileModel as exc:
ref_to_fullname = module_name + '.' + exc.model_cls_name
if self.model_classdef.fullname == ref_to_fullname:
related_manager_name = defn.name.lower() + '_set'
@@ -211,10 +204,10 @@ def is_related_field(expr: CallExpr, module_file: MypyFile) -> bool:
if isinstance(expr.callee, MemberExpr) and isinstance(expr.callee.expr, NameExpr):
module = module_file.names.get(expr.callee.expr.name)
if module \
and module.fullname == 'django.db.models' \
and expr.callee.name in {'ForeignKey',
'OneToOneField',
'ManyToManyField'}:
and module.fullname == 'django.db.models' \
and expr.callee.name in {'ForeignKey',
'OneToOneField',
'ManyToManyField'}:
return True
return False

View File

@@ -1,6 +1,8 @@
from typing import Iterable, List, Optional, cast
from mypy.nodes import ClassDef, Context, ImportAll, MypyFile, SymbolNode, SymbolTableNode, TypeInfo, Var
from mypy.nodes import (
ClassDef, Context, ImportAll, MypyFile, SymbolNode, SymbolTableNode, TypeInfo, Var,
)
from mypy.plugin import ClassDefContext
from mypy.semanal import SemanticAnalyzerPass2
from mypy.types import AnyType, Instance, NoneTyp, Type, TypeOfAny, UnionType
@@ -56,8 +58,8 @@ def load_settings_from_names(settings_classdef: ClassDef,
settings_classdef.info.names[name] = copied
else:
var = Var(name, AnyType(TypeOfAny.unannotated))
var.info = api.named_type('__builtins__.object').type
settings_classdef.info.names[name] = SymbolTableNode(sym.kind, var)
var.info = api.named_type('__builtins__.object').type # outer class type
settings_classdef.info.names[name] = SymbolTableNode(sym.kind, var, plugin_generated=True)
settings_metadata[name] = module.fullname()
@@ -67,11 +69,12 @@ def get_import_star_modules(api: SemanticAnalyzerPass2, module: MypyFile) -> Lis
for module_import in module.imports:
# relative import * are not resolved by mypy
if isinstance(module_import, ImportAll) and module_import.relative:
absolute_import_path, correct = correct_relative_import(module.fullname(), module_import.relative, module_import.id,
is_cur_package_init_file=False)
absolute_import_path, correct = correct_relative_import(module.fullname(), module_import.relative,
module_import.id, is_cur_package_init_file=False)
if not correct:
return []
for path in [absolute_import_path] + get_import_star_modules(api, module=api.modules.get(absolute_import_path)):
for path in [absolute_import_path] + get_import_star_modules(api,
module=api.modules.get(absolute_import_path)):
if path not in import_star_modules:
import_star_modules.append(path)
return import_star_modules

View File

@@ -1,9 +1,7 @@
[pytest]
testpaths = ./test-data
addopts =
--tb=native
--mypy-ini-file=./test-data/plugins.ini
--mypy-no-cache
-s
-v

View File

@@ -1,7 +1,7 @@
#!/usr/local/bin/xonsh
try:
pip install wheel
pip install wheel twine
python setup.py sdist bdist_wheel --universal
twine upload dist/*

View File

@@ -4,7 +4,6 @@ ignore_missing_imports = True
check_untyped_defs = True
warn_no_return = False
show_traceback = True
warn_redundant_casts = True
allow_redefinition = True
incremental = False

View File

@@ -1,3 +1,4 @@
import itertools
import os
import re
import sys
@@ -32,12 +33,13 @@ IGNORED_ERRORS = {
'Cannot assign to a type',
re.compile(r'Cannot assign to class variable "[a-z_]+" via instance'),
# forms <-> models plugin support
'"Model" has no attribute',
# '"Model" has no attribute',
re.compile(r'Cannot determine type of \'(objects|stuff)\''),
# settings
re.compile(r'Module has no attribute "[A-Z_]+"'),
# attributes assigned to test functions
re.compile(r'"Callable\[(\[(Any(, )?)*((, )?VarArg\(Any\))?((, )?KwArg\(Any\))?\]|\.\.\.), Any\]" has no attribute'),
re.compile(
r'"Callable\[(\[(Any(, )?)*((, )?VarArg\(Any\))?((, )?KwArg\(Any\))?\]|\.\.\.), Any\]" has no attribute'),
# assign empty tuple
re.compile(r'Incompatible types in assignment \(expression has type "Tuple\[\]", '
r'variable has type "Tuple\[[A-Za-z, ]+\]"'),
@@ -54,7 +56,10 @@ IGNORED_ERRORS = {
'ValuesIterable',
'Value of type "Optional[Dict[str, Any]]" is not indexable',
'Argument 1 to "len" has incompatible type "Optional[List[_Record]]"; expected "Sized"',
'Argument 1 to "loads" has incompatible type "Union[bytes, str, None]"; expected "Union[str, bytes, bytearray]"'
'Argument 1 to "loads" has incompatible type "Union[bytes, str, None]"; '
+ 'expected "Union[str, bytes, bytearray]"',
'Incompatible types in assignment (expression has type "None", variable has type Module)',
'note:'
],
'admin_changelist': [
'Incompatible types in assignment (expression has type "FilteredChildAdmin", variable has type "ChildAdmin")'
@@ -64,8 +69,9 @@ IGNORED_ERRORS = {
],
'admin_widgets': [
'Incompatible types in assignment (expression has type "RelatedFieldWidgetWrapper", '
'variable has type "AdminRadioSelect")',
'Incompatible types in assignment (expression has type "Union[Widget, Any]", variable has type "AutocompleteSelect")'
+ 'variable has type "AdminRadioSelect")',
'Incompatible types in assignment (expression has type "Union[Widget, Any]", '
+ 'variable has type "AutocompleteSelect")'
],
'admin_utils': [
re.compile(r'Argument [0-9] to "lookup_field" has incompatible type'),
@@ -85,17 +91,10 @@ IGNORED_ERRORS = {
'Argument "is_dst" to "localize" of "BaseTzInfo" has incompatible type "None"; expected "bool"'
],
'aggregation': [
'Incompatible types in assignment (expression has type "QuerySet[Any]", variable has type "List[Any]")',
'"as_sql" undefined in superclass',
'Incompatible types in assignment (expression has type "FlatValuesListIterable", '
+ 'variable has type "ValuesListIterable")',
'Incompatible type for "contact" of "Book" (got "Optional[Author]", expected "Union[Author, Combinable]")',
'Incompatible type for "publisher" of "Book" (got "Optional[Publisher]", expected "Union[Publisher, Combinable]")'
],
'aggregation_regress': [
'Incompatible types in assignment (expression has type "List[str]", variable has type "QuerySet[Author]")',
'Incompatible types in assignment (expression has type "FlatValuesListIterable", variable has type "QuerySet[Any]")',
'Too few arguments for "count" of "Sequence"'
'Incompatible type for "publisher" of "Book" (got "Optional[Publisher]", '
+ 'expected "Union[Publisher, Combinable]")'
],
'apps': [
'Incompatible types in assignment (expression has type "str", target has type "type")',
@@ -151,9 +150,6 @@ IGNORED_ERRORS = {
'db_typecasts': [
'"object" has no attribute "__iter__"; maybe "__str__" or "__dir__"? (not iterable)'
],
'expressions': [
'Argument 1 to "Subquery" has incompatible type "Sequence[Dict[str, Any]]"; expected "QuerySet[Any]"'
],
'from_db_value': [
'has no attribute "vendor"'
],
@@ -166,11 +162,34 @@ IGNORED_ERRORS = {
'fixtures': [
'Incompatible types in assignment (expression has type "int", target has type "Iterable[str]")'
],
'forms_tests': [
'List item 0 has incompatible type "Jinja2"; expected "DjangoTemplates"',
'Not enough arguments for format string',
'Argument after ** must be a mapping, not "object"',
'"media" undefined in superclass',
'expression has type "None", base class "TestFormParent"',
'variable has type "SongForm"',
'"full_clean" of "BaseForm" does not return a value',
'No overload variant of "zip" matches argument types "Tuple[str, str, str]", "object"',
'Incompatible types in assignment (expression has type "GetDateShowHiddenInitial", '
+ 'variable has type "GetDate")',
re.compile(r'Incompatible types in assignment \(expression has type "[a-zA-Z]+Field", '
r'base class "BaseForm" defined the type as "Dict\[str, Any\]"\)'),
'List or tuple expected as variable arguments',
'Argument 1 to "__init__" of "MultiWidget" has incompatible type "List[object]"; '
+ 'expected "Sequence[Union[Widget, Type[Widget]]]"',
'Argument 1 to "issubclass" has incompatible type "ModelFormMetaclass"; expected "type"',
'Incompatible types in assignment (expression has type "List[str]", target has type "str")',
'Incompatible types in assignment (expression has type "TestForm", variable has type "Person")',
'Incompatible types in assignment (expression has type "Type[Textarea]", '
+ 'base class "Field" defined the type as "Widget")',
'Incompatible types in assignment (expression has type "SimpleUploadedFile", variable has type "BinaryIO")',
],
'get_object_or_404': [
'Argument 1 to "get_object_or_404" has incompatible type "str"; '
+ 'expected "Union[Type[<nothing>], Manager[<nothing>], QuerySet[<nothing>]]"',
+ 'expected "Union[Type[<nothing>], QuerySet[<nothing>, <nothing>]]"',
'Argument 1 to "get_list_or_404" has incompatible type "List[Type[Article]]"; '
+ 'expected "Union[Type[<nothing>], Manager[<nothing>], QuerySet[<nothing>]]"',
+ 'expected "Union[Type[<nothing>], QuerySet[<nothing>, <nothing>]]"',
'CustomClass'
],
'get_or_create': [
@@ -190,23 +209,33 @@ IGNORED_ERRORS = {
'logging_tests': [
re.compile('"(setUpClass|tearDownClass)" undefined in superclass')
],
'lookup': [
'Unexpected keyword argument "headline__startswith" for "in_bulk" of "QuerySet"',
],
'many_to_one': [
'Incompatible type for "parent" of "Child" (got "None", expected "Union[Parent, Combinable]")'
],
'model_inheritance_regress': [
'Incompatible types in assignment (expression has type "List[Supplier]", variable has type "QuerySet[Supplier]")'
],
'model_meta': [
'"object" has no attribute "items"',
'"Field" has no attribute "many_to_many"'
],
'model_forms': [
'Argument "instance" to "InvalidModelForm" has incompatible type "Type[Category]"; expected "Optional[Model]"',
'Invalid type "NewForm"'
],
'model_fields': [
'Incompatible types in assignment (expression has type "Type[Person]", variable has type',
'Unexpected keyword argument "name" for "Person"',
'Cannot assign multiple types to name "PersonTwoImages" without an explicit "Type[...]" annotation',
'Incompatible types in assignment (expression has type "Type[Person]", '
+ 'base class "ImageFieldTestMixin" defined the type as "Type[PersonWithHeightAndWidth]")',
'note: "Person" defined here'
],
'model_formsets': [
'Incompatible types in string interpolation (expression has type "object", '
+ 'placeholder has type "Union[int, float]")'
],
'model_formsets_regress': [
'Incompatible types in assignment (expression has type "Model", variable has type "User")'
],
'model_regress': [
'Too many arguments for "Worker"',
@@ -249,16 +278,19 @@ IGNORED_ERRORS = {
'Incompatible types in assignment (expression has type "Type[Field[Any, Any]]',
'DummyArrayField',
'DummyJSONField',
'Argument "encoder" to "JSONField" has incompatible type "DjangoJSONEncoder"; expected "Optional[Type[JSONEncoder]]"',
'Argument "encoder" to "JSONField" has incompatible type "DjangoJSONEncoder"; '
+ 'expected "Optional[Type[JSONEncoder]]"',
'for model "CITestModel"',
'Incompatible type for "field" of "IntegerArrayModel" (got "None", expected "Union[Sequence[int], Combinable]")'
'Incompatible type for "field" of "IntegerArrayModel" (got "None", '
+ 'expected "Union[Sequence[int], Combinable]")'
],
'properties': [
re.compile('Unexpected attribute "(full_name|full_name_2)" for model "Person"')
],
'queries': [
'Incompatible types in assignment (expression has type "None", variable has type "str")',
'Invalid index type "Optional[str]" for "Dict[str, int]"; expected type "str"'
'Invalid index type "Optional[str]" for "Dict[str, int]"; expected type "str"',
'No overload variant of "values_list" of "QuerySet" matches argument types "str", "bool", "bool"',
],
'requests': [
'Incompatible types in assignment (expression has type "Dict[str, str]", variable has type "QueryDict")'
@@ -267,7 +299,7 @@ IGNORED_ERRORS = {
'Argument 1 to "TextIOWrapper" has incompatible type "HttpResponse"; expected "IO[bytes]"'
],
'prefetch_related': [
'Incompatible types in assignment (expression has type "List[Room]", variable has type "QuerySet[Room]")',
'Incompatible types in assignment (expression has type "List[Room]", variable has type "QuerySet[Room, Room]")',
'"None" has no attribute "__iter__"',
'has no attribute "read_by"'
],
@@ -286,7 +318,8 @@ IGNORED_ERRORS = {
],
'schema': [
'Incompatible type for "info" of "Note" (got "None", expected "Union[str, Combinable]")',
'Incompatible type for "detail_info" of "NoteRename" (got "None", expected "Union[str, Combinable]")'
'Incompatible type for "detail_info" of "NoteRename" (got "None", expected "Union[str, Combinable]")',
'Incompatible type for "year" of "UniqueTest" (got "None", expected "Union[float, int, str, Combinable]")'
],
'settings_tests': [
'Argument 1 to "Settings" has incompatible type "Optional[str]"; expected "str"'
@@ -295,11 +328,14 @@ IGNORED_ERRORS = {
'Incompatible types in assignment (expression has type "Thread", variable has type "Callable[[], Any]")'
],
'test_client': [
'Incompatible types in assignment (expression has type "StreamingHttpResponse", variable has type "HttpResponse")',
'Incompatible types in assignment (expression has type "HttpResponse", variable has type "StreamingHttpResponse")'
'Incompatible types in assignment (expression has type "StreamingHttpResponse", '
+ 'variable has type "HttpResponse")',
'Incompatible types in assignment (expression has type "HttpResponse", '
+ 'variable has type "StreamingHttpResponse")'
],
'test_client_regress': [
'Incompatible types in assignment (expression has type "Dict[<nothing>, <nothing>]", variable has type "SessionBase")',
'Incompatible types in assignment (expression has type "Dict[<nothing>, <nothing>]", '
+ 'variable has type "SessionBase")',
'Unsupported left operand type for + ("None")',
'Both left and right operands are unions'
],
@@ -309,7 +345,8 @@ IGNORED_ERRORS = {
'test_runner': [
'Value of type "TestSuite" is not indexable',
'"TestSuite" has no attribute "_tests"',
'Argument "result" to "run" of "TestCase" has incompatible type "RemoteTestResult"; expected "Optional[TestResult]"',
'Argument "result" to "run" of "TestCase" has incompatible type "RemoteTestResult"; '
+ 'expected "Optional[TestResult]"',
'Item "TestSuite" of "Union[TestCase, TestSuite]" has no attribute "id"',
'MockTestRunner',
'Incompatible types in assignment (expression has type "Tuple[Union[TestCase, TestSuite], ...]", '
@@ -329,7 +366,6 @@ IGNORED_ERRORS = {
'template_backends': [
'Incompatible import of "Jinja2" (imported name has type "Type[Jinja2]", local name has type "object")',
'TemplateStringsTests',
'Incompatible types in assignment (expression has type "None", variable has type Module)'
],
'urlpatterns': [
'"object" has no attribute "__iter__"; maybe "__str__" or "__dir__"? (not iterable)',
@@ -348,7 +384,7 @@ IGNORED_ERRORS = {
],
'sessions_tests': [
'base class "SessionTestsMixin" defined the type as "None")',
'Incompatible types in assignment (expression has type "None", variable has type "int")'
'Incompatible types in assignment (expression has type "None", variable has type "int")',
],
'select_related_onetoone': [
'"None" has no attribute'
@@ -439,7 +475,7 @@ TESTS_DIRS = [
'flatpages_tests',
'force_insert_update',
'foreign_object',
# TODO: 'forms_tests',
'forms_tests',
'from_db_value',
'generic_inline_admin',
'generic_relations',
@@ -593,7 +629,8 @@ def cd(path):
def is_ignored(line: str, test_folder_name: str) -> bool:
for pattern in IGNORED_ERRORS['__common__'] + IGNORED_ERRORS.get(test_folder_name, []):
for pattern in itertools.chain(IGNORED_ERRORS['__common__'],
IGNORED_ERRORS.get(test_folder_name, [])):
if isinstance(pattern, Pattern):
if pattern.search(line):
return True
@@ -631,6 +668,10 @@ def check_with_mypy(abs_path: Path, config_file_path: Path) -> int:
return int(error_happened)
def get_absolute_path_for_test(test_dirname: str):
return (PROJECT_DIRECTORY / tests_root / test_dirname).absolute()
if __name__ == '__main__':
mypy_config_file = (PROJECT_DIRECTORY / 'scripts' / 'mypy.ini').absolute()
repo_directory = PROJECT_DIRECTORY / 'django-sources'
@@ -645,8 +686,14 @@ if __name__ == '__main__':
repo.remotes['origin'].pull(DJANGO_BRANCH)
repo.git.checkout(DJANGO_COMMIT_SHA)
for dirname in TESTS_DIRS:
abs_path = (PROJECT_DIRECTORY / tests_root / dirname).absolute()
if len(sys.argv) > 1:
tests_to_run = sys.argv[1:]
else:
tests_to_run = TESTS_DIRS
for dirname in tests_to_run:
abs_path = get_absolute_path_for_test(dirname)
print(f'Checking {abs_path}')
rc = check_with_mypy(abs_path, mypy_config_file)

29
setup.cfg Normal file
View File

@@ -0,0 +1,29 @@
[isort]
skip =
django-sources,
django-stubs,
test-data
include_trailing_comma = true
multi_line_output = 5
wrap_length = 120
[flake8]
exclude =
django-sources,
django-stubs,
test-data
max_line_length = 120
[tool:pytest]
testpaths = ./test-data
addopts =
--tb=native
--mypy-ini-file=./test-data/plugins.ini
-s
-v
[bdist_wheel]
universal = 1
[metadata]
license_file = LICENSE.txt

View File

@@ -21,7 +21,6 @@ with open('README.md', 'r') as f:
readme = f.read()
dependencies = [
'Django',
'mypy>=0.670',
'typing-extensions'
]
@@ -31,7 +30,7 @@ if sys.version_info[:2] < (3, 7):
setup(
name="django-stubs",
version="0.5.1",
version="0.9.0",
description='Django mypy stubs',
long_description=readme,
long_description_content_type='text/markdown',

View File

@@ -1,5 +1,5 @@
[mypy]
incremental = False
incremental = True
strict_optional = True
plugins =
mypy_django_plugin.main

View File

@@ -1,28 +1,30 @@
[CASE missing_settings_ignored_flag]
[env MYPY_DJANGO_CONFIG=${MYPY_CWD}/mypy_django.ini]
[disable_cache]
from django.conf import settings
reveal_type(settings.NO_SUCH_SETTING) # E: Revealed type is 'Any'
[env MYPY_DJANGO_CONFIG=${MYPY_CWD}/mypy_django.ini]
[file mypy_django.ini]
[[mypy_django_plugin]
ignore_missing_settings = True
[out]
[/CASE]
[CASE django_settings_via_config_file]
[env MYPY_DJANGO_CONFIG=${MYPY_CWD}/mypy_django.ini]
[disable_cache]
from django.conf import settings
reveal_type(settings.MY_SETTING) # E: Revealed type is 'builtins.int'
[env MYPY_DJANGO_CONFIG=${MYPY_CWD}/mypy_django.ini]
[file mypy_django.ini]
[[mypy_django_plugin]
django_settings = mysettings
[file mysettings.py]
MY_SETTING: int = 1
[out]
[/CASE]
[CASE mypy_django_ini_in_current_directory_is_a_default]
[disable_cache]
from django.conf import settings
reveal_type(settings.MY_SETTING) # E: Revealed type is 'builtins.int'
@@ -32,4 +34,4 @@ django_settings = mysettings
[file mysettings.py]
MY_SETTING: int = 1
[out]
[/CASE]

Some files were not shown because too many files have changed in this diff Show More