diff --git a/odoo-stubs/fields.pyi b/odoo-stubs/fields.pyi index 70b74d2..e6ec96e 100644 --- a/odoo-stubs/fields.pyi +++ b/odoo-stubs/fields.pyi @@ -1,6 +1,6 @@ import datetime import enum -from typing import Any, Callable, Container, Collection, Iterator, Sequence, Type, TypeVar, Union +from typing import Any, Callable, Container, Collection, Generic, Iterator, Sequence, Type, TypeVar, Union, overload import psycopg2 from markupsafe import Markup @@ -9,6 +9,8 @@ from .api import Environment, Registry from .models import BaseModel from .tools import date_utils, float_utils +_FieldT = TypeVar('_FieldT', bound=Field) +_FieldValueT = TypeVar('_FieldValueT') _ModelT = TypeVar('_ModelT', bound=BaseModel) _Selection = list[tuple[str, str]] _SelectionRaw = _Selection | Callable[..., _Selection] | str @@ -32,7 +34,7 @@ class MetaField(type): by_type: dict def __init__(cls: type[Field], name, bases, attrs) -> None: ... -class Field(metaclass=MetaField): +class Field(Generic[_FieldValueT], metaclass=MetaField): type: str | None relational: bool translate: bool @@ -157,7 +159,10 @@ class Field(metaclass=MetaField): def read(self, records: BaseModel) -> None: ... def create(self, record_values: list[tuple[BaseModel, Any]]) -> None: ... def write(self, records: _ModelT, value) -> _ModelT: ... - def __get__(self, record: Union[BaseModel, None], owner): ... + @overload + def __get__(self, record: BaseModel, owner) -> _FieldValueT: ... + @overload + def __get__(self: _FieldT, records: None, owner) -> _FieldT: ... def mapped(self, records: BaseModel): ... def __set__(self, records: BaseModel, value): ... def recompute(self, records: BaseModel) -> None: ... @@ -165,14 +170,14 @@ class Field(metaclass=MetaField): def determine_inverse(self, records: BaseModel) -> None: ... def determine_domain(self, records: BaseModel, operator: str, value) -> list: ... -class Boolean(Field): +class Boolean(Field[bool]): type: str column_type: tuple[str, str] def convert_to_column(self, value, record: BaseModel, values: Any | None = ..., validate: bool = ...) -> bool: ... def convert_to_cache(self, value, record: BaseModel, validate: bool = ...) -> bool: ... def convert_to_export(self, value, record: BaseModel): ... -class Integer(Field): +class Integer(Field[int]): type: str column_type: tuple[str, str] group_operator: str @@ -183,7 +188,7 @@ class Integer(Field): def _update(self, records: BaseModel, value) -> None: ... def convert_to_export(self, value, record): ... -class Float(Field): +class Float(Field[float]): type: str _digits: tuple[int, int] | str | None group_operator: str @@ -201,7 +206,7 @@ class Float(Field): is_zero = float_utils.float_is_zero compare = float_utils.float_compare -class Monetary(Field): +class Monetary(Field[float]): type: str write_sequence: int column_type: tuple[str, str] @@ -218,7 +223,7 @@ class Monetary(Field): def convert_to_read(self, value, record: BaseModel, use_name_get: bool = ...): ... def convert_to_write(self, value, record: BaseModel): ... -class _String(Field): +class _String(Field[str]): translate: Callable | bool unaccent: bool def __init__(self, string: str = ..., **kwargs) -> None: ... @@ -289,7 +294,7 @@ class Html(_String): def convert_to_read(self, value, record: BaseModel, use_name_get: bool = ...) -> Markup | None: ... def get_trans_terms(self, value) -> list: ... -class Date(Field): +class Date(Field[datetime.date]): type: str column_type: tuple[str, str] start_of = date_utils.start_of @@ -308,7 +313,7 @@ class Date(Field): def convert_to_cache(self, value, record: BaseModel, validate: bool = ...) -> datetime.date | None: ... def convert_to_export(self, value, record: BaseModel): ... -class Datetime(Field): +class Datetime(Field[datetime.datetime]): type: str column_type: tuple[str, str] start_of = date_utils.start_of @@ -332,7 +337,7 @@ class Datetime(Field): _BINARY = memoryview -class Binary(Field): +class Binary(Field[bytes]): type: str prefetch: bool _depends_context: tuple[str] @@ -358,7 +363,7 @@ class Image(Binary): def _image_process(self, value): ... def _process_related(self, value): ... -class Selection(Field): +class Selection(Field[str]): type: str column_type: tuple[str, str] selection: _SelectionRaw @@ -388,12 +393,11 @@ class Reference(Selection): def convert_to_export(self, value, record: BaseModel) -> str: ... def convert_to_display_name(self, value, record: BaseModel) -> str: ... -class _Relational(Field): +class _Relational(Field[BaseModel]): relational: bool domain: _DomainRaw context: dict check_company: bool - def __get__(self, records: Union[BaseModel, None], owner) -> BaseModel: ... comodel_name: str def setup_nonrelated(self, model: BaseModel) -> None: ... def get_domain_list(self, model: BaseModel) -> _Domain: ... @@ -576,7 +580,7 @@ class Many2many(_RelationalMulti): def write_real(self, records_commands_list: _CommandList, create: bool = ...): ... def write_new(self, records_commands_list: _CommandList): ... -class Id(Field): +class Id(Field[int]): type: str column_type: tuple[str, str] string: str @@ -584,7 +588,6 @@ class Id(Field): readonly: bool prefetch: bool def update_db(self, model: BaseModel, columns) -> None: ... - def __get__(self, record: BaseModel, owner): ... def __set__(self, record: BaseModel, value) -> None: ... class PrefetchMany2one: