diff --git a/stubs/peewee/@tests/stubtest_allowlist.txt b/stubs/peewee/@tests/stubtest_allowlist.txt index 06bd8788cae5..63e6f01a49f3 100644 --- a/stubs/peewee/@tests/stubtest_allowlist.txt +++ b/stubs/peewee/@tests/stubtest_allowlist.txt @@ -22,6 +22,20 @@ peewee.SelectBase.peek peewee.SelectBase.scalar peewee.SelectBase.scalars +# Descriptor methods exist on FieldAccessor at runtime, but are declared on the +# generic Field classes in the stub so that `instance.field` resolves to the +# field's Python value and `Model.field` resolves to the field (for queries). +peewee.Field.__get__ +peewee.Field.__set__ +# BigBitField overrides __get__ to yield a BigBitFieldData wrapper, not bytes. +peewee.BigBitField.__get__ +peewee.Field.__init__ +# These fields take named constructor args, carried by their __new__ overloads. +peewee.CharField.__init__ +peewee.ForeignKeyField.__init__ +peewee.DecimalField.__init__ +peewee.IdentityField.__init__ + # Ignore missing playhouse modules and names we don't currently provide playhouse\.\w+? playhouse.flask_utils.PaginatedQuery diff --git a/stubs/peewee/METADATA.toml b/stubs/peewee/METADATA.toml index 4bb0e2ed3ad3..2afd31f409f6 100644 --- a/stubs/peewee/METADATA.toml +++ b/stubs/peewee/METADATA.toml @@ -1,4 +1,4 @@ -version = "4.0.5" +version = "4.0.8" upstream-repository = "https://github.com/coleifer/peewee" # We're not providing stubs for all playhouse modules right now # https://github.com/python/typeshed/pull/11731#issuecomment-2065729058 diff --git a/stubs/peewee/peewee.pyi b/stubs/peewee/peewee.pyi index 816b7a7e8d0c..99398277f060 100644 --- a/stubs/peewee/peewee.pyi +++ b/stubs/peewee/peewee.pyi @@ -2,11 +2,11 @@ import re import threading from _typeshed import Incomplete, SupportsKeysAndGetItem, Unused from collections.abc import Callable, Generator, Iterable, Iterator -from datetime import datetime +from datetime import date, datetime, time from decimal import Decimal from types import TracebackType -from typing import Any, ClassVar, Final, Literal, NamedTuple, NoReturn, TypeVar, overload, type_check_only -from typing_extensions import Self, TypeIs +from typing import Any, ClassVar, Final, Generic, Literal, NamedTuple, NoReturn, TypedDict, overload, type_check_only +from typing_extensions import Self, TypeIs, TypeVar, Unpack from uuid import UUID def callable_(c: object) -> TypeIs[Callable[..., object]]: ... @@ -18,6 +18,41 @@ def reraise(tp: Unused, value: BaseException, tb: TracebackType | None = None) - _T = TypeVar("_T") _VT = TypeVar("_VT") _F = TypeVar("_F", bound=Callable[..., Any]) +_M = TypeVar("_M", bound=Model, default=Model) +# __get__/__set__ value type. Bare Field defaults to Field[Any]. +_V = TypeVar("_V", default=Any) + +# Common field kwargs, Unpack-ed into the field __new__ overloads. +@type_check_only +class _FieldKwargs(TypedDict, total=False): + index: bool + unique: bool + primary_key: bool + column_name: str | None + default: Any + constraints: list[Node] | None + sequence: str | None + collation: str | None + unindexed: bool + choices: Iterable[tuple[Any, str]] | None + help_text: str | None + verbose_name: str | None + index_type: str | None + db_column: str | None + +@type_check_only +class _FKKwargs(_FieldKwargs, total=False): + field: Field[Any] | str | None + backref: str | Callable[[Field[Any]], str] | None + on_delete: str | None + on_update: str | None + deferrable: str | None + to_field: Field[Any] | str | None + object_id_name: str | None + lazy_load: bool + constraint_name: str | None + related_name: str | Callable[[Field[Any]], str] | None + rel_model: type[Model] | None class attrdict(dict[str, _VT]): def __getattr__(self, attr: str) -> _VT: ... @@ -42,7 +77,6 @@ CSQ_PARENTHESES_UNNESTED: Final = 2 SNAKE_CASE_STEP1: Final[re.Pattern[str]] SNAKE_CASE_STEP2: Final[re.Pattern[str]] IDENTIFIER_RE: Final[re.Pattern[str]] -MODEL_BASE: Final = "_metaclass_helper_" def make_identifier(s: str) -> str: ... def chunked(it, n) -> Generator[list[Incomplete]]: ... @@ -230,7 +264,7 @@ class ValuesList(_HashableSource, BaseTable): # type: ignore[misc] class CTE(_HashableSource, Source): # type: ignore[misc] def __init__(self, name, query, recursive: bool = False, columns=None, materialized=None) -> None: ... - def select_from(self, *columns): ... + def select_from(self, *columns) -> Select: ... def union_all(self, rhs) -> CTE: ... __add__ = union_all def union(self, rhs) -> CTE: ... @@ -239,7 +273,7 @@ class CTE(_HashableSource, Source): # type: ignore[misc] class ColumnBase(Node): def converter(self, converter=None) -> Self: ... - def alias(self, alias): ... + def alias(self, alias) -> Alias | Self: ... def unalias(self) -> Self: ... def bind_to(self, dest) -> BindTo: ... def cast(self, as_type) -> Cast: ... @@ -248,10 +282,10 @@ class ColumnBase(Node): def desc(self, collation=None, nulls=None) -> Ordering: ... __neg__ = desc def __invert__(self): ... - __and__: Incomplete - __or__: Incomplete + __and__: ClassVar[Callable[[Self, Any], Expression]] + __or__: ClassVar[Callable[[Self, Any], Expression]] def __add__(self, rhs: Any) -> Expression: ... - __sub__: Incomplete + __sub__: ClassVar[Callable[[Self, Any], Expression]] __mul__: ClassVar[Callable[[Self, Any], Expression]] __div__: ClassVar[Callable[[Self, Any], Expression]] __truediv__: ClassVar[Callable[[Self, Any], Expression]] @@ -343,9 +377,9 @@ class Negated(WrappedNode): def __sql__(self, ctx): ... class BitwiseMixin: - def __and__(self, other): ... - def __or__(self, other): ... - def __sub__(self, other): ... + def __and__(self, other) -> Expression: ... + def __or__(self, other) -> Expression: ... + def __sub__(self, other) -> Expression: ... def __invert__(self) -> BitwiseNegated: ... class BitwiseNegated(BitwiseMixin, WrappedNode): @@ -403,15 +437,16 @@ class SQL(ColumnBase): def __init__(self, sql, params=None) -> None: ... def __sql__(self, ctx): ... -def Check(constraint, name=None): ... +def Check(constraint, name=None) -> Node: ... def Default(value) -> SQL: ... class Function(ColumnBase): no_coerce_functions: ClassVar[set[str]] - name: Incomplete - arguments: Incomplete + name: str | None + arguments: tuple[Any, ...] | None def __init__(self, name, arguments, coerce: bool = True, python_value=None) -> None: ... - def __getattr__(self, attr: str): ... + # fn.COUNT(...), fn.SUM(...), etc. each build a Function node. + def __getattr__(self, attr: str) -> Callable[..., Function]: ... def filter(self, where=None) -> Self: ... def order_by(self, *ordering) -> Self: ... def python_value(self, func=None) -> Self: ... @@ -420,7 +455,7 @@ class Function(ColumnBase): ) -> NodeList: ... def __sql__(self, ctx): ... -fn: Incomplete +fn: Function class Window(Node): CURRENT_ROW: SQL @@ -536,8 +571,9 @@ class BaseQuery(Node): def namedtuples(self, as_namedtuple: bool = True) -> Self: ... def objects(self, constructor=None) -> Self: ... def __sql__(self, ctx) -> None: ... - def sql(self): ... + def sql(self) -> tuple[str, list[Any]]: ... def execute(self, database=None): ... + async def aexecute(self, database=None): ... def iterator(self, database=None): ... def __iter__(self): ... def __getitem__(self, value): ... @@ -756,6 +792,7 @@ class ConnectionContext(_callable_context_manager): class Database(_callable_context_manager): context_class: Incomplete + json_methods: Incomplete field_types: Incomplete operations: Incomplete param: str @@ -1043,8 +1080,10 @@ class _manual(_callable_context_manager): class _atomic(_callable_context_manager): db: Incomplete def __init__(self, db, *args, **kwargs) -> None: ... - def __enter__(self): ... - def __exit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None): ... + def __enter__(self) -> _transaction | _savepoint: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> None: ... class _transaction(_callable_context_manager): db: Incomplete @@ -1141,7 +1180,13 @@ class ObjectIdAccessor: def __get__(self, instance, instance_type=None): ... def __set__(self, instance, value) -> None: ... -class Field(ColumnBase): +class Field(ColumnBase, Generic[_V]): + @overload + def __get__(self, instance: None, owner: Any) -> Self: ... + @overload + def __get__(self, instance: object, owner: Any) -> _V: ... + + def __set__(self, instance: object, value: _V) -> None: ... accessor_class: Incomplete auto_increment: bool default_index_type: Incomplete @@ -1161,25 +1206,8 @@ class Field(ColumnBase): help_text: Incomplete verbose_name: Incomplete index_type: Incomplete - def __init__( - self, - null: bool = False, - index: bool = False, - unique: bool = False, - column_name=None, - default=None, - primary_key: bool = False, - constraints=None, - sequence=None, - collation=None, - unindexed: bool = False, - choices=None, - help_text=None, - verbose_name=None, - index_type=None, - db_column=None, - _hidden: bool = False, - ) -> None: ... + # Field constructor args are typed per-field in the __new__ overloads. + def __init__(self, *args: Any, **kwargs: Any) -> None: ... def __hash__(self) -> int: ... model: Incomplete name: Incomplete @@ -1198,64 +1226,144 @@ class Field(ColumnBase): class AnyField(Field): ... -class IntegerField(Field): +class IntegerField(Field[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> IntegerField[int | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> IntegerField[int]: ... + def adapt(self, value): ... -class BigIntegerField(IntegerField): ... -class SmallIntegerField(IntegerField): ... +class BigIntegerField(IntegerField[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> BigIntegerField[int | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> BigIntegerField[int]: ... -class AutoField(IntegerField): +class SmallIntegerField(IntegerField[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> SmallIntegerField[int | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> SmallIntegerField[int]: ... + +class AutoField(IntegerField[_V]): auto_increment: bool - def __init__(self, *args, **kwargs) -> None: ... + def __new__(cls, *args: Any, **kwargs: Unpack[_FieldKwargs]) -> AutoField[int]: ... -class BigAutoField(AutoField): ... +class BigAutoField(AutoField[_V]): + def __new__(cls, *args: Any, **kwargs: Unpack[_FieldKwargs]) -> BigAutoField[int]: ... -class IdentityField(AutoField): - def __init__(self, generate_always: bool = False, **kwargs) -> None: ... +class IdentityField(AutoField[_V]): + def __new__(cls, *args: Any, **kwargs: Unpack[_FieldKwargs]) -> IdentityField[int]: ... -class PrimaryKeyField(AutoField): - def __init__(self, *args, **kwargs) -> None: ... +class PrimaryKeyField(AutoField[_V]): + def __new__(cls, *args: Any, **kwargs: Unpack[_FieldKwargs]) -> PrimaryKeyField[int]: ... + +class FloatField(Field[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> FloatField[float | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> FloatField[float]: ... -class FloatField(Field): def adapt(self, value): ... -class DoubleField(FloatField): ... +class DoubleField(FloatField[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> DoubleField[float | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> DoubleField[float]: ... -class DecimalField(Field): +class DecimalField(Field[_V]): max_digits: Incomplete decimal_places: Incomplete auto_round: Incomplete rounding: Incomplete - def __init__( - self, max_digits: int = 10, decimal_places: int = 5, auto_round: bool = False, rounding=None, *args, **kwargs - ) -> None: ... + + @overload + def __new__( + cls, + max_digits: int = ..., + decimal_places: int = ..., + auto_round: bool = ..., + rounding: Any = ..., + *args: Any, + null: Literal[True], + **kwargs: Unpack[_FieldKwargs], + ) -> DecimalField[Decimal | None]: ... + @overload + def __new__( + cls, + max_digits: int = ..., + decimal_places: int = ..., + auto_round: bool = ..., + rounding: Any = ..., + *args: Any, + null: Literal[False] = ..., + **kwargs: Unpack[_FieldKwargs], + ) -> DecimalField[Decimal]: ... + def get_modifiers(self) -> list[int]: ... def db_value(self, value): ... def python_value(self, value) -> Decimal | None: ... -class _StringField(Field): +class _StringField(Field[_V]): def adapt(self, value) -> str: ... def __add__(self, other) -> StringExpression: ... def __radd__(self, other) -> StringExpression: ... -class CharField(_StringField): +class CharField(_StringField[_V]): max_length: int - def __init__(self, max_length: int = 255, *args, **kwargs) -> None: ... + + @overload + def __new__( + cls, max_length: int = 255, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs] + ) -> CharField[str | None]: ... + @overload + def __new__( + cls, max_length: int = 255, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs] + ) -> CharField[str]: ... + def get_modifiers(self) -> list[int] | None: ... -class FixedCharField(CharField): +class FixedCharField(CharField[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> FixedCharField[str | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> FixedCharField[str]: ... + def adapt(self, value) -> str: ... -class TextField(_StringField): ... +class TextField(_StringField[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> TextField[str | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> TextField[str]: ... class FieldDatabaseHook: def bind(self, model, name, set_attribute: bool = True): ... -class BlobField(FieldDatabaseHook, Field): +class BlobField(FieldDatabaseHook, Field[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> BlobField[bytes | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> BlobField[bytes]: ... + def db_value(self, value): ... -class BitField(BitwiseMixin, BigIntegerField): - def __init__(self, *args, **kwargs) -> None: ... +class JSONField(FieldDatabaseHook, Field): + def __init__(self, dumps=None, loads=None, **kwargs) -> None: ... + def path(self, *keys): ... + def length(self) -> Expression: ... + def append(self, value) -> Expression: ... + def update(self, value) -> Expression: ... + def contains(self, value) -> Expression: ... # type: ignore[override] + def contained_by(self, value) -> Expression: ... + def has_key(self, key) -> Expression: ... + def has_keys(self, key_list) -> Expression: ... + def has_any_keys(self, key_list) -> Expression: ... + +class BitField(BitwiseMixin, BigIntegerField[_V]): + def __new__(cls, *args: Any, **kwargs: Unpack[_FieldKwargs]) -> BitField[int]: ... def flag(self, value=None): ... class BigBitFieldData: @@ -1281,24 +1389,49 @@ class BigBitFieldAccessor(FieldAccessor): def __get__(self, instance, instance_type=None): ... def __set__(self, instance, value) -> None: ... -class BigBitField(BlobField): +class BigBitField(BlobField[bytes]): accessor_class: Incomplete - def __init__(self, *args, **kwargs) -> None: ... + def __new__(cls, *args: Any, **kwargs: Unpack[_FieldKwargs]) -> Self: ... + + @overload # type: ignore[override] + def __get__(self, instance: None, owner: Any) -> Self: ... + @overload + def __get__(self, instance: object, owner: Any) -> BigBitFieldData: ... + def db_value(self, value): ... -class UUIDField(Field): +class UUIDField(Field[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> UUIDField[UUID | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> UUIDField[UUID]: ... + def db_value(self, value): ... def python_value(self, value) -> UUID | None: ... -class BinaryUUIDField(BlobField): +class BinaryUUIDField(BlobField[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> BinaryUUIDField[UUID | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> BinaryUUIDField[UUID]: ... + def db_value(self, value): ... def python_value(self, value) -> UUID | None: ... -class _BaseFormattedField(Field): +class _BaseFormattedField(Field[_V]): formats: Incomplete def __init__(self, formats=None, *args, **kwargs) -> None: ... -class DateTimeField(_BaseFormattedField): +class DateTimeField(_BaseFormattedField[_V]): + @overload + def __new__( + cls, formats: Any = ..., *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs] + ) -> DateTimeField[datetime | None]: ... + @overload + def __new__( + cls, formats: Any = ..., *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs] + ) -> DateTimeField[datetime]: ... + formats: Incomplete def adapt(self, value): ... def to_timestamp(self): ... @@ -1316,7 +1449,16 @@ class DateTimeField(_BaseFormattedField): @property def second(self): ... -class DateField(_BaseFormattedField): +class DateField(_BaseFormattedField[_V]): + @overload + def __new__( + cls, formats: Any = ..., *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs] + ) -> DateField[date | None]: ... + @overload + def __new__( + cls, formats: Any = ..., *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs] + ) -> DateField[date]: ... + formats: Incomplete def adapt(self, value): ... def to_timestamp(self): ... @@ -1328,7 +1470,16 @@ class DateField(_BaseFormattedField): @property def day(self): ... -class TimeField(_BaseFormattedField): +class TimeField(_BaseFormattedField[_V]): + @overload + def __new__( + cls, formats: Any = ..., *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs] + ) -> TimeField[time | None]: ... + @overload + def __new__( + cls, formats: Any = ..., *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs] + ) -> TimeField[time]: ... + formats: Incomplete def adapt(self, value): ... @property @@ -1338,12 +1489,17 @@ class TimeField(_BaseFormattedField): @property def second(self): ... -class TimestampField(BigIntegerField): +class TimestampField(BigIntegerField[_V]): valid_resolutions: Incomplete resolution: Incomplete ticks_to_microsecond: Incomplete utc: Incomplete - def __init__(self, *args, **kwargs) -> None: ... + + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> TimestampField[datetime | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> TimestampField[datetime]: ... + def local_to_utc(self, dt) -> datetime: ... def utc_to_local(self, dt) -> datetime: ... def get_timestamp(self, value) -> float: ... @@ -1363,11 +1519,21 @@ class TimestampField(BigIntegerField): @property def second(self): ... -class IPField(BigIntegerField): +class IPField(BigIntegerField[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> IPField[str | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> IPField[str]: ... + def db_value(self, val): ... def python_value(self, val) -> str | None: ... -class BooleanField(Field): +class BooleanField(Field[_V]): + @overload + def __new__(cls, *args: Any, null: Literal[True], **kwargs: Unpack[_FieldKwargs]) -> BooleanField[bool | None]: ... + @overload + def __new__(cls, *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FieldKwargs]) -> BooleanField[bool]: ... + adapt: Incomplete class BareField(Field): @@ -1375,7 +1541,7 @@ class BareField(Field): def __init__(self, adapt=None, *args, **kwargs) -> None: ... def ddl_datatype(self, ctx): ... -class ForeignKeyField(Field): +class ForeignKeyField(Field[_V]): accessor_class: Incomplete backref_accessor_class: Incomplete rel_model: Incomplete @@ -1389,24 +1555,18 @@ class ForeignKeyField(Field): object_id_name: Incomplete lazy_load: Incomplete constraint_name: str | None - def __init__( - self, - model, - field=None, - backref=None, - on_delete=None, - on_update=None, - deferrable=None, - _deferred=None, - rel_model=None, - to_field=None, - object_id_name=None, - lazy_load: bool = True, - constraint_name: str | None = None, - related_name=None, - *args, - **kwargs, - ) -> None: ... + + @overload + def __new__( + cls, model: type[_M], *args: Any, null: Literal[True], **kwargs: Unpack[_FKKwargs] + ) -> ForeignKeyField[_M | None]: ... + @overload + def __new__( + cls, model: type[_M], *args: Any, null: Literal[False] = ..., **kwargs: Unpack[_FKKwargs] + ) -> ForeignKeyField[_M]: ... + @overload + def __new__(cls, model: Any = ..., *args: Any, **kwargs: Unpack[_FKKwargs]) -> ForeignKeyField[Any]: ... + @property def field_type(self): ... # type: ignore[override] def get_modifiers(self): ... @@ -1538,7 +1698,7 @@ class SchemaManager: def drop_all(self, safe: bool = True, drop_sequences: bool = True, **options) -> None: ... class Metadata: - model: Incomplete + model: type[Model] database: Incomplete fields: Incomplete columns: Incomplete @@ -1552,7 +1712,7 @@ class Metadata: table_name: Incomplete indexes: Incomplete constraints: Incomplete - primary_key: Incomplete + primary_key: Field[Any] | Literal[False] composite_key: Incomplete only_save_dirty: Incomplete depends_on: Incomplete @@ -1602,7 +1762,7 @@ class Metadata: def table(self) -> None: ... @property - def schema(self): ... + def schema(self) -> str | None: ... @schema.setter def schema(self, value) -> None: ... @@ -1660,7 +1820,7 @@ class Model(metaclass=ModelBase): @classmethod def alias(cls, alias=None) -> ModelAlias: ... @classmethod - def select(cls, *fields) -> ModelSelect: ... + def select(cls, *fields) -> ModelSelect[Self]: ... @classmethod def update(cls, data=None, /, **update) -> ModelUpdate: ... @classmethod @@ -1686,11 +1846,11 @@ class Model(metaclass=ModelBase): @classmethod def noop(cls) -> NoopModelSelect: ... @classmethod - def get(cls, *query, **filters): ... + def get(cls, *query, **filters) -> Self: ... @classmethod - def get_or_none(cls, *query, **filters): ... + def get_or_none(cls, *query, **filters) -> Self | None: ... @classmethod - def get_by_id(cls, pk): ... + def get_by_id(cls, pk) -> Self: ... @classmethod def set_by_id(cls, key, value): ... @classmethod @@ -1700,14 +1860,14 @@ class Model(metaclass=ModelBase): @classmethod def filter(cls, *dq_nodes, **filters): ... def get_id(self): ... - def save(self, force_insert: bool = False, only=None): ... + def save(self, force_insert: bool = False, only=None) -> int: ... def is_dirty(self) -> bool: ... @property - def dirty_fields(self) -> list[Incomplete]: ... + def dirty_fields(self) -> list[Field[Any]]: ... @property - def dirty_field_names(self) -> list[Incomplete]: ... + def dirty_field_names(self) -> list[str]: ... def dependencies(self, search_nullable: bool = True, exclude_null_children: bool = False) -> Generator[Incomplete]: ... - def delete_instance(self, recursive: bool = False, delete_nullable: bool = False): ... + def delete_instance(self, recursive: bool = False, delete_nullable: bool = False) -> int: ... def __hash__(self) -> int: ... def __eq__(self, other) -> Expression | bool: ... # type: ignore[override] def __ne__(self, other) -> Expression | bool: ... # type: ignore[override] @@ -1761,7 +1921,7 @@ class _ModelQueryHelper: class ModelRaw(_ModelQueryHelper, RawQuery): # type: ignore[misc] model: Incomplete def __init__(self, model, sql, params, **kwargs) -> None: ... - def get(self): ... + def get(self) -> Model: ... class BaseModelSelect(_ModelQueryHelper): def union_all(self, rhs) -> ModelCompoundSelectQuery: ... @@ -1782,19 +1942,22 @@ class ModelCompoundSelectQuery(BaseModelSelect, CompoundSelectQuery): # type: i model: Incomplete def __init__(self, model, *args, **kwargs) -> None: ... -class ModelSelect(BaseModelSelect, Select): # type: ignore[misc] - model: Incomplete +class ModelSelect(BaseModelSelect, Select, Generic[_M]): # type: ignore[misc] + model: type[_M] def __init__(self, model, fields_or_models, is_default: bool = False) -> None: ... + def __iter__(self) -> Iterator[_M]: ... + def get(self, database=None) -> _M: ... + def get_or_none(self, database=None) -> _M | None: ... def clone(self) -> Self: ... - def select(self, *fields_or_models): ... - def select_extend(self, *columns): ... + def select(self, *fields_or_models) -> ModelSelect[_M]: ... + def select_extend(self, *columns) -> Self: ... def switch(self, ctx=None) -> Self: ... def join(self, dest, join_type="INNER JOIN", on=None, src=None, attr=None) -> Self: ... # type: ignore[override] def left_outer_join(self, dest, on=None, src=None, attr=None) -> Self: ... # type: ignore[override] def join_from(self, src, dest, join_type="INNER JOIN", on=None, attr=None) -> Self: ... def ensure_join(self, lm, rm, on=None, **join_kwargs): ... def convert_dict_to_node(self, qdict) -> tuple[list[Incomplete], list[Incomplete]]: ... - def filter(self, *args, **kwargs): ... + def filter(self, *args, **kwargs) -> Self: ... def create_table(self, name, safe: bool = True, **meta): ... def __sql_selection__(self, ctx, is_subquery: bool = False): ... @@ -1804,14 +1967,14 @@ class NoopModelSelect(ModelSelect): class _ModelWriteQueryHelper(_ModelQueryHelper): model: Incomplete def __init__(self, model, *args, **kwargs) -> None: ... - def returning(self, *returning): ... + def returning(self, *returning) -> Self: ... class ModelUpdate(_ModelWriteQueryHelper, Update): ... # type: ignore[misc] class ModelInsert(_ModelWriteQueryHelper, Insert): # type: ignore[misc] default_row_type: Incomplete def __init__(self, *args, **kwargs) -> None: ... - def returning(self, *returning): ... + def returning(self, *returning) -> Self: ... def get_default_data(self): ... def get_default_columns(self): ... @@ -1938,6 +2101,7 @@ __all__ = [ "InternalError", "IPField", "JOIN", + "JSONField", "ManyToManyField", "Model", "ModelIndex",