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