plain.models 0.49.1__py3-none-any.whl → 0.50.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. plain/models/CHANGELOG.md +23 -0
  2. plain/models/aggregates.py +42 -19
  3. plain/models/backends/base/base.py +125 -105
  4. plain/models/backends/base/client.py +11 -3
  5. plain/models/backends/base/creation.py +22 -12
  6. plain/models/backends/base/features.py +10 -4
  7. plain/models/backends/base/introspection.py +29 -16
  8. plain/models/backends/base/operations.py +187 -91
  9. plain/models/backends/base/schema.py +267 -165
  10. plain/models/backends/base/validation.py +12 -3
  11. plain/models/backends/ddl_references.py +85 -43
  12. plain/models/backends/mysql/base.py +29 -26
  13. plain/models/backends/mysql/client.py +7 -2
  14. plain/models/backends/mysql/compiler.py +12 -3
  15. plain/models/backends/mysql/creation.py +5 -2
  16. plain/models/backends/mysql/features.py +24 -22
  17. plain/models/backends/mysql/introspection.py +22 -13
  18. plain/models/backends/mysql/operations.py +106 -39
  19. plain/models/backends/mysql/schema.py +48 -24
  20. plain/models/backends/mysql/validation.py +13 -6
  21. plain/models/backends/postgresql/base.py +41 -34
  22. plain/models/backends/postgresql/client.py +7 -2
  23. plain/models/backends/postgresql/creation.py +10 -5
  24. plain/models/backends/postgresql/introspection.py +15 -8
  25. plain/models/backends/postgresql/operations.py +109 -42
  26. plain/models/backends/postgresql/schema.py +85 -46
  27. plain/models/backends/sqlite3/_functions.py +151 -115
  28. plain/models/backends/sqlite3/base.py +37 -23
  29. plain/models/backends/sqlite3/client.py +7 -1
  30. plain/models/backends/sqlite3/creation.py +9 -5
  31. plain/models/backends/sqlite3/features.py +5 -3
  32. plain/models/backends/sqlite3/introspection.py +32 -16
  33. plain/models/backends/sqlite3/operations.py +125 -42
  34. plain/models/backends/sqlite3/schema.py +82 -58
  35. plain/models/backends/utils.py +52 -29
  36. plain/models/backups/cli.py +8 -6
  37. plain/models/backups/clients.py +16 -7
  38. plain/models/backups/core.py +24 -13
  39. plain/models/base.py +113 -74
  40. plain/models/cli.py +94 -63
  41. plain/models/config.py +1 -1
  42. plain/models/connections.py +23 -7
  43. plain/models/constraints.py +65 -47
  44. plain/models/database_url.py +1 -1
  45. plain/models/db.py +6 -2
  46. plain/models/deletion.py +66 -43
  47. plain/models/entrypoints.py +1 -1
  48. plain/models/enums.py +22 -11
  49. plain/models/exceptions.py +23 -8
  50. plain/models/expressions.py +440 -257
  51. plain/models/fields/__init__.py +253 -202
  52. plain/models/fields/json.py +120 -54
  53. plain/models/fields/mixins.py +12 -8
  54. plain/models/fields/related.py +284 -252
  55. plain/models/fields/related_descriptors.py +34 -25
  56. plain/models/fields/related_lookups.py +23 -11
  57. plain/models/fields/related_managers.py +81 -47
  58. plain/models/fields/reverse_related.py +58 -55
  59. plain/models/forms.py +89 -63
  60. plain/models/functions/comparison.py +71 -18
  61. plain/models/functions/datetime.py +79 -29
  62. plain/models/functions/math.py +43 -10
  63. plain/models/functions/mixins.py +24 -7
  64. plain/models/functions/text.py +104 -25
  65. plain/models/functions/window.py +12 -6
  66. plain/models/indexes.py +52 -28
  67. plain/models/lookups.py +228 -153
  68. plain/models/migrations/autodetector.py +86 -43
  69. plain/models/migrations/exceptions.py +7 -3
  70. plain/models/migrations/executor.py +33 -7
  71. plain/models/migrations/graph.py +79 -50
  72. plain/models/migrations/loader.py +45 -22
  73. plain/models/migrations/migration.py +23 -18
  74. plain/models/migrations/operations/base.py +37 -19
  75. plain/models/migrations/operations/fields.py +89 -42
  76. plain/models/migrations/operations/models.py +245 -143
  77. plain/models/migrations/operations/special.py +82 -25
  78. plain/models/migrations/optimizer.py +7 -2
  79. plain/models/migrations/questioner.py +58 -31
  80. plain/models/migrations/recorder.py +18 -11
  81. plain/models/migrations/serializer.py +50 -39
  82. plain/models/migrations/state.py +220 -133
  83. plain/models/migrations/utils.py +29 -13
  84. plain/models/migrations/writer.py +17 -14
  85. plain/models/options.py +63 -56
  86. plain/models/otel.py +16 -6
  87. plain/models/preflight.py +35 -12
  88. plain/models/query.py +323 -228
  89. plain/models/query_utils.py +93 -58
  90. plain/models/registry.py +34 -16
  91. plain/models/sql/compiler.py +146 -97
  92. plain/models/sql/datastructures.py +38 -25
  93. plain/models/sql/query.py +255 -169
  94. plain/models/sql/subqueries.py +32 -21
  95. plain/models/sql/where.py +54 -29
  96. plain/models/test/pytest.py +15 -11
  97. plain/models/test/utils.py +4 -2
  98. plain/models/transaction.py +20 -7
  99. plain/models/utils.py +13 -5
  100. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/METADATA +1 -1
  101. plain_models-0.50.0.dist-info/RECORD +122 -0
  102. plain_models-0.49.1.dist-info/RECORD +0 -122
  103. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/WHEEL +0 -0
  104. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/entry_points.txt +0 -0
  105. {plain_models-0.49.1.dist-info → plain_models-0.50.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import collections.abc
2
4
  import copy
3
5
  import datetime
@@ -7,7 +9,9 @@ import operator
7
9
  import uuid
8
10
  import warnings
9
11
  from base64 import b64decode, b64encode
12
+ from collections.abc import Callable, Sequence
10
13
  from functools import cached_property, total_ordering
14
+ from typing import TYPE_CHECKING, Any
11
15
 
12
16
  from plain import exceptions, validators
13
17
  from plain.models.constants import LOOKUP_SEP
@@ -30,6 +34,10 @@ from plain.utils.itercompat import is_iterable
30
34
 
31
35
  from ..registry import models_registry
32
36
 
37
+ if TYPE_CHECKING:
38
+ from plain.models.backends.base.base import BaseDatabaseWrapper
39
+ from plain.models.sql.compiler import SQLCompiler
40
+
33
41
  __all__ = [
34
42
  "BLANK_CHOICE_DASH",
35
43
  "PrimaryKeyField",
@@ -72,7 +80,7 @@ class NOT_PROVIDED:
72
80
  BLANK_CHOICE_DASH = [("", "---------")]
73
81
 
74
82
 
75
- def _load_field(package_label, model_name, field_name):
83
+ def _load_field(package_label: str, model_name: str, field_name: str) -> Field:
76
84
  return models_registry.get_model(package_label, model_name)._meta.get_field(
77
85
  field_name
78
86
  )
@@ -92,13 +100,13 @@ def _load_field(package_label, model_name, field_name):
92
100
  # attname.
93
101
 
94
102
 
95
- def _empty(of_cls):
103
+ def _empty(of_cls: type) -> Empty:
96
104
  new = Empty()
97
105
  new.__class__ = of_cls
98
106
  return new
99
107
 
100
108
 
101
- def return_None():
109
+ def return_None() -> None:
102
110
  return None
103
111
 
104
112
 
@@ -150,7 +158,7 @@ class Field(RegisterLookupMixin):
150
158
  descriptor_class = DeferredAttribute
151
159
 
152
160
  # Generic field type description, usually overridden by subclasses
153
- def _description(self):
161
+ def _description(self) -> str:
154
162
  return f"Field of type: {self.__class__.__name__}"
155
163
 
156
164
  description = property(_description)
@@ -158,16 +166,16 @@ class Field(RegisterLookupMixin):
158
166
  def __init__(
159
167
  self,
160
168
  *,
161
- max_length=None,
162
- required=True,
163
- allow_null=False,
164
- rel=None,
165
- default=NOT_PROVIDED,
166
- choices=None,
167
- db_column=None,
168
- validators=(),
169
- error_messages=None,
170
- db_comment=None,
169
+ max_length: int | None = None,
170
+ required: bool = True,
171
+ allow_null: bool = False,
172
+ rel: Any = None,
173
+ default: Any = NOT_PROVIDED,
174
+ choices: Any = None,
175
+ db_column: str | None = None,
176
+ validators: Sequence[Callable[..., Any]] = (),
177
+ error_messages: dict[str, str] | None = None,
178
+ db_comment: str | None = None,
171
179
  ):
172
180
  self.name = None # Set by set_attributes_from_name
173
181
  self.max_length = max_length
@@ -196,7 +204,7 @@ class Field(RegisterLookupMixin):
196
204
 
197
205
  self._error_messages = error_messages # Store for deconstruction later
198
206
 
199
- def __str__(self):
207
+ def __str__(self) -> str:
200
208
  """
201
209
  Return "package_label.model_label.field_name" for fields attached to
202
210
  models.
@@ -206,7 +214,7 @@ class Field(RegisterLookupMixin):
206
214
  model = self.model
207
215
  return f"{model._meta.label}.{self.name}"
208
216
 
209
- def __repr__(self):
217
+ def __repr__(self) -> str:
210
218
  """Display the module, class, and name of the field."""
211
219
  path = f"{self.__class__.__module__}.{self.__class__.__qualname__}"
212
220
  name = getattr(self, "name", None)
@@ -214,7 +222,7 @@ class Field(RegisterLookupMixin):
214
222
  return f"<{path}: {name}>"
215
223
  return f"<{path}>"
216
224
 
217
- def preflight(self, **kwargs):
225
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]:
218
226
  return [
219
227
  *self._check_field_name(),
220
228
  *self._check_choices(),
@@ -224,7 +232,7 @@ class Field(RegisterLookupMixin):
224
232
  *self._check_validators(),
225
233
  ]
226
234
 
227
- def _check_field_name(self):
235
+ def _check_field_name(self) -> list[PreflightResult]:
228
236
  """
229
237
  Check if field name is valid, i.e. 1) does not end with an
230
238
  underscore, 2) does not contain "__" and 3) is not "id".
