Skip to content

Commit 74eae06

Browse files
committed
2 parents 5a1dd9f + dbbdec7 commit 74eae06

File tree

26 files changed

+114
-219
lines changed

26 files changed

+114
-219
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ jobs:
9595
SETUPTOOLS_ENABLE_FEATURES=legacy-editable pip install -r ./requirements.txt
9696
9797
- name: Run stubtest
98-
run: bash ./scripts/stubtest.sh
98+
run: ./scripts/stubtest.sh
9999

100100
run-pyright:
101101
timeout-minutes: 10

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ repos:
1717
args: [--fix=lf]
1818
- id: check-case-conflict
1919
- repo: https://github.com/astral-sh/ruff-pre-commit
20-
rev: v0.9.7
20+
rev: v0.9.10
2121
hooks:
2222
- id: ruff
2323
args: ["--fix", "--exit-non-zero-on-fix"]

CONTRIBUTING.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,12 @@ rm -r .mypy_cache
7979

8080
### Testing stubs with `stubtest`
8181

82-
Run `bash ./scripts/stubtest.sh` to test that stubs and sources are in-line.
82+
Run `./scripts/stubtest.sh` to test that stubs and sources are in-line.
8383

84-
We have two special files to allow errors:
84+
We have some special files to allow errors:
8585
1. `scripts/stubtest/allowlist.txt` where we store things that we really don't care about: hacks, django internal utility modules, things that are handled by our plugin, things that are not representable by type system, etc
86-
2. `scripts/stubtest/allowlist_todo.txt` where we store all errors there are right now. Basically, this is a TODO list: we need to work through this list and fix things (or move entries to real `allowlist.txt`). In the end, ideally we can remove this file
86+
2. `scripts/stubtest/allowlist_todo.txt` where we store all errors there are right now. Basically, this is a TODO list: we need to work through this list and fix things (or move entries to real `allowlist.txt`). In the end, ideally we can remove this file.
87+
3. `scripts/stubtest/allowlist_todo_django51.txt` where we store new errors from the Django 5.0 to 5.1 upgrade. This is an extra TODO list.
8788

8889
You might also want to disable `incremental` mode while working on `stubtest` changes.
8990
This mode leads to several known problems (stubs do not show up or have strange errors).
Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,9 @@
1-
# Stubs for django.conf.urls (Python 3.5)
2-
from collections.abc import Callable, Sequence
3-
from typing import Any, overload
4-
5-
from django.http.response import HttpResponse, HttpResponseBase
6-
from django.urls import URLPattern, URLResolver
71
from django.urls import include as include
8-
from typing_extensions import TypeAlias
9-
10-
handler400: str | Callable[..., HttpResponse]
11-
handler403: str | Callable[..., HttpResponse]
12-
handler404: str | Callable[..., HttpResponse]
13-
handler500: str | Callable[..., HttpResponse]
2+
from django.views import defaults
143

15-
_IncludedURLConf: TypeAlias = tuple[Sequence[URLResolver | URLPattern], str | None, str | None]
4+
__all__ = ["handler400", "handler403", "handler404", "handler500", "include"]
165

17-
# Deprecated
18-
@overload
19-
def url(
20-
regex: str, view: Callable[..., HttpResponseBase], kwargs: dict[str, Any] | None = ..., name: str | None = ...
21-
) -> URLPattern: ...
22-
@overload
23-
def url(
24-
regex: str, view: _IncludedURLConf, kwargs: dict[str, Any] | None = ..., name: str | None = ...
25-
) -> URLResolver: ...
26-
@overload
27-
def url(
28-
regex: str,
29-
view: Sequence[URLResolver | str],
30-
kwargs: dict[str, Any] | None = ...,
31-
name: str | None = ...,
32-
) -> URLResolver: ...
6+
handler400 = defaults.bad_request
7+
handler403 = defaults.permission_denied
8+
handler404 = defaults.page_not_found
9+
handler500 = defaults.server_error

django-stubs/contrib/admin/models.pyi

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, ClassVar, Literal, overload
1+
from typing import Any, ClassVar
22
from uuid import UUID
33

44
from django.contrib.auth.models import AbstractUser
@@ -25,26 +25,13 @@ class LogEntryManager(models.Manager[LogEntry]):
2525
action_flag: int,
2626
change_message: Any = ...,
2727
) -> LogEntry: ...
28-
@overload
2928
def log_actions(
3029
self,
3130
user_id: int,
3231
queryset: QuerySet[Model],
3332
action_flag: int,
3433
change_message: str | list[Any] = "",
35-
*,
36-
single_object: Literal[True],
37-
) -> LogEntry: ...
38-
@overload
39-
def log_actions(
40-
self,
41-
user_id: int,
42-
queryset: QuerySet[Model],
43-
action_flag: int,
44-
change_message: str | list[Any] = "",
45-
*,
46-
single_object: Literal[False] = False,
47-
) -> list[LogEntry]: ...
34+
) -> list[LogEntry] | LogEntry: ...
4835

