v0.146.0
  1"""
  2Type stubs for typed model fields.
  3
  4These stubs tell type checkers that field constructors return primitive types,
  5enabling typed model definitions like:
  6    name: str = types.TextField()
  7
  8At runtime, these are Field instances (descriptors), but type checkers see the primitives.
  9
 10The return type is conditional on allow_null:
 11- allow_null=False (default) returns the primitive type (e.g., str)
 12- allow_null=True returns the primitive type | None (e.g., str | None)
 13"""
 14
 15from collections.abc import Callable, Sequence
 16from datetime import date, datetime, time, timedelta
 17from decimal import Decimal
 18from json import JSONDecoder, JSONEncoder
 19from typing import Any, Literal, overload
 20from uuid import UUID
 21from zoneinfo import ZoneInfo
 22
 23# Import manager types from runtime (will be Generic[T, QS] there)
 24from plain.postgres.base import Model
 25from plain.postgres.deletion import OnDelete
 26from plain.postgres.fields.related_managers import (
 27    ManyToManyManager,
 28    ReverseForeignKeyManager,
 29)
 30from plain.postgres.query import QuerySet
 31
 32# String fields
 33@overload
 34def TextField(
 35    *,
 36    max_length: int | None = None,
 37    required: bool = True,
 38    allow_null: Literal[True],
 39    default: Any = ...,
 40    choices: Any = None,
 41    validators: Sequence[Callable[..., Any]] = (),
 42) -> str | None: ...
 43@overload
 44def TextField(
 45    *,
 46    max_length: int | None = None,
 47    required: bool = True,
 48    allow_null: Literal[False] = False,
 49    default: Any = ...,
 50    choices: Any = None,
 51    validators: Sequence[Callable[..., Any]] = (),
 52) -> str: ...
 53@overload
 54def EmailField(
 55    *,
 56    max_length: int | None = None,
 57    required: bool = True,
 58    allow_null: Literal[True],
 59    default: Any = ...,
 60    choices: Any = None,
 61    validators: Sequence[Callable[..., Any]] = (),
 62) -> str | None: ...
 63@overload
 64def EmailField(
 65    *,
 66    max_length: int | None = None,
 67    required: bool = True,
 68    allow_null: Literal[False] = False,
 69    default: Any = ...,
 70    choices: Any = None,
 71    validators: Sequence[Callable[..., Any]] = (),
 72) -> str: ...
 73@overload
 74def URLField(
 75    *,
 76    max_length: int | None = None,
 77    required: bool = True,
 78    allow_null: Literal[True],
 79    default: Any = ...,
 80    choices: Any = None,
 81    validators: Sequence[Callable[..., Any]] = (),
 82) -> str | None: ...
 83@overload
 84def URLField(
 85    *,
 86    max_length: int | None = None,
 87    required: bool = True,
 88    allow_null: Literal[False] = False,
 89    default: Any = ...,
 90    choices: Any = None,
 91    validators: Sequence[Callable[..., Any]] = (),
 92) -> str: ...
 93
 94# Integer fields
 95@overload
 96def IntegerField(
 97    *,
 98    required: bool = True,
 99    allow_null: Literal[True],
100    default: Any = ...,
101    validators: Sequence[Callable[..., Any]] = (),
102) -> int | None: ...
103@overload
104def IntegerField(
105    *,
106    required: bool = True,
107    allow_null: Literal[False] = False,
108    default: Any = ...,
109    validators: Sequence[Callable[..., Any]] = (),
110) -> int: ...
111@overload
112def BigIntegerField(
113    *,
114    required: bool = True,
115    allow_null: Literal[True],
116    default: Any = ...,
117    validators: Sequence[Callable[..., Any]] = (),
118) -> int | None: ...
119@overload
120def BigIntegerField(
121    *,
122    required: bool = True,
123    allow_null: Literal[False] = False,
124    default: Any = ...,
125    validators: Sequence[Callable[..., Any]] = (),
126) -> int: ...
127@overload
128def SmallIntegerField(
129    *,
130    required: bool = True,
131    allow_null: Literal[True],
132    default: Any = ...,
133    validators: Sequence[Callable[..., Any]] = (),
134) -> int | None: ...
135@overload
136def SmallIntegerField(
137    *,
138    required: bool = True,
139    allow_null: Literal[False] = False,
140    default: Any = ...,
141    validators: Sequence[Callable[..., Any]] = (),
142) -> int: ...
143def PrimaryKeyField() -> int: ...
144
145# Numeric fields
146@overload
147def FloatField(
148    *,
149    required: bool = True,
150    allow_null: Literal[True],
151    default: Any = ...,
152    validators: Sequence[Callable[..., Any]] = (),
153) -> float | None: ...
154@overload
155def FloatField(
156    *,
157    required: bool = True,
158    allow_null: Literal[False] = False,
159    default: Any = ...,
160    validators: Sequence[Callable[..., Any]] = (),
161) -> float: ...
162@overload
163def DecimalField(
164    *,
165    max_digits: int | None = None,
166    decimal_places: int | None = None,
167    required: bool = True,
168    allow_null: Literal[True],
169    default: Any = ...,
170    validators: Sequence[Callable[..., Any]] = (),
171) -> Decimal | None: ...
172@overload
173def DecimalField(
174    *,
175    max_digits: int | None = None,
176    decimal_places: int | None = None,
177    required: bool = True,
178    allow_null: Literal[False] = False,
179    default: Any = ...,
180    validators: Sequence[Callable[..., Any]] = (),
181) -> Decimal: ...
182
183# Boolean field
184@overload
185def BooleanField(
186    *,
187    required: bool = True,
188    allow_null: Literal[True],
189    default: Any = ...,
190    validators: Sequence[Callable[..., Any]] = (),
191) -> bool | None: ...
192@overload
193def BooleanField(
194    *,
195    required: bool = True,
196    allow_null: Literal[False] = False,
197    default: Any = ...,
198    validators: Sequence[Callable[..., Any]] = (),
199) -> bool: ...
200
201# Date/time fields
202@overload
203def DateField(
204    *,
205    required: bool = True,
206    allow_null: Literal[True],
207    default: Any = ...,
208    validators: Sequence[Callable[..., Any]] = (),
209) -> date | None: ...
210@overload
211def DateField(
212    *,
213    required: bool = True,
214    allow_null: Literal[False] = False,
215    default: Any = ...,
216    validators: Sequence[Callable[..., Any]] = (),
217) -> date: ...
218@overload
219def DateTimeField(
220    *,
221    create_now: bool = False,
222    update_now: bool = False,
223    required: bool = True,
224    allow_null: Literal[True],
225    validators: Sequence[Callable[..., Any]] = (),
226) -> datetime | None: ...
227@overload
228def DateTimeField(
229    *,
230    create_now: bool = False,
231    update_now: bool = False,
232    required: bool = True,
233    allow_null: Literal[False] = False,
234    validators: Sequence[Callable[..., Any]] = (),
235) -> datetime: ...
236@overload
237def TimeField(
238    *,
239    required: bool = True,
240    allow_null: Literal[True],
241    default: Any = ...,
242    validators: Sequence[Callable[..., Any]] = (),
243) -> time | None: ...
244@overload
245def TimeField(
246    *,
247    required: bool = True,
248    allow_null: Literal[False] = False,
249    default: Any = ...,
250    validators: Sequence[Callable[..., Any]] = (),
251) -> time: ...
252@overload
253def DurationField(
254    *,
255    required: bool = True,
256    allow_null: Literal[True],
257    default: Any = ...,
258    validators: Sequence[Callable[..., Any]] = (),
259) -> timedelta | None: ...
260@overload
261def DurationField(
262    *,
263    required: bool = True,
264    allow_null: Literal[False] = False,
265    default: Any = ...,
266    validators: Sequence[Callable[..., Any]] = (),
267) -> timedelta: ...
268@overload
269def TimeZoneField(
270    *,
271    required: bool = True,
272    allow_null: Literal[True],
273    default: Any = ...,
274    validators: Sequence[Callable[..., Any]] = (),
275) -> ZoneInfo | None: ...
276@overload
277def TimeZoneField(
278    *,
279    required: bool = True,
280    allow_null: Literal[False] = False,
281    default: Any = ...,
282    validators: Sequence[Callable[..., Any]] = (),
283) -> ZoneInfo: ...
284
285# Other fields
286@overload
287def UUIDField(
288    *,
289    generate: bool = False,
290    required: bool = True,
291    allow_null: Literal[True],
292    validators: Sequence[Callable[..., Any]] = (),
293) -> UUID | None: ...
294@overload
295def UUIDField(
296    *,
297    generate: bool = False,
298    required: bool = True,
299    allow_null: Literal[False] = False,
300    validators: Sequence[Callable[..., Any]] = (),
301) -> UUID: ...
302@overload
303def RandomStringField(
304    *,
305    length: int,
306    required: bool = True,
307    allow_null: Literal[True],
308    validators: Sequence[Callable[..., Any]] = (),
309) -> str | None: ...
310@overload
311def RandomStringField(
312    *,
313    length: int,
314    required: bool = True,
315    allow_null: Literal[False] = False,
316    validators: Sequence[Callable[..., Any]] = (),
317) -> str: ...
318@overload
319def BinaryField(
320    *,
321    max_length: int | None = None,
322    required: bool = True,
323    allow_null: Literal[True],
324    validators: Sequence[Callable[..., Any]] = (),
325) -> bytes | None: ...
326@overload
327def BinaryField(
328    *,
329    max_length: int | None = None,
330    required: bool = True,
331    allow_null: Literal[False] = False,
332    validators: Sequence[Callable[..., Any]] = (),
333) -> bytes: ...
334@overload
335def GenericIPAddressField(
336    *,
337    protocol: str = "both",
338    unpack_ipv4: bool = False,
339    required: bool = True,
340    allow_null: Literal[True],
341    default: Any = ...,
342    validators: Sequence[Callable[..., Any]] = (),
343) -> str | None: ...
344@overload
345def GenericIPAddressField(
346    *,
347    protocol: str = "both",
348    unpack_ipv4: bool = False,
349    required: bool = True,
350    allow_null: Literal[False] = False,
351    default: Any = ...,
352    validators: Sequence[Callable[..., Any]] = (),
353) -> str: ...
354@overload
355def JSONField(
356    *,
357    encoder: type[JSONEncoder] | None = None,
358    decoder: type[JSONDecoder] | None = None,
359    required: bool = True,
360    allow_null: Literal[True],
361    default: Any = ...,
362    validators: Sequence[Callable[..., Any]] = (),
363) -> Any: ...
364@overload
365def JSONField(
366    *,
367    encoder: type[JSONEncoder] | None = None,
368    decoder: type[JSONDecoder] | None = None,
369    required: bool = True,
370    allow_null: Literal[False] = False,
371    default: Any = ...,
372    validators: Sequence[Callable[..., Any]] = (),
373) -> Any: ...
374
375# Encrypted fields
376@overload
377def EncryptedTextField(
378    *,
379    max_length: int | None = None,
380    required: bool = True,
381    allow_null: Literal[True],
382    validators: Sequence[Callable[..., Any]] = (),
383) -> str | None: ...
384@overload
385def EncryptedTextField(
386    *,
387    max_length: int | None = None,
388    required: bool = True,
389    allow_null: Literal[False] = False,
390    validators: Sequence[Callable[..., Any]] = (),
391) -> str: ...
392@overload
393def EncryptedJSONField(
394    *,
395    encoder: type[JSONEncoder] | None = None,
396    decoder: type[JSONDecoder] | None = None,
397    required: bool = True,
398    allow_null: Literal[True],
399    validators: Sequence[Callable[..., Any]] = (),
400) -> Any: ...
401@overload
402def EncryptedJSONField(
403    *,
404    encoder: type[JSONEncoder] | None = None,
405    decoder: type[JSONDecoder] | None = None,
406    required: bool = True,
407    allow_null: Literal[False] = False,
408    validators: Sequence[Callable[..., Any]] = (),
409) -> Any: ...
410
411# Related fields
412@overload
413def ForeignKeyField[T: Model](
414    to: type[T] | str,
415    on_delete: OnDelete,
416    *,
417    related_query_name: str | None = None,
418    limit_choices_to: Any = None,
419    db_constraint: bool = True,
420    required: bool = True,
421    allow_null: Literal[True],
422    validators: Sequence[Callable[..., Any]] = (),
423) -> T | None: ...
424@overload
425def ForeignKeyField[T: Model](
426    to: type[T] | str,
427    on_delete: OnDelete,
428    *,
429    related_query_name: str | None = None,
430    limit_choices_to: Any = None,
431    db_constraint: bool = True,
432    required: bool = True,
433    allow_null: Literal[False] = False,
434    validators: Sequence[Callable[..., Any]] = (),
435) -> T: ...
436def ManyToManyField[T: Model](
437    to: type[T] | str,
438    *,
439    through: Any,
440    through_fields: tuple[str, str] | None = None,
441    related_query_name: str | None = None,
442    limit_choices_to: Any = None,
443    symmetrical: bool | None = None,
444) -> ManyToManyManager[T]: ...
445
446# Reverse relation descriptors
447class ReverseForeignKey[T: Model, QS: QuerySet[Any] = QuerySet[Any]]:
448    """
449    Descriptor for the reverse side of a ForeignKeyField.
450
451    Type parameters:
452        _T: The related model type
453        _QS: The QuerySet type (use the model's custom QuerySet for proper method typing)
454
455    Example:
456        # With custom QuerySet for proper typing of custom methods like .enabled()
457        repos: ReverseForeignKey[Repo, RepoQuerySet] = ReverseForeignKey(to="Repo", field="organization")
458
459        # Usage: org.repos.query.enabled()  # .enabled() is now recognized
460    """
461    def __init__(self, *, to: type[T] | str, field: str) -> None: ...
462    @overload
463    def __get__(self, instance: None, owner: type) -> ReverseForeignKey[T, QS]: ...
464    @overload
465    def __get__(
466        self, instance: Model, owner: type
467    ) -> ReverseForeignKeyManager[T, QS]: ...
468    def __get__(
469        self, instance: Model | None, owner: type
470    ) -> ReverseForeignKey[T, QS] | ReverseForeignKeyManager[T, QS]: ...
471
472class ReverseManyToMany[T: Model, QS: QuerySet[Any] = QuerySet[Any]]:
473    """
474    Descriptor for the reverse side of a ManyToManyField.
475
476    Type parameters:
477        _T: The related model type
478        _QS: The QuerySet type (use the model's custom QuerySet for proper method typing)
479    """
480    def __init__(self, *, to: type[T] | str, field: str) -> None: ...
481    @overload
482    def __get__(self, instance: None, owner: type) -> ReverseManyToMany[T, QS]: ...
483    @overload
484    def __get__(self, instance: Model, owner: type) -> ManyToManyManager[T, QS]: ...
485    def __get__(
486        self, instance: Model | None, owner: type
487    ) -> ReverseManyToMany[T, QS] | ManyToManyManager[T, QS]: ...
488
489# Export all types (should match types.py)
490__all__ = [
491    "BigIntegerField",
492    "BinaryField",
493    "BooleanField",
494    "DateField",
495    "DateTimeField",
496    "DecimalField",
497    "DurationField",
498    "EmailField",
499    "EncryptedJSONField",
500    "EncryptedTextField",
501    "FloatField",
502    "ForeignKeyField",
503    "GenericIPAddressField",
504    "IntegerField",
505    "JSONField",
506    "ManyToManyField",
507    "ManyToManyManager",
508    "PrimaryKeyField",
509    "RandomStringField",
510    "ReverseForeignKey",
511    "ReverseForeignKeyManager",
512    "ReverseManyToMany",
513    "SmallIntegerField",
514    "TextField",
515    "TimeField",
516    "TimeZoneField",
517    "URLField",
518    "UUIDField",
519]