@@ -257,10 +265,10 @@ class Field(RegisterLookupMixin):
257
265
  return []
258
266
 
259
267
  @classmethod
260
- def _choices_is_value(cls, value):
268
+ def _choices_is_value(cls, value: Any) -> bool:
261
269
  return isinstance(value, str | Promise) or not is_iterable(value)
262
270
 
263
- def _check_choices(self):
271
+ def _check_choices(self) -> list[PreflightResult]:
264
272
  if not self.choices:
265
273
  return []
266
274
 
@@ -332,7 +340,7 @@ class Field(RegisterLookupMixin):
332
340
  )
333
341
  ]
334
342
 
335
- def _check_db_comment(self):
343
+ def _check_db_comment(self) -> list[PreflightResult]:
336
344
  if not self.db_comment:
337
345
  return []
338
346
  errors = []
@@ -351,7 +359,7 @@ class Field(RegisterLookupMixin):
351
359
  )
352
360
  return errors
353
361
 
354
- def _check_null_allowed_for_primary_keys(self):
362
+ def _check_null_allowed_for_primary_keys(self) -> list[PreflightResult]:
355
363
  if self.primary_key and self.allow_null:
356
364
  # We cannot reliably check this for backends like Oracle which
357
365
  # consider NULL and '' to be equal (and thus set up
@@ -368,12 +376,12 @@ class Field(RegisterLookupMixin):
368
376
  else:
369
377
  return []
370
378
 
371
- def _check_backend_specific_checks(self):
379
+ def _check_backend_specific_checks(self) -> list[PreflightResult]:
372
380
  errors = []
373
381
  errors.extend(db_connection.validation.check_field(self))
374
382
  return errors
375
383
 
376
- def _check_validators(self):
384
+ def _check_validators(self) -> list[PreflightResult]:
377
385
  errors = []
378
386
  for i, validator in enumerate(self.validators):
379
387
  if not callable(validator):
@@ -390,7 +398,7 @@ class Field(RegisterLookupMixin):
390
398
  )
391
399
  return errors
392
400
 
393
- def get_col(self, alias, output_field=None):
401
+ def get_col(self, alias: str, output_field: Field | None = None) -> Any:
394
402
  if alias == self.model._meta.db_table and (
395
403
  output_field is None or output_field == self
396
404
  ):
@@ -400,12 +408,14 @@ class Field(RegisterLookupMixin):
400
408
  return Col(alias, self, output_field)
401
409
 
402
410
  @cached_property
403
- def cached_col(self):
411
+ def cached_col(self) -> Any:
404
412
  from plain.models.expressions import Col
405
413
 
406
414
  return Col(self.model._meta.db_table, self)
407
415
 
408
- def select_format(self, compiler, sql, params):
416
+ def select_format(
417
+ self, compiler: SQLCompiler, sql: str, params: Any
418
+ ) -> tuple[str, Any]:
409
419
  """
410
420
  Custom format for select clauses. For example, GIS columns need to be
411
421
  selected as AsText(table.col) on MySQL as the table.col data can't be
@@ -413,7 +423,7 @@ class Field(RegisterLookupMixin):
413
423
  """
414
424
  return sql, params
415
425
 
416
- def deconstruct(self):
426
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
417
427
  """
418
428
  Return enough information to recreate the field as a 4-tuple:
419
429
 
@@ -488,7 +498,7 @@ class Field(RegisterLookupMixin):
488
498
  # Return basic info - other fields should override this.
489
499
  return (self.name, path, [], keywords)
490
500
 
491
- def clone(self):
501
+ def clone(self) -> Field:
492
502
  """
493
503
  Uses deconstruct() to clone a new copy of this Field.
494
504
  Will not preserve any class attachments/attribute names.
@@ -496,7 +506,7 @@ class Field(RegisterLookupMixin):
496
506
  name, path, args, kwargs = self.deconstruct()
497
507
  return self.__class__(*args, **kwargs)
498
508
 
499
- def __eq__(self, other):
509
+ def __eq__(self, other: object) -> bool:
500
510
  # Needed for @total_ordering
501
511
  if isinstance(other, Field):
502
512
  return self.creation_counter == other.creation_counter and getattr(
@@ -504,7 +514,7 @@ class Field(RegisterLookupMixin):
504
514
  ) == getattr(other, "model", None)
505
515
  return NotImplemented
506
516
 
507
- def __lt__(self, other):
517
+ def __lt__(self, other: object) -> bool:
508
518
  # This is needed because bisect does not take a comparison function.
509
519
  # Order by creation_counter first for backward compatibility.
510
520
  if isinstance(other, Field):
@@ -524,10 +534,10 @@ class Field(RegisterLookupMixin):
524
534
  )
525
535
  return NotImplemented
526
536
 
527
- def __hash__(self):
537
+ def __hash__(self) -> int:
528
538
  return hash(self.creation_counter)
529
539
 
530
- def __deepcopy__(self, memodict):
540
+ def __deepcopy__(self, memodict: dict[int, Any]) -> Field:
531
541
  # We don't have to deepcopy very much here, since most things are not
532
542
  # intended to be altered after initial creation.
533
543
  obj = copy.copy(self)
@@ -538,15 +548,20 @@ class Field(RegisterLookupMixin):
538
548
  memodict[id(self)] = obj
539
549
  return obj
540
550
 
541
- def __copy__(self):
551
+ def __copy__(self) -> Field:
542
552
  # We need to avoid hitting __reduce__, so define this
543
553
  # slightly weird copy construct.
544
554
  obj = Empty()
545
555
  obj.__class__ = self.__class__
546
556
  obj.__dict__ = self.__dict__.copy()
547
- return obj
557
+ return obj # type: ignore[return-value]
548
558
 
549
- def __reduce__(self):
559
+ def __reduce__(
560
+ self,
561
+ ) -> (
562
+ tuple[Callable[..., Any], tuple[Any, ...], dict[str, Any]]
563
+ | tuple[Callable[..., Field], tuple[str, str, str]]
564
+ ):
550
565
  """
551
566
  Pickling should return the model._meta.fields instance of the field,
552
567
  not a new copy of that field. So, use the app registry to load the
@@ -569,7 +584,7 @@ class Field(RegisterLookupMixin):
569
584
  self.name,
570
585
  )
571
586
 
572
- def get_id_value_on_save(self, instance):
587
+ def get_id_value_on_save(self, instance: Any) -> Any:
573
588
  """
574
589
  Hook to generate new primary key values on save. This method is called when
575
590
  saving instances with no primary key value set. If this method returns
@@ -580,7 +595,7 @@ class Field(RegisterLookupMixin):
580
595
  return self.get_default()
581
596
  return None
582
597
 
583
- def to_python(self, value):
598
+ def to_python(self, value: Any) -> Any:
584
599
  """
585
600
  Convert the input value into the expected Python data type, raising
586
601
  plain.exceptions.ValidationError if the data can't be converted.
@@ -589,7 +604,7 @@ class Field(RegisterLookupMixin):
589
604
  return value
590
605
 
591
606
  @cached_property
592
- def error_messages(self):
607
+ def error_messages(self) -> dict[str, str]:
593
608
  messages = {}
594
609
  for c in reversed(self.__class__.__mro__):
595
610
  messages.update(getattr(c, "default_error_messages", {}))
@@ -597,14 +612,14 @@ class Field(RegisterLookupMixin):
597
612
  return messages
598
613
 
599
614
  @cached_property
600
- def validators(self):
615
+ def validators(self) -> list[Callable[..., Any]]:
601
616
  """
602
617
  Some validators can't be created at field initialization time.
603
618
  This method provides a way to delay their creation until required.
604
619
  """
605
620
  return [*self.default_validators, *self._validators]
606
621
 
607
- def run_validators(self, value):
622
+ def run_validators(self, value: Any) -> None:
608
623
  if value in self.empty_values:
609
624
  return
610
625
 
@@ -620,7 +635,7 @@ class Field(RegisterLookupMixin):
620
635
  if errors:
621
636
  raise exceptions.ValidationError(errors)
622
637
 
623
- def validate(self, value, model_instance):
638
+ def validate(self, value: Any, model_instance: Any) -> None:
624
639
  """
625
640
  Validate value and raise ValidationError if necessary. Subclasses
626
641
  should override this to provide validation logic.
@@ -652,7 +667,7 @@ class Field(RegisterLookupMixin):
652
667
  self.error_messages["required"], code="required"
653
668
  )
654
669
 
655
- def clean(self, value, model_instance):
670
+ def clean(self, value: Any, model_instance: Any) -> Any:
656
671
  """
657
672
  Convert the value's type and run validation. Validation errors
658
673
  from to_python() and validate() are propagated. Return the correct
@@ -663,10 +678,10 @@ class Field(RegisterLookupMixin):
663
678
  self.run_validators(value)
664
679
  return value
665
680
 
666
- def db_type_parameters(self, connection):
681
+ def db_type_parameters(self, connection: BaseDatabaseWrapper) -> DictWrapper:
667
682
  return DictWrapper(self.__dict__, connection.ops.quote_name, "qn_")
668
683
 
669
- def db_check(self, connection):
684
+ def db_check(self, connection: BaseDatabaseWrapper) -> str | None:
670
685
  """
671
686
  Return the database column check constraint for this field, for the
672
687
  provided connection. Works the same way as db_type() for the case that
@@ -680,7 +695,7 @@ class Field(RegisterLookupMixin):
680
695
  except KeyError:
681
696
  return None
682
697
 
683
- def db_type(self, connection):
698
+ def db_type(self, connection: BaseDatabaseWrapper) -> str | None:
684
699
  """
685
700
  Return the database column data type for this field, for the provided
686
701
  connection.
@@ -711,21 +726,21 @@ class Field(RegisterLookupMixin):
711
726
  return column_type(data)
712
727
  return column_type % data
713
728
 
714
- def rel_db_type(self, connection):
729
+ def rel_db_type(self, connection: BaseDatabaseWrapper) -> str | None:
715
730
  """
716
731
  Return the data type that a related field pointing to this field should
717
732
  use. For example, this method is called by ForeignKey to determine its data type.
718
733
  """
719
734
  return self.db_type(connection)
720
735
 
721
- def cast_db_type(self, connection):
736
+ def cast_db_type(self, connection: BaseDatabaseWrapper) -> str | None:
722
737
  """Return the data type to use in the Cast() function."""
723
738
  db_type = connection.ops.cast_data_types.get(self.get_internal_type())
724
739
  if db_type:
725
740
  return db_type % self.db_type_parameters(connection)
726
741
  return self.db_type(connection)
727
742
 
728
- def db_parameters(self, connection):
743
+ def db_parameters(self, connection: BaseDatabaseWrapper) -> dict[str, Any]:
729
744
  """
730
745
  Extension of db_type(), providing a range of different return values
731
746
  (type, checks). This will look at db_type(), allowing custom model
@@ -738,28 +753,30 @@ class Field(RegisterLookupMixin):
738
753
  "check": check_string,
739
754
  }
740
755
 
741
- def db_type_suffix(self, connection):
756
+ def db_type_suffix(self, connection: BaseDatabaseWrapper) -> str | None:
742
757
  return connection.data_types_suffix.get(self.get_internal_type())
743
758
 
744
- def get_db_converters(self, connection):
759
+ def get_db_converters(
760
+ self, connection: BaseDatabaseWrapper
761
+ ) -> list[Callable[..., Any]]:
745
762
  if hasattr(self, "from_db_value"):
746
763
  return [self.from_db_value]
747
764
  return []
748
765
 
749
766
  @property
750
- def db_returning(self):
767
+ def db_returning(self) -> bool:
751
768
  """
752
769
  Private API intended only to be used by Plain itself. Currently only
753
770
  the PostgreSQL backend supports returning multiple fields on a model.
754
771
  """
755
772
  return False
756
773
 
757
- def set_attributes_from_name(self, name):
774
+ def set_attributes_from_name(self, name: str) -> None:
758
775
  self.name = self.name or name
759
776
  self.attname, self.column = self.get_attname_column()
760
777
  self.concrete = self.column is not None
761
778
 
762
- def contribute_to_class(self, cls, name):
779
+ def contribute_to_class(self, cls: Any, name: str) -> None:
763
780
  """
764
781
  Register the field with the model class it belongs to.
765
782
  """
@@ -769,28 +786,30 @@ class Field(RegisterLookupMixin):
769
786
  if self.column:
770
787
  setattr(cls, self.attname, self.descriptor_class(self))
771
788
 
772
- def get_attname(self):
789
+ def get_attname(self) -> str:
773
790
  return self.name
774
791
 
775
- def get_attname_column(self):
792
+ def get_attname_column(self) -> tuple[str, str]:
776
793
  attname = self.get_attname()
777
794
  column = self.db_column or attname
778
795
  return attname, column
779
796
 
780
- def get_internal_type(self):
797
+ def get_internal_type(self) -> str:
781
798
  return self.__class__.__name__
782
799
 
783
- def pre_save(self, model_instance, add):
800
+ def pre_save(self, model_instance: Any, add: bool) -> Any:
784
801
  """Return field's value just before saving."""
785
802
  return getattr(model_instance, self.attname)
786
803
 
787
- def get_prep_value(self, value):
804
+ def get_prep_value(self, value: Any) -> Any:
788
805
  """Perform preliminary non-db specific value checks and conversions."""
789
806
  if isinstance(value, Promise):
790
807
  value = value._proxy____cast()
791
808
  return value
792
809
 
793
- def get_db_prep_value(self, value, connection, prepared=False):
810
+ def get_db_prep_value(
811
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
812
+ ) -> Any:
794
813
  """
795
814
  Return field's value prepared for interacting with the database backend.
796
815
 
@@ -800,22 +819,22 @@ class Field(RegisterLookupMixin):
800
819
  value = self.get_prep_value(value)
801
820
  return value
802
821
 
803
- def get_db_prep_save(self, value, connection):
822
+ def get_db_prep_save(self, value: Any, connection: BaseDatabaseWrapper) -> Any:
804
823
  """Return field's value prepared for saving into a database."""
805
824
  if hasattr(value, "as_sql"):
806
825
  return value
807
826
  return self.get_db_prep_value(value, connection=connection, prepared=False)
808
827
 
809
- def has_default(self):
828
+ def has_default(self) -> bool:
810
829
  """Return a boolean of whether this field has a default value."""
811
830
  return self.default is not NOT_PROVIDED
812
831
 
813
- def get_default(self):
832
+ def get_default(self) -> Any:
814
833
  """Return the default value for this field."""
815
834
  return self._get_default()
816
835
 
817
836
  @cached_property
818
- def _get_default(self):
837
+ def _get_default(self) -> Callable[[], Any]:
819
838
  if self.has_default():
820
839
  if callable(self.default):
821
840
  return self.default
@@ -827,11 +846,11 @@ class Field(RegisterLookupMixin):
827
846
 
828
847
  def get_choices(
829
848
  self,
830
- include_blank=True,
831
- blank_choice=BLANK_CHOICE_DASH,
832
- limit_choices_to=None,
833
- ordering=(),
834
- ):
849
+ include_blank: bool = True,
850
+ blank_choice: list[tuple[str, str]] = BLANK_CHOICE_DASH,
851
+ limit_choices_to: Any = None,
852
+ ordering: tuple[str, ...] = (),
853
+ ) -> list[tuple[Any, str]]:
835
854
  """
836
855
  Return choices with a default blank choices included, for use
837
856
  as <select> choices for this field.
@@ -859,14 +878,14 @@ class Field(RegisterLookupMixin):
859
878
  (choice_func(x), str(x)) for x in qs
860
879
  ]
861
880
 
862
- def value_to_string(self, obj):
881
+ def value_to_string(self, obj: Any) -> str:
863
882
  """
864
883
  Return a string value of this field from the passed obj.
865
884
  This is used by the serialization framework.
866
885
  """
867
886
  return str(self.value_from_object(obj))
868
887
 
869
- def _get_flatchoices(self):
888
+ def _get_flatchoices(self) -> list[tuple[Any, Any]]:
870
889
  """Flattened version of choices tuple."""
871
890
  if self.choices is None:
872
891
  return []
@@ -880,10 +899,10 @@ class Field(RegisterLookupMixin):
880
899
 
881
900
  flatchoices = property(_get_flatchoices)
882
901
 
883
- def save_form_data(self, instance, data):
902
+ def save_form_data(self, instance: Any, data: Any) -> None:
884
903
  setattr(instance, self.name, data)
885
904
 
886
- def value_from_object(self, obj):
905
+ def value_from_object(self, obj: Any) -> Any:
887
906
  """Return the value of this field in the given model instance."""
888
907
  return getattr(obj, self.attname)
889
908
 
@@ -896,10 +915,10 @@ class BooleanField(Field):
896
915
  }
897
916
  description = "Boolean (Either True or False)"
898
917
 
899
- def get_internal_type(self):
918
+ def get_internal_type(self) -> str:
900
919
  return "BooleanField"
901
920
 
902
- def to_python(self, value):
921
+ def to_python(self, value: Any) -> Any:
903
922
  if self.allow_null and value in self.empty_values:
904
923
  return None
905
924
  if value in (True, False):
@@ -915,7 +934,7 @@ class BooleanField(Field):
915
934
  params={"value": value},
916
935
  )
917
936
 
918
- def get_prep_value(self, value):
937
+ def get_prep_value(self, value: Any) -> Any:
919
938
  value = super().get_prep_value(value)
920
939
  if value is None:
921
940
  return None
@@ -923,27 +942,27 @@ class BooleanField(Field):
923
942
 
924
943
 
925
944
  class CharField(Field):
926
- def __init__(self, *, db_collation=None, **kwargs):
945
+ def __init__(self, *, db_collation: str | None = None, **kwargs: Any):
927
946
  super().__init__(**kwargs)
928
947
  self.db_collation = db_collation
929
948
  if self.max_length is not None:
930
949
  self.validators.append(validators.MaxLengthValidator(self.max_length))
931
950
 
932
951
  @property
933
- def description(self):
952
+ def description(self) -> str:
934
953
  if self.max_length is not None:
935
954
  return "String (up to %(max_length)s)"
936
955
  else:
937
956
  return "String (unlimited)"
938
957
 
939
- def preflight(self, **kwargs):
958
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]:
940
959
  return [
941
960
  *super().preflight(**kwargs),
942
961
  *self._check_db_collation(),
943
962
  *self._check_max_length_attribute(),
944
963
  ]
945
964
 
946
- def _check_max_length_attribute(self, **kwargs):
965
+ def _check_max_length_attribute(self, **kwargs: Any) -> list[PreflightResult]:
947
966
  if self.max_length is None:
948
967
  if (
949
968
  db_connection.features.supports_unlimited_charfield
@@ -973,7 +992,7 @@ class CharField(Field):
973
992
  else:
974
993
  return []
975
994
 
976
- def _check_db_collation(self):
995
+ def _check_db_collation(self) -> list[PreflightResult]:
977
996
  errors = []
978
997
  if not (
979
998
  self.db_collation is None
@@ -991,61 +1010,61 @@ class CharField(Field):
991
1010
  )
992
1011
  return errors
993
1012
 
994
- def cast_db_type(self, connection):
1013
+ def cast_db_type(self, connection: BaseDatabaseWrapper) -> str | None:
995
1014
  if self.max_length is None:
996
1015
  return connection.ops.cast_char_field_without_max_length
997
1016
  return super().cast_db_type(connection)
998
1017
 
999
- def db_parameters(self, connection):
1018
+ def db_parameters(self, connection: BaseDatabaseWrapper) -> dict[str, Any]:
1000
1019
  db_params = super().db_parameters(connection)
1001
1020
  db_params["collation"] = self.db_collation
1002
1021
  return db_params
1003
1022
 
1004
- def get_internal_type(self):
1023
+ def get_internal_type(self) -> str:
1005
1024
  return "CharField"
1006
1025
 
1007
- def to_python(self, value):
1026
+ def to_python(self, value: Any) -> Any:
1008
1027
  if isinstance(value, str) or value is None:
1009
1028
  return value
1010
1029
  return str(value)
1011
1030
 
1012
- def get_prep_value(self, value):
1031
+ def get_prep_value(self, value: Any) -> Any:
1013
1032
  value = super().get_prep_value(value)
1014
1033
  return self.to_python(value)
1015
1034
 
1016
- def deconstruct(self):
1035
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1017
1036
  name, path, args, kwargs = super().deconstruct()
1018
1037
  if self.db_collation:
1019
1038
  kwargs["db_collation"] = self.db_collation
1020
1039
  return name, path, args, kwargs
1021
1040
 
1022
1041
 
1023
- def _to_naive(value):
1042
+ def _to_naive(value: datetime.datetime) -> datetime.datetime:
1024
1043
  if timezone.is_aware(value):
1025
1044
  value = timezone.make_naive(value, datetime.UTC)
1026
1045
  return value
1027
1046
 
1028
1047
 
1029
- def _get_naive_now():
1048
+ def _get_naive_now() -> datetime.datetime:
1030
1049
  return _to_naive(timezone.now())
1031
1050
 
1032
1051
 
1033
1052
  class DateTimeCheckMixin:
1034
- def preflight(self, **kwargs):
1053
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]: # type: ignore[misc]
1035
1054
  return [
1036
- *super().preflight(**kwargs),
1055
+ *super().preflight(**kwargs), # type: ignore[misc]
1037
1056
  *self._check_mutually_exclusive_options(),
1038
1057
  *self._check_fix_default_value(),
1039
1058
  ]
1040
1059
 
1041
- def _check_mutually_exclusive_options(self):
1060
+ def _check_mutually_exclusive_options(self) -> list[PreflightResult]:
1042
1061
  # auto_now, auto_now_add, and default are mutually exclusive
1043
1062
  # options. The use of more than one of these options together
1044
1063
  # will trigger an Error
1045
1064
  mutually_exclusive_options = [
1046
- self.auto_now_add,
1047
- self.auto_now,
1048
- self.has_default(),
1065
+ self.auto_now_add, # type: ignore[attr-defined]
1066
+ self.auto_now, # type: ignore[attr-defined]
1067
+ self.has_default(), # type: ignore[attr-defined]
1049
1068
  ]
1050
1069
  enabled_options = [
1051
1070
  option not in (None, False) for option in mutually_exclusive_options
@@ -1063,12 +1082,16 @@ class DateTimeCheckMixin:
1063
1082
  else:
1064
1083
  return []
1065
1084
 
1066
- def _check_fix_default_value(self):
1085
+ def _check_fix_default_value(self) -> list[PreflightResult]:
1067
1086
  return []
1068
1087
 
1069
1088
  # Concrete subclasses use this in their implementations of
1070
1089
  # _check_fix_default_value().
1071
- def _check_if_value_fixed(self, value, now=None):
1090
+ def _check_if_value_fixed(
1091
+ self,
1092
+ value: datetime.date | datetime.datetime,
1093
+ now: datetime.datetime | None = None,
1094
+ ) -> list[PreflightResult]:
1072
1095
  """
1073
1096
  Check if the given value appears to have been provided as a "fixed"
1074
1097
  time value, and include a warning in the returned list if it does. The
