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.CharField()
  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.fields.related_managers import (
 26    ManyToManyManager,
 27    ReverseForeignKeyManager,
 28)
 29from plain.postgres.query import QuerySet
 30
 31# String fields
 32@overload
 33def CharField(
 34    *,
 35    max_length: int | None = None,
 36    required: bool = True,
 37    allow_null: Literal[True],
 38    default: Any = ...,
 39    choices: Any = None,
 40    validators: Sequence[Callable[..., Any]] = (),
 41    error_messages: dict[str, str] | None = None,
 42) -> str | None: ...
 43@overload
 44def CharField(
 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    error_messages: dict[str, str] | None = None,
 53) -> str: ...
 54@overload
 55def TextField(
 56    *,
 57    max_length: int | None = None,
 58    required: bool = True,
 59    allow_null: Literal[True],
 60    default: Any = ...,
 61    choices: Any = None,
 62    validators: Sequence[Callable[..., Any]] = (),
 63    error_messages: dict[str, str] | None = None,
 64) -> str | None: ...
 65@overload
 66def TextField(
 67    *,
 68    max_length: int | None = None,
 69    required: bool = True,
 70    allow_null: Literal[False] = False,
 71    default: Any = ...,
 72    choices: Any = None,
 73    validators: Sequence[Callable[..., Any]] = (),
 74    error_messages: dict[str, str] | None = None,
 75) -> str: ...
 76@overload
 77def EmailField(
 78    *,
 79    max_length: int | None = None,
 80    required: bool = True,
 81    allow_null: Literal[True],
 82    default: Any = ...,
 83    choices: Any = None,
 84    validators: Sequence[Callable[..., Any]] = (),
 85    error_messages: dict[str, str] | None = None,
 86) -> str | None: ...
 87@overload
 88def EmailField(
 89    *,
 90    max_length: int | None = None,
 91    required: bool = True,
 92    allow_null: Literal[False] = False,
 93    default: Any = ...,
 94    choices: Any = None,
 95    validators: Sequence[Callable[..., Any]] = (),
 96    error_messages: dict[str, str] | None = None,
 97) -> str: ...
 98@overload
 99def URLField(
100    *,
101    max_length: int | None = None,
102    required: bool = True,
103    allow_null: Literal[True],
104    default: Any = ...,
105    choices: Any = None,
106    validators: Sequence[Callable[..., Any]] = (),
107    error_messages: dict[str, str] | None = None,
108) -> str | None: ...
109@overload
110def URLField(
111    *,
112    max_length: int | None = None,
113    required: bool = True,
114    allow_null: Literal[False] = False,
115    default: Any = ...,
116    choices: Any = None,
117    validators: Sequence[Callable[..., Any]] = (),
118    error_messages: dict[str, str] | None = None,
119) -> str: ...
120
121# Integer fields
122@overload
123def IntegerField(
124    *,
125    max_length: int | None = None,
126    required: bool = True,
127    allow_null: Literal[True],
128    default: Any = ...,
129    choices: Any = None,
130    validators: Sequence[Callable[..., Any]] = (),
131    error_messages: dict[str, str] | None = None,
132) -> int | None: ...
133@overload
134def IntegerField(
135    *,
136    max_length: int | None = None,
137    required: bool = True,
138    allow_null: Literal[False] = False,
139    default: Any = ...,
140    choices: Any = None,
141    validators: Sequence[Callable[..., Any]] = (),
142    error_messages: dict[str, str] | None = None,
143) -> int: ...
144@overload
145def BigIntegerField(
146    *,
147    max_length: int | None = None,
148    required: bool = True,
149    allow_null: Literal[True],
150    default: Any = ...,
151    choices: Any = None,
152    validators: Sequence[Callable[..., Any]] = (),
153    error_messages: dict[str, str] | None = None,
154) -> int | None: ...
155@overload
156def BigIntegerField(
157    *,
158    max_length: int | None = None,
159    required: bool = True,
160    allow_null: Literal[False] = False,
161    default: Any = ...,
162    choices: Any = None,
163    validators: Sequence[Callable[..., Any]] = (),
164    error_messages: dict[str, str] | None = None,
165) -> int: ...
166@overload
167def SmallIntegerField(
168    *,
169    max_length: int | None = None,
170    required: bool = True,
171    allow_null: Literal[True],
172    default: Any = ...,
173    choices: Any = None,
174    validators: Sequence[Callable[..., Any]] = (),
175    error_messages: dict[str, str] | None = None,
176) -> int | None: ...
177@overload
178def SmallIntegerField(
179    *,
180    max_length: int | None = None,
181    required: bool = True,
182    allow_null: Literal[False] = False,
183    default: Any = ...,
184    choices: Any = None,
185    validators: Sequence[Callable[..., Any]] = (),
186    error_messages: dict[str, str] | None = None,
187) -> int: ...
188@overload
189def PositiveIntegerField(
190    *,
191    max_length: int | None = None,
192    required: bool = True,
193    allow_null: Literal[True],
194    default: Any = ...,
195    choices: Any = None,
196    validators: Sequence[Callable[..., Any]] = (),
197    error_messages: dict[str, str] | None = None,
198) -> int | None: ...
199@overload
200def PositiveIntegerField(
201    *,
202    max_length: int | None = None,
203    required: bool = True,
204    allow_null: Literal[False] = False,
205    default: Any = ...,
206    choices: Any = None,
207    validators: Sequence[Callable[..., Any]] = (),
208    error_messages: dict[str, str] | None = None,
209) -> int: ...
210@overload
211def PositiveBigIntegerField(
212    *,
213    max_length: int | None = None,
214    required: bool = True,
215    allow_null: Literal[True],
216    default: Any = ...,
217    choices: Any = None,
218    validators: Sequence[Callable[..., Any]] = (),
219    error_messages: dict[str, str] | None = None,
220) -> int | None: ...
221@overload
222def PositiveBigIntegerField(
223    *,
224    max_length: int | None = None,
225    required: bool = True,
226    allow_null: Literal[False] = False,
227    default: Any = ...,
228    choices: Any = None,
229    validators: Sequence[Callable[..., Any]] = (),
230    error_messages: dict[str, str] | None = None,
231) -> int: ...
232@overload
233def PositiveSmallIntegerField(
234    *,
235    max_length: int | None = None,
236    required: bool = True,
237    allow_null: Literal[True],
238    default: Any = ...,
239    choices: Any = None,
240    validators: Sequence[Callable[..., Any]] = (),
241    error_messages: dict[str, str] | None = None,
242) -> int | None: ...
243@overload
244def PositiveSmallIntegerField(
245    *,
246    max_length: int | None = None,
247    required: bool = True,
248    allow_null: Literal[False] = False,
249    default: Any = ...,
250    choices: Any = None,
251    validators: Sequence[Callable[..., Any]] = (),
252    error_messages: dict[str, str] | None = None,
253) -> int: ...
254@overload
255def PrimaryKeyField(
256    *,
257    max_length: int | None = None,
258    required: bool = True,
259    allow_null: Literal[True],
260    default: Any = ...,
261    choices: Any = None,
262    validators: Sequence[Callable[..., Any]] = (),
263    error_messages: dict[str, str] | None = None,
264) -> int | None: ...
265@overload
266def PrimaryKeyField(
267    *,
268    max_length: int | None = None,
269    required: bool = True,
270    allow_null: Literal[False] = False,
271    default: Any = ...,
272    choices: Any = None,
273    validators: Sequence[Callable[..., Any]] = (),
274    error_messages: dict[str, str] | None = None,
275) -> int: ...
276
277# Numeric fields
278@overload
279def FloatField(
280    *,
281    max_length: int | None = None,
282    required: bool = True,
283    allow_null: Literal[True],
284    default: Any = ...,
285    choices: Any = None,
286    validators: Sequence[Callable[..., Any]] = (),
287    error_messages: dict[str, str] | None = None,
288) -> float | None: ...
289@overload
290def FloatField(
291    *,
292    max_length: int | None = None,
293    required: bool = True,
294    allow_null: Literal[False] = False,
295    default: Any = ...,
296    choices: Any = None,
297    validators: Sequence[Callable[..., Any]] = (),
298    error_messages: dict[str, str] | None = None,
299) -> float: ...
300@overload
301def DecimalField(
302    *,
303    max_digits: int | None = None,
304    decimal_places: int | None = None,
305    max_length: int | None = None,
306    required: bool = True,
307    allow_null: Literal[True],
308    default: Any = ...,
309    choices: Any = None,
310    validators: Sequence[Callable[..., Any]] = (),
311    error_messages: dict[str, str] | None = None,
312) -> Decimal | None: ...
313@overload
314def DecimalField(
315    *,
316    max_digits: int | None = None,
317    decimal_places: int | None = None,
318    max_length: int | None = None,
319    required: bool = True,
320    allow_null: Literal[False] = False,
321    default: Any = ...,
322    choices: Any = None,
323    validators: Sequence[Callable[..., Any]] = (),
324    error_messages: dict[str, str] | None = None,
325) -> Decimal: ...
326
327# Boolean field
328@overload
329def BooleanField(
330    *,
331    max_length: int | None = None,
332    required: bool = True,
333    allow_null: Literal[True],
334    default: Any = ...,
335    choices: Any = None,
336    validators: Sequence[Callable[..., Any]] = (),
337    error_messages: dict[str, str] | None = None,
338) -> bool | None: ...
339@overload
340def BooleanField(
341    *,
342    max_length: int | None = None,
343    required: bool = True,
344    allow_null: Literal[False] = False,
345    default: Any = ...,
346    choices: Any = None,
347    validators: Sequence[Callable[..., Any]] = (),
348    error_messages: dict[str, str] | None = None,
349) -> bool: ...
350
351# Date/time fields
352@overload
353def DateField(
354    *,
355    auto_now: bool = False,
356    auto_now_add: bool = False,
357    max_length: int | None = None,
358    required: bool = True,
359    allow_null: Literal[True],
360    default: Any = ...,
361    choices: Any = None,
362    validators: Sequence[Callable[..., Any]] = (),
363    error_messages: dict[str, str] | None = None,
364) -> date | None: ...
365@overload
366def DateField(
367    *,
368    auto_now: bool = False,
369    auto_now_add: bool = False,
370    max_length: int | None = None,
371    required: bool = True,
372    allow_null: Literal[False] = False,
373    default: Any = ...,
374    choices: Any = None,
375    validators: Sequence[Callable[..., Any]] = (),
376    error_messages: dict[str, str] | None = None,
377) -> date: ...
378@overload
379def DateTimeField(
380    *,
381    auto_now: bool = False,
382    auto_now_add: bool = False,
383    max_length: int | None = None,
384    required: bool = True,
385    allow_null: Literal[True],
386    default: Any = ...,
387    choices: Any = None,
388    validators: Sequence[Callable[..., Any]] = (),
389    error_messages: dict[str, str] | None = None,
390) -> datetime | None: ...
391@overload
392def DateTimeField(
393    *,
394    auto_now: bool = False,
395    auto_now_add: bool = False,
396    max_length: int | None = None,
397    required: bool = True,
398    allow_null: Literal[False] = False,
399    default: Any = ...,
400    choices: Any = None,
401    validators: Sequence[Callable[..., Any]] = (),
402    error_messages: dict[str, str] | None = None,
403) -> datetime: ...
404@overload
405def TimeField(
406    *,
407    auto_now: bool = False,
408    auto_now_add: bool = False,
409    max_length: int | None = None,
410    required: bool = True,
411    allow_null: Literal[True],
412    default: Any = ...,
413    choices: Any = None,
414    validators: Sequence[Callable[..., Any]] = (),
415    error_messages: dict[str, str] | None = None,
416) -> time | None: ...
417@overload
418def TimeField(
419    *,
420    auto_now: bool = False,
421    auto_now_add: bool = False,
422    max_length: int | None = None,
423    required: bool = True,
424    allow_null: Literal[False] = False,
425    default: Any = ...,
426    choices: Any = None,
427    validators: Sequence[Callable[..., Any]] = (),
428    error_messages: dict[str, str] | None = None,
429) -> time: ...
430@overload
431def DurationField(
432    *,
433    max_length: int | None = None,
434    required: bool = True,
435    allow_null: Literal[True],
436    default: Any = ...,
437    choices: Any = None,
438    validators: Sequence[Callable[..., Any]] = (),
439    error_messages: dict[str, str] | None = None,
440) -> timedelta | None: ...
441@overload
442def DurationField(
443    *,
444    max_length: int | None = None,
445    required: bool = True,
446    allow_null: Literal[False] = False,
447    default: Any = ...,
448    choices: Any = None,
449    validators: Sequence[Callable[..., Any]] = (),
450    error_messages: dict[str, str] | None = None,
451) -> timedelta: ...
452@overload
453def TimeZoneField(
454    *,
455    max_length: int | None = None,
456    required: bool = True,
457    allow_null: Literal[True],
458    default: Any = ...,
459    choices: Any = None,
460    validators: Sequence[Callable[..., Any]] = (),
461    error_messages: dict[str, str] | None = None,
462) -> ZoneInfo | None: ...
463@overload
464def TimeZoneField(
465    *,
466    max_length: int | None = None,
467    required: bool = True,
468    allow_null: Literal[False] = False,
469    default: Any = ...,
470    choices: Any = None,
471    validators: Sequence[Callable[..., Any]] = (),
472    error_messages: dict[str, str] | None = None,
473) -> ZoneInfo: ...
474
475# Other fields
476@overload
477def UUIDField(
478    *,
479    max_length: int | None = None,
480    required: bool = True,
481    allow_null: Literal[True],
482    default: Any = ...,
483    choices: Any = None,
484    validators: Sequence[Callable[..., Any]] = (),
485    error_messages: dict[str, str] | None = None,
486) -> UUID | None: ...
487@overload
488def UUIDField(
489    *,
490    max_length: int | None = None,
491    required: bool = True,
492    allow_null: Literal[False] = False,
493    default: Any = ...,
494    choices: Any = None,
495    validators: Sequence[Callable[..., Any]] = (),
496    error_messages: dict[str, str] | None = None,
497) -> UUID: ...
498@overload
499def BinaryField(
500    *,
501    max_length: int | None = None,
502    required: bool = True,
503    allow_null: Literal[True],
504    default: Any = ...,
505    choices: Any = None,
506    validators: Sequence[Callable[..., Any]] = (),
507    error_messages: dict[str, str] | None = None,
508) -> bytes | None: ...
509@overload
510def BinaryField(
511    *,
512    max_length: int | None = None,
513    required: bool = True,
514    allow_null: Literal[False] = False,
515    default: Any = ...,
516    choices: Any = None,
517    validators: Sequence[Callable[..., Any]] = (),
518    error_messages: dict[str, str] | None = None,
519) -> bytes: ...
520@overload
521def GenericIPAddressField(
522    *,
523    protocol: str = "both",
524    unpack_ipv4: bool = False,
525    max_length: int | None = None,
526    required: bool = True,
527    allow_null: Literal[True],
528    default: Any = ...,
529    choices: Any = None,
530    validators: Sequence[Callable[..., Any]] = (),
531    error_messages: dict[str, str] | None = None,
532) -> str | None: ...
533@overload
534def GenericIPAddressField(
535    *,
536    protocol: str = "both",
537    unpack_ipv4: bool = False,
538    max_length: int | None = None,
539    required: bool = True,
540    allow_null: Literal[False] = False,
541    default: Any = ...,
542    choices: Any = None,
543    validators: Sequence[Callable[..., Any]] = (),
544    error_messages: dict[str, str] | None = None,
545) -> str: ...
546@overload
547def JSONField(
548    *,
549    encoder: type[JSONEncoder] | None = None,
550    decoder: type[JSONDecoder] | None = None,
551    max_length: int | None = None,
552    required: bool = True,
553    allow_null: Literal[True],
554    default: Any = ...,
555    choices: Any = None,
556    validators: Sequence[Callable[..., Any]] = (),
557    error_messages: dict[str, str] | None = None,
558) -> Any: ...
559@overload
560def JSONField(
561    *,
562    encoder: type[JSONEncoder] | None = None,
563    decoder: type[JSONDecoder] | None = None,
564    max_length: int | None = None,
565    required: bool = True,
566    allow_null: Literal[False] = False,
567    default: Any = ...,
568    choices: Any = None,
569    validators: Sequence[Callable[..., Any]] = (),
570    error_messages: dict[str, str] | None = None,
571) -> Any: ...
572
573# Encrypted fields
574@overload
575def EncryptedTextField(
576    *,
577    max_length: int | None = None,
578    required: bool = True,
579    allow_null: Literal[True],
580    default: Any = ...,
581    choices: Any = None,
582    validators: Sequence[Callable[..., Any]] = (),
583    error_messages: dict[str, str] | None = None,
584) -> str | None: ...
585@overload
586def EncryptedTextField(
587    *,
588    max_length: int | None = None,
589    required: bool = True,
590    allow_null: Literal[False] = False,
591    default: Any = ...,
592    choices: Any = None,
593    validators: Sequence[Callable[..., Any]] = (),
594    error_messages: dict[str, str] | None = None,
595) -> str: ...
596@overload
597def EncryptedJSONField(
598    *,
599    encoder: type[JSONEncoder] | None = None,
600    decoder: type[JSONDecoder] | None = None,
601    max_length: int | None = None,
602    required: bool = True,
603    allow_null: Literal[True],
604    default: Any = ...,
605    choices: Any = None,
606    validators: Sequence[Callable[..., Any]] = (),
607    error_messages: dict[str, str] | None = None,
608) -> Any: ...
609@overload
610def EncryptedJSONField(
611    *,
612    encoder: type[JSONEncoder] | None = None,
613    decoder: type[JSONDecoder] | None = None,
614    max_length: int | None = None,
615    required: bool = True,
616    allow_null: Literal[False] = False,
617    default: Any = ...,
618    choices: Any = None,
619    validators: Sequence[Callable[..., Any]] = (),
620    error_messages: dict[str, str] | None = None,
621) -> Any: ...
622
623# Related fields
624@overload
625def ForeignKeyField[T: Model](
626    to: type[T] | str,
627    on_delete: Any,
628    *,
629    related_query_name: str | None = None,
630    limit_choices_to: Any = None,
631    db_index: bool = True,
632    db_constraint: bool = True,
633    max_length: int | None = None,
634    required: bool = True,
635    allow_null: Literal[True],
636    default: Any = ...,
637    choices: Any = None,
638    validators: Sequence[Callable[..., Any]] = (),
639    error_messages: dict[str, str] | None = None,
640) -> T | None: ...
641@overload
642def ForeignKeyField[T: Model](
643    to: type[T] | str,
644    on_delete: Any,
645    *,
646    related_query_name: str | None = None,
647    limit_choices_to: Any = None,
648    db_index: bool = True,
649    db_constraint: bool = True,
650    max_length: int | None = None,
651    required: bool = True,
652    allow_null: Literal[False] = False,
653    default: Any = ...,
654    choices: Any = None,
655    validators: Sequence[Callable[..., Any]] = (),
656    error_messages: dict[str, str] | None = None,
657) -> T: ...
658def ManyToManyField[T: Model](
659    to: type[T] | str,
660    *,
661    through: Any,
662    through_fields: tuple[str, str] | None = None,
663    related_query_name: str | None = None,
664    limit_choices_to: Any = None,
665    symmetrical: bool | None = None,
666    max_length: int | None = None,
667    required: bool = True,
668    allow_null: bool = False,
669    default: Any = ...,
670    choices: Any = None,
671    validators: Sequence[Callable[..., Any]] = (),
672    error_messages: dict[str, str] | None = None,
673) -> ManyToManyManager[T]: ...
674
675# Reverse relation descriptors
676class ReverseForeignKey[T: Model, QS: QuerySet[Any] = QuerySet[Any]]:
677    """
678    Descriptor for the reverse side of a ForeignKeyField.
679
680    Type parameters:
681        _T: The related model type
682        _QS: The QuerySet type (use the model's custom QuerySet for proper method typing)
683
684    Example:
685        # With custom QuerySet for proper typing of custom methods like .enabled()
686        repos: ReverseForeignKey[Repo, RepoQuerySet] = ReverseForeignKey(to="Repo", field="organization")
687
688        # Usage: org.repos.query.enabled()  # .enabled() is now recognized
689    """
690    def __init__(self, *, to: type[T] | str, field: str) -> None: ...
691    @overload
692    def __get__(self, instance: None, owner: type) -> ReverseForeignKey[T, QS]: ...
693    @overload
694    def __get__(
695        self, instance: Model, owner: type
696    ) -> ReverseForeignKeyManager[T, QS]: ...
697    def __get__(
698        self, instance: Model | None, owner: type
699    ) -> ReverseForeignKey[T, QS] | ReverseForeignKeyManager[T, QS]: ...
700
701class ReverseManyToMany[T: Model, QS: QuerySet[Any] = QuerySet[Any]]:
702    """
703    Descriptor for the reverse side of a ManyToManyField.
704
705    Type parameters:
706        _T: The related model type
707        _QS: The QuerySet type (use the model's custom QuerySet for proper method typing)
708    """
709    def __init__(self, *, to: type[T] | str, field: str) -> None: ...
710    @overload
711    def __get__(self, instance: None, owner: type) -> ReverseManyToMany[T, QS]: ...
712    @overload
713    def __get__(self, instance: Model, owner: type) -> ManyToManyManager[T, QS]: ...
714    def __get__(
715        self, instance: Model | None, owner: type
716    ) -> ReverseManyToMany[T, QS] | ManyToManyManager[T, QS]: ...
717
718# Export all types (should match types.py)
719__all__ = [
720    "BigIntegerField",
721    "BinaryField",
722    "BooleanField",
723    "CharField",
724    "DateField",
725    "DateTimeField",
726    "DecimalField",
727    "DurationField",
728    "EmailField",
729    "EncryptedJSONField",
730    "EncryptedTextField",
731    "FloatField",
732    "ForeignKeyField",
733    "GenericIPAddressField",
734    "IntegerField",
735    "JSONField",
736    "ManyToManyField",
737    "ManyToManyManager",
738    "PositiveBigIntegerField",
739    "PositiveIntegerField",
740    "PositiveSmallIntegerField",
741    "PrimaryKeyField",
742    "ReverseForeignKey",
743    "ReverseForeignKeyManager",
744    "ReverseManyToMany",
745    "SmallIntegerField",
746    "TextField",
747    "TimeField",
748    "TimeZoneField",
749    "URLField",
750    "UUIDField",
751]