4936
class LogEntry(models.Model):
5037
id: models.AutoField

django-stubs/contrib/admin/options.pyi

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import enum
22
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
3-
from typing import Any, Generic, Literal, TypeVar, cast, overload, type_check_only
3+
from typing import Any, ClassVar, Generic, Literal, TypeVar, cast, overload, type_check_only
44

55
from django import forms
66
from django.contrib.admin.filters import FieldListFilter, ListFilter
@@ -84,23 +84,25 @@ _ListFilterT: TypeAlias = (
8484
_ModelT = TypeVar("_ModelT", bound=Model)
8585
_DisplayT: TypeAlias = _ListOrTuple[str | Callable[[_ModelT], str | bool]]
8686

87+
# Options `form`, `list_display`, `list_display_links` and `actions` are not marked as `ClassVar` due to the
88+
# limitations of the current type system: `ClassVar` cannot contain type variables.
8789
class BaseModelAdmin(Generic[_ModelT]):
88-
autocomplete_fields: _ListOrTuple[str]
89-
raw_id_fields: _ListOrTuple[str]
90-
fields: _FieldGroups | None
91-
exclude: _ListOrTuple[str] | None
92-
fieldsets: _FieldsetSpec | None
90+
autocomplete_fields: ClassVar[_ListOrTuple[str]]
91+
raw_id_fields: ClassVar[_ListOrTuple[str]]
92+
fields: ClassVar[_FieldGroups | None]
93+
exclude: ClassVar[_ListOrTuple[str] | None]
94+
fieldsets: ClassVar[_FieldsetSpec | None]
9395
form: type[forms.ModelForm[_ModelT]]
94-
filter_vertical: _ListOrTuple[str]
95-
filter_horizontal: _ListOrTuple[str]
96-
radio_fields: Mapping[str, _Direction]
97-
prepopulated_fields: dict[str, Sequence[str]]
98-
formfield_overrides: Mapping[type[Field], Mapping[str, Any]]
99-
readonly_fields: _ListOrTuple[str]
100-
ordering: _ListOrTuple[str] | None
101-
sortable_by: _ListOrTuple[str] | None
102-
show_full_result_count: bool
103-
checks_class: Any
96+
filter_vertical: ClassVar[_ListOrTuple[str]]
97+
filter_horizontal: ClassVar[_ListOrTuple[str]]
98+
radio_fields: ClassVar[Mapping[str, _Direction]]
99+
prepopulated_fields: ClassVar[dict[str, Sequence[str]]]
100+
formfield_overrides: ClassVar[Mapping[type[Field], Mapping[str, Any]]]
101+
readonly_fields: ClassVar[_ListOrTuple[str]]
102+
ordering: ClassVar[_ListOrTuple[str] | None]
103+
sortable_by: ClassVar[_ListOrTuple[str] | None]
104+
show_full_result_count: ClassVar[bool]
105+
checks_class: ClassVar[Any]
104106
model: type[_ModelT]
105107
opts: Options[_ModelT]
106108
admin_site: AdminSite
@@ -150,33 +152,33 @@ _ActionCallable: TypeAlias = Callable[[_ModelAdmin, HttpRequest, QuerySet[_Model
150152
class ModelAdmin(BaseModelAdmin[_ModelT]):
151153
list_display: _DisplayT[_ModelT]
152154
list_display_links: _DisplayT[_ModelT] | None
153-
list_filter: _ListOrTuple[_ListFilterT]
154-
list_select_related: bool | _ListOrTuple[str]
155-
list_per_page: int
156-
list_max_show_all: int
157-
list_editable: _ListOrTuple[str]
158-
search_fields: _ListOrTuple[str]
159-
search_help_text: _StrOrPromise | None
160-
date_hierarchy: str | None
161-
save_as: bool
162-
save_as_continue: bool
163-
save_on_top: bool
164-
paginator: type
165-
preserve_filters: bool
166-
show_facets: ShowFacets
167-
inlines: _ListOrTuple[type[InlineModelAdmin]]
168-
add_form_template: _TemplateForResponseT | None
169-
change_form_template: _TemplateForResponseT | None
170-
change_list_template: _TemplateForResponseT | None
171-
delete_confirmation_template: _TemplateForResponseT | None
172-
delete_selected_confirmation_template: _TemplateForResponseT | None
173-
object_history_template: _TemplateForResponseT | None
174-
popup_response_template: _TemplateForResponseT | None
155+
list_filter: ClassVar[_ListOrTuple[_ListFilterT]]
156+
list_select_related: ClassVar[bool | _ListOrTuple[str]]
157+
list_per_page: ClassVar[int]
158+
list_max_show_all: ClassVar[int]
159+
list_editable: ClassVar[_ListOrTuple[str]]
160+
search_fields: ClassVar[_ListOrTuple[str]]
161+
search_help_text: ClassVar[_StrOrPromise | None]
162+
date_hierarchy: ClassVar[str | None]
163+
save_as: ClassVar[bool]
164+
save_as_continue: ClassVar[bool]
165+
save_on_top: ClassVar[bool]
166+
paginator: ClassVar[type]
167+
preserve_filters: ClassVar[bool]
168+
show_facets: ClassVar[ShowFacets]
169+
inlines: ClassVar[_ListOrTuple[type[InlineModelAdmin]]]
170+
add_form_template: ClassVar[_TemplateForResponseT | None]
171+
change_form_template: ClassVar[_TemplateForResponseT | None]
172+
change_list_template: ClassVar[_TemplateForResponseT | None]
173+
delete_confirmation_template: ClassVar[_TemplateForResponseT | None]
174+
delete_selected_confirmation_template: ClassVar[_TemplateForResponseT | None]
175+
object_history_template: ClassVar[_TemplateForResponseT | None]
176+
popup_response_template: ClassVar[_TemplateForResponseT | None]
175177
actions: Sequence[_ActionCallable[Self, _ModelT] | str] | None
176-
action_form: Any
177-
actions_on_top: bool
178-
actions_on_bottom: bool
179-
actions_selection_counter: bool
178+
action_form: ClassVar[Any]
179+
actions_on_top: ClassVar[bool]
180+
actions_on_bottom: ClassVar[bool]
181+
actions_selection_counter: ClassVar[bool]
180182
model: type[_ModelT]
181183
opts: Options[_ModelT]
182184
admin_site: AdminSite
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
from typing import Any
1+
from typing import Any, ClassVar
22

33
from django.contrib import admin
44
from django.contrib.flatpages.models import FlatPage
55

66
class FlatPageAdmin(admin.ModelAdmin[FlatPage]):
77
form: Any
8-
fieldsets: Any
8+
fieldsets: ClassVar[Any]
99
list_display: Any
10-
list_filter: Any
11-
search_fields: Any
10+
list_filter: ClassVar[Any]
11+
search_fields: ClassVar[Any]

django-stubs/contrib/gis/db/models/fields.pyi

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ class GeometryField(BaseSpatialField[_ST, _GT]):
121121
srid: Any = ...,
122122
**kwargs: Any,
123123
) -> forms.GeometryField: ...
124-
def select_format(self, compiler: Any, sql: Any, params: Any) -> Any: ...
125124

126125
class PointField(GeometryField[_ST, _GT]):
127126
_pyi_private_set_type: Point | Combinable
@@ -181,7 +180,6 @@ class GeometryCollectionField(GeometryField[_ST, _GT]):
181180

182181
class ExtentField(Field):
183182
def get_internal_type(self) -> Any: ...
184-
def select_format(self, compiler: Any, sql: Any, params: Any) -> Any: ...
185183

186184
class RasterField(BaseSpatialField):
187185
def db_type(self, connection: Any) -> Any: ...

django-stubs/contrib/gis/db/models/functions.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ from django.utils.functional import cached_property
1111
NUMERIC_TYPES: Any
1212

1313
class GeoFuncMixin:
14+
function: str | None = None
1415
geom_param_pos: Any
1516
@property
1617
def geo_field(self) -> Any: ...

django-stubs/contrib/postgres/operations.pyi

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
from typing import Literal
2-
31
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
42
from django.db.migrations import AddConstraint, AddIndex, RemoveIndex
53
from django.db.migrations.operations.base import Operation
64

75
class CreateExtension(Operation):
8-
reversible: bool
96
name: str
107
def __init__(self, name: str) -> None: ...
118
def extension_exists(self, schema_editor: BaseDatabaseSchemaEditor, extension: str) -> bool: ...
@@ -37,11 +34,8 @@ class UnaccentExtension(CreateExtension):
3734
class NotInTransactionMixin:
3835
def _ensure_not_in_transaction(self, schema_editor: BaseDatabaseSchemaEditor) -> None: ...
3936

40-
class AddIndexConcurrently(NotInTransactionMixin, AddIndex):
41-
atomic: Literal[False]
42-
43-
class RemoveIndexConcurrently(NotInTransactionMixin, RemoveIndex):
44-
atomic: Literal[False]
37+
class AddIndexConcurrently(NotInTransactionMixin, AddIndex): ...
38+
class RemoveIndexConcurrently(NotInTransactionMixin, RemoveIndex): ...
4539

4640
class CollationOperation(Operation):
4741
name: str

0 commit comments

Comments
 (0)