@@ -1110,13 +1133,15 @@ class DateField(DateTimeCheckMixin, Field):
1110
1133
  }
1111
1134
  description = "Date (without time)"
1112
1135
 
1113
- def __init__(self, *, auto_now=False, auto_now_add=False, **kwargs):
1136
+ def __init__(
1137
+ self, *, auto_now: bool = False, auto_now_add: bool = False, **kwargs: Any
1138
+ ):
1114
1139
  self.auto_now, self.auto_now_add = auto_now, auto_now_add
1115
1140
  if auto_now or auto_now_add:
1116
1141
  kwargs["required"] = False
1117
1142
  super().__init__(**kwargs)
1118
1143
 
1119
- def _check_fix_default_value(self):
1144
+ def _check_fix_default_value(self) -> list[PreflightResult]:
1120
1145
  """
1121
1146
  Warn that using an actual date or datetime value is probably wrong;
1122
1147
  it's only evaluated on server startup.
@@ -1135,7 +1160,7 @@ class DateField(DateTimeCheckMixin, Field):
1135
1160
  # At this point, value is a date object.
1136
1161
  return self._check_if_value_fixed(value)
1137
1162
 
1138
- def deconstruct(self):
1163
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1139
1164
  name, path, args, kwargs = super().deconstruct()
1140
1165
  if self.auto_now:
1141
1166
  kwargs["auto_now"] = True
@@ -1145,10 +1170,10 @@ class DateField(DateTimeCheckMixin, Field):
1145
1170
  del kwargs["required"]
1146
1171
  return name, path, args, kwargs
1147
1172
 
1148
- def get_internal_type(self):
1173
+ def get_internal_type(self) -> str:
1149
1174
  return "DateField"
1150
1175
 
1151
- def to_python(self, value):
1176
+ def to_python(self, value: Any) -> Any:
1152
1177
  if value is None:
1153
1178
  return value
1154
1179
  if isinstance(value, datetime.datetime):
@@ -1178,7 +1203,7 @@ class DateField(DateTimeCheckMixin, Field):
1178
1203
  params={"value": value},
1179
1204
  )
1180
1205
 
1181
- def pre_save(self, model_instance, add):
1206
+ def pre_save(self, model_instance: Any, add: bool) -> Any:
1182
1207
  if self.auto_now or (self.auto_now_add and add):
1183
1208
  value = datetime.date.today()
1184
1209
  setattr(model_instance, self.attname, value)
@@ -1186,17 +1211,19 @@ class DateField(DateTimeCheckMixin, Field):
1186
1211
  else:
1187
1212
  return super().pre_save(model_instance, add)
1188
1213
 
1189
- def get_prep_value(self, value):
1214
+ def get_prep_value(self, value: Any) -> Any:
1190
1215
  value = super().get_prep_value(value)
1191
1216
  return self.to_python(value)
1192
1217
 
1193
- def get_db_prep_value(self, value, connection, prepared=False):
1218
+ def get_db_prep_value(
1219
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
1220
+ ) -> Any:
1194
1221
  # Casts dates into the format expected by the backend
1195
1222
  if not prepared:
1196
1223
  value = self.get_prep_value(value)
1197
1224
  return connection.ops.adapt_datefield_value(value)
1198
1225
 
1199
- def value_to_string(self, obj):
1226
+ def value_to_string(self, obj: Any) -> str:
1200
1227
  val = self.value_from_object(obj)
1201
1228
  return "" if val is None else val.isoformat()
1202
1229
 
@@ -1212,7 +1239,7 @@ class DateTimeField(DateField):
1212
1239
 
1213
1240
  # __init__ is inherited from DateField
1214
1241
 
1215
- def _check_fix_default_value(self):
1242
+ def _check_fix_default_value(self) -> list[PreflightResult]:
1216
1243
  """
1217
1244
  Warn that using an actual date or datetime value is probably wrong;
1218
1245
  it's only evaluated on server startup.
@@ -1226,10 +1253,10 @@ class DateTimeField(DateField):
1226
1253
  # No explicit date / datetime value -- no checks necessary.
1227
1254
  return []
1228
1255
 
1229
- def get_internal_type(self):
1256
+ def get_internal_type(self) -> str:
1230
1257
  return "DateTimeField"
1231
1258
 
1232
- def to_python(self, value):
1259
+ def to_python(self, value: Any) -> Any:
1233
1260
  if value is None:
1234
1261
  return value
1235
1262
  if isinstance(value, datetime.datetime):
@@ -1279,7 +1306,7 @@ class DateTimeField(DateField):
1279
1306
  params={"value": value},
1280
1307
  )
1281
1308
 
1282
- def pre_save(self, model_instance, add):
1309
+ def pre_save(self, model_instance: Any, add: bool) -> Any:
1283
1310
  if self.auto_now or (self.auto_now_add and add):
1284
1311
  value = timezone.now()
1285
1312
  setattr(model_instance, self.attname, value)
@@ -1287,7 +1314,7 @@ class DateTimeField(DateField):
1287
1314
  else:
1288
1315
  return super().pre_save(model_instance, add)
1289
1316
 
1290
- def get_prep_value(self, value):
1317
+ def get_prep_value(self, value: Any) -> Any:
1291
1318
  value = super().get_prep_value(value)
1292
1319
  value = self.to_python(value)
1293
1320
  if value is not None and timezone.is_naive(value):
@@ -1307,13 +1334,15 @@ class DateTimeField(DateField):
1307
1334
  value = timezone.make_aware(value, default_timezone)
1308
1335
  return value
1309
1336
 
1310
- def get_db_prep_value(self, value, connection, prepared=False):
1337
+ def get_db_prep_value(
1338
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
1339
+ ) -> Any:
1311
1340
  # Casts datetimes into the format expected by the backend
1312
1341
  if not prepared:
1313
1342
  value = self.get_prep_value(value)
1314
1343
  return connection.ops.adapt_datetimefield_value(value)
1315
1344
 
1316
- def value_to_string(self, obj):
1345
+ def value_to_string(self, obj: Any) -> str:
1317
1346
  val = self.value_from_object(obj)
1318
1347
  return "" if val is None else val.isoformat()
1319
1348
 
@@ -1328,14 +1357,14 @@ class DecimalField(Field):
1328
1357
  def __init__(
1329
1358
  self,
1330
1359
  *,
1331
- max_digits=None,
1332
- decimal_places=None,
1333
- **kwargs,
1360
+ max_digits: int | None = None,
1361
+ decimal_places: int | None = None,
1362
+ **kwargs: Any,
1334
1363
  ):
1335
1364
  self.max_digits, self.decimal_places = max_digits, decimal_places
1336
1365
  super().__init__(**kwargs)
1337
1366
 
1338
- def preflight(self, **kwargs):
1367
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]:
1339
1368
  errors = super().preflight(**kwargs)
1340
1369
 
1341
1370
  digits_errors = [
@@ -1348,7 +1377,7 @@ class DecimalField(Field):
1348
1377
  errors.extend(digits_errors)
1349
1378
  return errors
1350
1379
 
1351
- def _check_decimal_places(self):
1380
+ def _check_decimal_places(self) -> list[PreflightResult]:
1352
1381
  try:
1353
1382
  decimal_places = int(self.decimal_places)
1354
1383
  if decimal_places < 0:
@@ -1372,7 +1401,7 @@ class DecimalField(Field):
1372
1401
  else:
1373
1402
  return []
1374
1403
 
1375
- def _check_max_digits(self):
1404
+ def _check_max_digits(self) -> list[PreflightResult]:
1376
1405
  try:
1377
1406
  max_digits = int(self.max_digits)
1378
1407
  if max_digits <= 0:
@@ -1396,7 +1425,7 @@ class DecimalField(Field):
1396
1425
  else:
1397
1426
  return []
1398
1427
 
1399
- def _check_decimal_places_and_max_digits(self):
1428
+ def _check_decimal_places_and_max_digits(self) -> list[PreflightResult]:
1400
1429
  if int(self.decimal_places) > int(self.max_digits):
1401
1430
  return [
1402
1431
  PreflightResult(
@@ -1408,16 +1437,16 @@ class DecimalField(Field):
1408
1437
  return []
1409
1438
 
1410
1439
  @cached_property
1411
- def validators(self):
1440
+ def validators(self) -> list[Callable[..., Any]]:
1412
1441
  return super().validators + [
1413
1442
  validators.DecimalValidator(self.max_digits, self.decimal_places)
1414
1443
  ]
1415
1444
 
1416
1445
  @cached_property
1417
- def context(self):
1446
+ def context(self) -> decimal.Context:
1418
1447
  return decimal.Context(prec=self.max_digits)
1419
1448
 
1420
- def deconstruct(self):
1449
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1421
1450
  name, path, args, kwargs = super().deconstruct()
1422
1451
  if self.max_digits is not None:
1423
1452
  kwargs["max_digits"] = self.max_digits
@@ -1425,10 +1454,10 @@ class DecimalField(Field):
1425
1454
  kwargs["decimal_places"] = self.decimal_places
1426
1455
  return name, path, args, kwargs
1427
1456
 
1428
- def get_internal_type(self):
1457
+ def get_internal_type(self) -> str:
1429
1458
  return "DecimalField"
1430
1459
 
1431
- def to_python(self, value):
1460
+ def to_python(self, value: Any) -> Any:
1432
1461
  if value is None:
1433
1462
  return value
1434
1463
  try:
@@ -1450,7 +1479,9 @@ class DecimalField(Field):
1450
1479
  )
1451
1480
  return decimal_value
1452
1481
 
1453
- def get_db_prep_value(self, value, connection, prepared=False):
1482
+ def get_db_prep_value(
1483
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
1484
+ ) -> Any:
1454
1485
  if not prepared:
1455
1486
  value = self.get_prep_value(value)
1456
1487
  if hasattr(value, "as_sql"):
@@ -1459,7 +1490,7 @@ class DecimalField(Field):
1459
1490
  value, self.max_digits, self.decimal_places
1460
1491
  )
1461
1492
 
1462
- def get_prep_value(self, value):
1493
+ def get_prep_value(self, value: Any) -> Any:
1463
1494
  value = super().get_prep_value(value)
1464
1495
  return self.to_python(value)
1465
1496
 
@@ -1478,10 +1509,10 @@ class DurationField(Field):
1478
1509
  }
1479
1510
  description = "Duration"
1480
1511
 
1481
- def get_internal_type(self):
1512
+ def get_internal_type(self) -> str:
1482
1513
  return "DurationField"
1483
1514
 
1484
- def to_python(self, value):
1515
+ def to_python(self, value: Any) -> Any:
1485
1516
  if value is None:
1486
1517
  return value
1487
1518
  if isinstance(value, datetime.timedelta):
@@ -1500,20 +1531,24 @@ class DurationField(Field):
1500
1531
  params={"value": value},
1501
1532
  )
1502
1533
 
1503
- def get_db_prep_value(self, value, connection, prepared=False):
1534
+ def get_db_prep_value(
1535
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
1536
+ ) -> Any:
1504
1537
  if connection.features.has_native_duration_field:
1505
1538
  return value
1506
1539
  if value is None:
1507
1540
  return None
1508
1541
  return duration_microseconds(value)
1509
1542
 
1510
- def get_db_converters(self, connection):
1543
+ def get_db_converters(
1544
+ self, connection: BaseDatabaseWrapper
1545
+ ) -> list[Callable[..., Any]]:
1511
1546
  converters = []
1512
1547
  if not connection.features.has_native_duration_field:
1513
1548
  converters.append(connection.ops.convert_durationfield_value)
1514
1549
  return converters + super().get_db_converters(connection)
1515
1550
 
1516
- def value_to_string(self, obj):
1551
+ def value_to_string(self, obj: Any) -> str:
1517
1552
  val = self.value_from_object(obj)
1518
1553
  return "" if val is None else duration_string(val)
1519
1554
 
@@ -1522,12 +1557,12 @@ class EmailField(CharField):
1522
1557
  default_validators = [validators.validate_email]
1523
1558
  description = "Email address"
1524
1559
 
1525
- def __init__(self, **kwargs):
1560
+ def __init__(self, **kwargs: Any):
1526
1561
  # max_length=254 to be compliant with RFCs 3696 and 5321
1527
1562
  kwargs.setdefault("max_length", 254)
1528
1563
  super().__init__(**kwargs)
1529
1564
 
1530
- def deconstruct(self):
1565
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1531
1566
  name, path, args, kwargs = super().deconstruct()
1532
1567
  # We do not exclude max_length if it matches default as we want to change
1533
1568
  # the default in future.
@@ -1541,7 +1576,7 @@ class FloatField(Field):
1541
1576
  }
1542
1577
  description = "Floating point number"
1543
1578
 
1544
- def get_prep_value(self, value):
1579
+ def get_prep_value(self, value: Any) -> Any:
1545
1580
  value = super().get_prep_value(value)
1546
1581
  if value is None:
1547
1582
  return None
@@ -1552,10 +1587,10 @@ class FloatField(Field):
1552
1587
  f"Field '{self.name}' expected a number but got {value!r}.",
1553
1588
  ) from e
1554
1589
 
1555
- def get_internal_type(self):
1590
+ def get_internal_type(self) -> str:
1556
1591
  return "FloatField"
1557
1592
 
1558
- def to_python(self, value):
1593
+ def to_python(self, value: Any) -> Any:
1559
1594
  if value is None:
1560
1595
  return value
1561
1596
  try:
@@ -1575,13 +1610,13 @@ class IntegerField(Field):
1575
1610
  }
1576
1611
  description = "Integer"
1577
1612
 
1578
- def preflight(self, **kwargs):
1613
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]:
1579
1614
  return [
1580
1615
  *super().preflight(**kwargs),
1581
1616
  *self._check_max_length_warning(),
1582
1617
  ]
1583
1618
 
1584
- def _check_max_length_warning(self):
1619
+ def _check_max_length_warning(self) -> list[PreflightResult]:
1585
1620
  if self.max_length is not None:
1586
1621
  return [
1587
1622
  PreflightResult(
@@ -1594,7 +1629,7 @@ class IntegerField(Field):
1594
1629
  return []
1595
1630
 
1596
1631
  @cached_property
1597
- def validators(self):
1632
+ def validators(self) -> list[Callable[..., Any]]:
1598
1633
  # These validators can't be added at field initialization time since
1599
1634
  # they're based on values retrieved from the database connection.
1600
1635
  validators_ = super().validators
@@ -1628,7 +1663,7 @@ class IntegerField(Field):
1628
1663
  validators_.append(validators.MaxValueValidator(max_value))
1629
1664
  return validators_
1630
1665
 
1631
- def get_prep_value(self, value):
1666
+ def get_prep_value(self, value: Any) -> Any:
1632
1667
  value = super().get_prep_value(value)
1633
1668
  if value is None:
1634
1669
  return None
@@ -1639,14 +1674,16 @@ class IntegerField(Field):
1639
1674
  f"Field '{self.name}' expected a number but got {value!r}.",
1640
1675
  ) from e
1641
1676
 
1642
- def get_db_prep_value(self, value, connection, prepared=False):
1677
+ def get_db_prep_value(
1678
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
1679
+ ) -> Any:
1643
1680
  value = super().get_db_prep_value(value, connection, prepared)
1644
1681
  return connection.ops.adapt_integerfield_value(value, self.get_internal_type())
1645
1682
 
1646
- def get_internal_type(self):
1683
+ def get_internal_type(self) -> str:
1647
1684
  return "IntegerField"
1648
1685
 
1649
- def to_python(self, value):
1686
+ def to_python(self, value: Any) -> Any:
1650
1687
  if value is None:
1651
1688
  return value
1652
1689
  try:
@@ -1662,14 +1699,14 @@ class IntegerField(Field):
1662
1699
  class BigIntegerField(IntegerField):
1663
1700
  description = "Big (8 byte) integer"
1664
1701
 
1665
- def get_internal_type(self):
1702
+ def get_internal_type(self) -> str:
1666
1703
  return "BigIntegerField"
1667
1704
 
1668
1705
 
1669
1706
  class SmallIntegerField(IntegerField):
1670
1707
  description = "Small integer"
1671
1708
 
1672
- def get_internal_type(self):
1709
+ def get_internal_type(self) -> str:
1673
1710
  return "SmallIntegerField"
1674
1711
 
1675
1712
 
@@ -1681,9 +1718,9 @@ class GenericIPAddressField(Field):
1681
1718
  def __init__(
1682
1719
  self,
1683
1720
  *,
1684
- protocol="both",
1685
- unpack_ipv4=False,
1686
- **kwargs,
1721
+ protocol: str = "both",
1722
+ unpack_ipv4: bool = False,
1723
+ **kwargs: Any,
1687
1724
  ):
1688
1725
  self.unpack_ipv4 = unpack_ipv4
1689
1726
  self.protocol = protocol
@@ -1695,13 +1732,13 @@ class GenericIPAddressField(Field):
1695
1732
  kwargs["max_length"] = 39
1696
1733
  super().__init__(**kwargs)
1697
1734
 
1698
- def preflight(self, **kwargs):
1735
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]:
1699
1736
  return [
1700
1737
  *super().preflight(**kwargs),
1701
1738
  *self._check_required_and_null_values(),
1702
1739
  ]
1703
1740
 
1704
- def _check_required_and_null_values(self):
1741
+ def _check_required_and_null_values(self) -> list[PreflightResult]:
1705
1742
  if not getattr(self, "allow_null", False) and not getattr(
1706
1743
  self, "required", True
1707
1744
  ):
@@ -1715,7 +1752,7 @@ class GenericIPAddressField(Field):
1715
1752
  ]
1716
1753
  return []
1717
1754
 
1718
- def deconstruct(self):
1755
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1719
1756
  name, path, args, kwargs = super().deconstruct()
1720
1757
  if self.unpack_ipv4 is not False:
1721
1758
  kwargs["unpack_ipv4"] = self.unpack_ipv4
@@ -1725,10 +1762,10 @@ class GenericIPAddressField(Field):
1725
1762
  del kwargs["max_length"]
1726
1763
  return name, path, args, kwargs
1727
1764
 
1728
- def get_internal_type(self):
1765
+ def get_internal_type(self) -> str:
1729
1766
  return "GenericIPAddressField"
1730
1767
 
1731
- def to_python(self, value):
1768
+ def to_python(self, value: Any) -> Any:
1732
1769
  if value is None:
1733
1770
  return None
1734
1771
  if not isinstance(value, str):
@@ -1740,12 +1777,14 @@ class GenericIPAddressField(Field):
1740
1777
  )
1741
1778
  return value
1742
1779
 
1743
- def get_db_prep_value(self, value, connection, prepared=False):
1780
+ def get_db_prep_value(
1781
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
1782
+ ) -> Any:
1744
1783
  if not prepared:
1745
1784
  value = self.get_prep_value(value)
1746
1785
  return connection.ops.adapt_ipaddressfield_value(value)
1747
1786
 
1748
- def get_prep_value(self, value):
1787
+ def get_prep_value(self, value: Any) -> Any:
1749
1788
  value = super().get_prep_value(value)
1750
1789
  if value is None:
1751
1790
  return None
@@ -1758,7 +1797,7 @@ class GenericIPAddressField(Field):
1758
1797
 
1759
1798
 
1760
1799
  class PositiveIntegerRelDbTypeMixin:
1761
- def __init_subclass__(cls, **kwargs):
1800
+ def __init_subclass__(cls, **kwargs: Any) -> None:
1762
1801
  super().__init_subclass__(**kwargs)
1763
1802
  if not hasattr(cls, "integer_field_class"):
1764
1803
  cls.integer_field_class = next(
@@ -1770,7 +1809,7 @@ class PositiveIntegerRelDbTypeMixin:
1770
1809
  None,
1771
1810
  )
1772
1811
 
1773
- def rel_db_type(self, connection):
1812
+ def rel_db_type(self, connection: BaseDatabaseWrapper) -> str | None:
1774
1813
  """
1775
1814
  Return the data type that a related field pointing to this field should
1776
1815
  use. In most cases, a foreign key pointing to a positive integer
@@ -1788,38 +1827,38 @@ class PositiveIntegerRelDbTypeMixin:
1788
1827
  class PositiveBigIntegerField(PositiveIntegerRelDbTypeMixin, BigIntegerField):
1789
1828
  description = "Positive big integer"
1790
1829
 
1791
- def get_internal_type(self):
1830
+ def get_internal_type(self) -> str:
1792
1831
  return "PositiveBigIntegerField"
1793
1832
 
1794
1833
 
1795
1834
  class PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField):
1796
1835
  description = "Positive integer"
1797
1836
 
1798
- def get_internal_type(self):
1837
+ def get_internal_type(self) -> str:
1799
1838
  return "PositiveIntegerField"
1800
1839
 
1801
1840
 
1802
1841
  class PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, SmallIntegerField):
1803
1842
  description = "Positive small integer"
1804
1843
 
1805
- def get_internal_type(self):
1844
+ def get_internal_type(self) -> str:
1806
1845
  return "PositiveSmallIntegerField"
1807
1846
 
1808
1847
 
1809
1848
  class TextField(Field):
1810
1849
  description = "Text"
1811
1850
 
1812
- def __init__(self, *, db_collation=None, **kwargs):
1851
+ def __init__(self, *, db_collation: str | None = None, **kwargs: Any):
1813
1852
  super().__init__(**kwargs)
1814
1853
  self.db_collation = db_collation
1815
1854
 
1816
- def preflight(self, **kwargs):
1855
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]:
1817
1856
  return [
1818
1857
  *super().preflight(**kwargs),
1819
1858
  *self._check_db_collation(),
1820
1859
  ]
1821
1860
 
1822
- def _check_db_collation(self):
1861
+ def _check_db_collation(self) -> list[PreflightResult]:
1823
1862
  errors = []
1824
1863
  if not (
1825
1864
  self.db_collation is None
@@ -1837,24 +1876,24 @@ class TextField(Field):
1837
1876
  )
1838
1877
  return errors
1839
1878
 
1840
- def db_parameters(self, connection):
1879
+ def db_parameters(self, connection: BaseDatabaseWrapper) -> dict[str, Any]:
1841
1880
  db_params = super().db_parameters(connection)
1842
1881
  db_params["collation"] = self.db_collation
1843
1882
  return db_params
1844
1883
 
1845
- def get_internal_type(self):
1884
+ def get_internal_type(self) -> str:
1846
1885
  return "TextField"
1847
1886
 
1848
- def to_python(self, value):
1887
+ def to_python(self, value: Any) -> Any:
1849
1888
  if isinstance(value, str) or value is None:
1850
1889
  return value
1851
1890
  return str(value)
1852
1891
 
1853
- def get_prep_value(self, value):
1892
+ def get_prep_value(self, value: Any) -> Any:
1854
1893
  value = super().get_prep_value(value)
1855
1894
  return self.to_python(value)
1856
1895
 
1857
- def deconstruct(self):
1896
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1858
1897
  name, path, args, kwargs = super().deconstruct()
1859
1898
  if self.db_collation:
1860
1899
  kwargs["db_collation"] = self.db_collation
@@ -1869,13 +1908,15 @@ class TimeField(DateTimeCheckMixin, Field):
1869
1908
  }
1870
1909
  description = "Time"
1871
1910
 
1872
- def __init__(self, *, auto_now=False, auto_now_add=False, **kwargs):
1911
+ def __init__(
1912
+ self, *, auto_now: bool = False, auto_now_add: bool = False, **kwargs: Any
1913
+ ):
1873
1914
  self.auto_now, self.auto_now_add = auto_now, auto_now_add
1874
1915
  if auto_now or auto_now_add:
1875
1916
  kwargs["required"] = False
1876
1917
  super().__init__(**kwargs)
1877
1918
 
1878
- def _check_fix_default_value(self):
1919
+ def _check_fix_default_value(self) -> list[PreflightResult]:
1879
1920
  """
1880
1921
  Warn that using an actual date or datetime value is probably wrong;
1881
1922
  it's only evaluated on server startup.
@@ -1897,7 +1938,7 @@ class TimeField(DateTimeCheckMixin, Field):
1897
1938
  # At this point, value is a datetime object.
1898
1939
  return self._check_if_value_fixed(value, now=now)
1899
1940
 
1900
- def deconstruct(self):
1941
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1901
1942
  name, path, args, kwargs = super().deconstruct()
1902
1943
  if self.auto_now is not False:
1903
1944
  kwargs["auto_now"] = self.auto_now
@@ -1907,10 +1948,10 @@ class TimeField(DateTimeCheckMixin, Field):
1907
1948
  del kwargs["required"]
1908
1949
  return name, path, args, kwargs
1909
1950
 
1910
- def get_internal_type(self):
1951
+ def get_internal_type(self) -> str:
1911
1952
  return "TimeField"
1912
1953
 
1913
- def to_python(self, value):
1954
+ def to_python(self, value: Any) -> Any:
1914
1955
  if value is None:
1915
1956
  return None
1916
1957
  if isinstance(value, datetime.time):
@@ -1938,7 +1979,7 @@ class TimeField(DateTimeCheckMixin, Field):
1938
1979
  params={"value": value},
1939
1980
  )
1940
1981
 
1941
- def pre_save(self, model_instance, add):
1982
+ def pre_save(self, model_instance: Any, add: bool) -> Any:
1942
1983
  if self.auto_now or (self.auto_now_add and add):
1943
1984
  value = datetime.datetime.now().time()
1944
1985
  setattr(model_instance, self.attname, value)
@@ -1946,17 +1987,19 @@ class TimeField(DateTimeCheckMixin, Field):
1946
1987
  else:
1947
1988
  return super().pre_save(model_instance, add)
1948
1989
 
1949
- def get_prep_value(self, value):
1990
+ def get_prep_value(self, value: Any) -> Any:
1950
1991
  value = super().get_prep_value(value)
1951
1992
  return self.to_python(value)
1952
1993
 
1953
- def get_db_prep_value(self, value, connection, prepared=False):
1994
+ def get_db_prep_value(
1995
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
1996
+ ) -> Any:
1954
1997
  # Casts times into the format expected by the backend
1955
1998
  if not prepared:
1956
1999
  value = self.get_prep_value(value)
1957
2000
  return connection.ops.adapt_timefield_value(value)
1958
2001
 
1959
- def value_to_string(self, obj):
2002
+ def value_to_string(self, obj: Any) -> str:
1960
2003
  val = self.value_from_object(obj)
1961
2004
  return "" if val is None else val.isoformat()
1962
2005
 
@@ -1965,11 +2008,11 @@ class URLField(CharField):
1965
2008
  default_validators = [validators.URLValidator()]
1966
2009
  description = "URL"
1967
2010
 
1968
- def __init__(self, **kwargs):
2011
+ def __init__(self, **kwargs: Any):
1969
2012
  kwargs.setdefault("max_length", 200)
1970
2013
  super().__init__(**kwargs)
1971
2014
 
1972
- def deconstruct(self):
2015
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
1973
2016
  name, path, args, kwargs = super().deconstruct()
1974
2017
  if kwargs.get("max_length") == 200:
1975
2018
  del kwargs["max_length"]
@@ -1980,15 +2023,15 @@ class BinaryField(Field):
1980
2023
  description = "Raw binary data"
1981
2024
  empty_values = [None, b""]
1982
2025
 
1983
- def __init__(self, **kwargs):
2026
+ def __init__(self, **kwargs: Any):
1984
2027
  super().__init__(**kwargs)
1985
2028
  if self.max_length is not None:
1986
2029
  self.validators.append(validators.MaxLengthValidator(self.max_length))
1987
2030
 
1988
- def preflight(self, **kwargs):
2031
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]:
1989
2032
  return [*super().preflight(**kwargs), *self._check_str_default_value()]
1990
2033
 
1991
- def _check_str_default_value(self):
2034
+ def _check_str_default_value(self) -> list[PreflightResult]:
1992
2035
  if self.has_default() and isinstance(self.default, str):
1993
2036
  return [
1994
2037
  PreflightResult(
@@ -2000,13 +2043,15 @@ class BinaryField(Field):
2000
2043
  ]
2001
2044
  return []
2002
2045
 
2003
- def get_internal_type(self):
2046
+ def get_internal_type(self) -> str:
2004
2047
  return "BinaryField"
2005
2048
 
2006
- def get_placeholder(self, value, compiler, connection):
2049
+ def get_placeholder(
2050
+ self, value: Any, compiler: SQLCompiler, connection: BaseDatabaseWrapper
2051
+ ) -> Any:
2007
2052
  return connection.ops.binary_placeholder_sql(value)
2008
2053
 
2009
- def get_default(self):
2054
+ def get_default(self) -> Any:
2010
2055
  if self.has_default() and not callable(self.default):
2011
2056
  return self.default
2012
2057
  default = super().get_default()
@@ -2014,17 +2059,19 @@ class BinaryField(Field):
2014
2059
  return b""
2015
2060
  return default
2016
2061
 
2017
- def get_db_prep_value(self, value, connection, prepared=False):
2062
+ def get_db_prep_value(
2063
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
2064
+ ) -> Any:
2018
2065
  value = super().get_db_prep_value(value, connection, prepared)
2019
2066
  if value is not None:
2020
- return connection.Database.Binary(value)
2067
+ return connection.Database.Binary(value) # type: ignore[attr-defined]
2021
2068
  return value
2022
2069
 
2023
- def value_to_string(self, obj):
2070
+ def value_to_string(self, obj: Any) -> str:
2024
2071
  """Binary data is serialized as base64"""
2025
2072
  return b64encode(self.value_from_object(obj)).decode("ascii")
2026
2073
 
2027
- def to_python(self, value):
2074
+ def to_python(self, value: Any) -> Any:
2028
2075
  # If it's a string, it should be base64-encoded data
2029
2076
  if isinstance(value, str):
2030
2077
  return memoryview(b64decode(value.encode("ascii")))
@@ -2038,23 +2085,25 @@ class UUIDField(Field):
2038
2085
  description = "Universally unique identifier"
2039
2086
  empty_strings_allowed = False
2040
2087
 
2041
- def __init__(self, **kwargs):
2088
+ def __init__(self, **kwargs: Any):
2042
2089
  kwargs["max_length"] = 32
2043
2090
  super().__init__(**kwargs)
2044
2091
 
2045
- def deconstruct(self):
2092
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
2046
2093
  name, path, args, kwargs = super().deconstruct()
2047
2094
  del kwargs["max_length"]
2048
2095
  return name, path, args, kwargs
2049
2096
 
2050
- def get_internal_type(self):
2097
+ def get_internal_type(self) -> str:
2051
2098
  return "UUIDField"
2052
2099
 
2053
- def get_prep_value(self, value):
2100
+ def get_prep_value(self, value: Any) -> Any:
2054
2101
  value = super().get_prep_value(value)
2055
2102
  return self.to_python(value)
2056
2103
 
2057
- def get_db_prep_value(self, value, connection, prepared=False):
2104
+ def get_db_prep_value(
2105
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
2106
+ ) -> Any:
2058
2107
  if value is None:
2059
2108
  return None
2060
2109
  if not isinstance(value, uuid.UUID):
@@ -2064,7 +2113,7 @@ class UUIDField(Field):
2064
2113
  return value
2065
2114
  return value.hex
2066
2115
 
2067
- def to_python(self, value):
2116
+ def to_python(self, value: Any) -> Any:
2068
2117
  if value is not None and not isinstance(value, uuid.UUID):
2069
2118
  input_form = "int" if isinstance(value, int) else "hex"
2070
2119
  try:
@@ -2091,27 +2140,29 @@ class PrimaryKeyField(BigIntegerField):
2091
2140
  self.creation_counter = Field.auto_creation_counter
2092
2141
  Field.auto_creation_counter -= 1
2093
2142
 
2094
- def preflight(self, **kwargs):
2143
+ def preflight(self, **kwargs: Any) -> list[PreflightResult]:
2095
2144
  errors = super().preflight(**kwargs)
2096
2145
  # Remove the reserved_field_name_id error for 'id' field name since PrimaryKeyField is allowed to use it
2097
2146
  errors = [e for e in errors if e.id != "fields.reserved_field_name_id"]
2098
2147
  return errors
2099
2148
 
2100
- def deconstruct(self):
2149
+ def deconstruct(self) -> tuple[str, str, list[Any], dict[str, Any]]:
2101
2150
  # PrimaryKeyField takes no parameters, so we return an empty kwargs dict
2102
2151
  return (self.name, "plain.models.PrimaryKeyField", [], {})
2103
2152
 
2104
- def validate(self, value, model_instance):
2153
+ def validate(self, value: Any, model_instance: Any) -> None:
2105
2154
  pass
2106
2155
 
2107
- def get_db_prep_value(self, value, connection, prepared=False):
2156
+ def get_db_prep_value(
2157
+ self, value: Any, connection: BaseDatabaseWrapper, prepared: bool = False
2158
+ ) -> Any:
2108
2159
  if not prepared:
2109
2160
  value = self.get_prep_value(value)
2110
2161
  value = connection.ops.validate_autopk_value(value)
2111
2162
  return value
2112
2163
 
2113
- def get_internal_type(self):
2164
+ def get_internal_type(self) -> str:
2114
2165
  return "PrimaryKeyField"
2115
2166
 
2116
- def rel_db_type(self, connection):
2167
+ def rel_db_type(self, connection: BaseDatabaseWrapper) -> str | None:
2117
2168
  return BigIntegerField().db_type(connection=connection)