From d1e3a7ffea79cde9280ab246fa18c4bccb8e0f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tin=20Tvrtkovi=C4=87?= Date: Sat, 3 Feb 2024 00:25:27 +0100 Subject: [PATCH 1/6] Tweak stubs for better VS Code import --- src/attr/__init__.pyi | 406 +++++++++++------------------------------ src/attrs/__init__.pyi | 236 +++++++++++++++++++++--- 2 files changed, 312 insertions(+), 330 deletions(-) diff --git a/src/attr/__init__.pyi b/src/attr/__init__.pyi index 37a208732..14e53a8d2 100644 --- a/src/attr/__init__.pyi +++ b/src/attr/__init__.pyi @@ -4,17 +4,11 @@ import sys from typing import ( Any, Callable, - Dict, Generic, - List, Mapping, - Optional, Protocol, Sequence, - Tuple, - Type, TypeVar, - Union, overload, ) @@ -27,6 +21,20 @@ from . import validators as validators from ._cmp import cmp_using as cmp_using from ._typing_compat import AttrsInstance_ from ._version_info import VersionInfo +from attrs import ( + define as define, + field as field, + mutable as mutable, + frozen as frozen, + _EqOrderType, + _ValidatorType, + _ConverterType, + _ReprArgType, + _OnSetAttrType, + _OnSetAttrArgType, + _FieldTransformer, + _ValidatorArgType, +) if sys.version_info >= (3, 10): from typing import TypeGuard @@ -52,23 +60,7 @@ __copyright__: str _T = TypeVar("_T") _C = TypeVar("_C", bound=type) -_EqOrderType = Union[bool, Callable[[Any], Any]] -_ValidatorType = Callable[[Any, "Attribute[_T]", _T], Any] -_ConverterType = Callable[[Any], Any] _FilterType = Callable[["Attribute[_T]", _T], bool] -_ReprType = Callable[[Any], str] -_ReprArgType = Union[bool, _ReprType] -_OnSetAttrType = Callable[[Any, "Attribute[Any]", Any], Any] -_OnSetAttrArgType = Union[ - _OnSetAttrType, List[_OnSetAttrType], setters._NoOpType -] -_FieldTransformer = Callable[ - [type, List["Attribute[Any]"]], List["Attribute[Any]"] -] -# FIXME: in reality, if multiple validators are passed they must be in a list -# or tuple, but those are invariant and so would prevent subtypes of -# _ValidatorType from working when passed in a list or tuple. -_ValidatorArgType = Union[_ValidatorType[_T], Sequence[_ValidatorType[_T]]] # We subclass this here to keep the protocol's qualified name clean. class AttrsInstance(AttrsInstance_, Protocol): @@ -110,20 +102,20 @@ else: class Attribute(Generic[_T]): name: str - default: Optional[_T] - validator: Optional[_ValidatorType[_T]] + default: _T | None + validator: _ValidatorType[_T] | None repr: _ReprArgType cmp: _EqOrderType eq: _EqOrderType order: _EqOrderType - hash: Optional[bool] + hash: bool | None init: bool - converter: Optional[_ConverterType] - metadata: Dict[Any, Any] - type: Optional[Type[_T]] + converter: _ConverterType | None + metadata: dict[Any, Any] + type: type[_T] | None kw_only: bool on_setattr: _OnSetAttrType - alias: Optional[str] + alias: str | None def evolve(self, **changes: Any) -> "Attribute[Any]": ... @@ -156,18 +148,18 @@ def attrib( default: None = ..., validator: None = ..., repr: _ReprArgType = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., + metadata: Mapping[Any, Any] | None = ..., type: None = ..., converter: None = ..., factory: None = ..., kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - alias: Optional[str] = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., ) -> Any: ... # This form catches an explicit None or no default and infers the type from the @@ -175,149 +167,70 @@ def attrib( @overload def attrib( default: None = ..., - validator: Optional[_ValidatorArgType[_T]] = ..., + validator: _ValidatorArgType[_T] | None = ..., repr: _ReprArgType = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - type: Optional[Type[_T]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., + metadata: Mapping[Any, Any] | None = ..., + type: type[_T] | None = ..., + converter: _ConverterType | None = ..., + factory: Callable[[], _T] | None = ..., kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - alias: Optional[str] = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., ) -> _T: ... # This form catches an explicit default argument. @overload def attrib( default: _T, - validator: Optional[_ValidatorArgType[_T]] = ..., + validator: _ValidatorArgType[_T] | None = ..., repr: _ReprArgType = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - type: Optional[Type[_T]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., + metadata: Mapping[Any, Any] | None = ..., + type: type[_T] | None = ..., + converter: _ConverterType | None = ..., + factory: Callable[[], _T] | None = ..., kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - alias: Optional[str] = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., ) -> _T: ... # This form covers type=non-Type: e.g. forward references (str), Any @overload def attrib( - default: Optional[_T] = ..., - validator: Optional[_ValidatorArgType[_T]] = ..., + default: _T | None = ..., + validator: _ValidatorArgType[_T] | None = ..., repr: _ReprArgType = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., + metadata: Mapping[Any, Any] | None = ..., type: object = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - alias: Optional[str] = ..., -) -> Any: ... -@overload -def field( - *, - default: None = ..., - validator: None = ..., - repr: _ReprArgType = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - converter: None = ..., - factory: None = ..., - kw_only: bool = ..., - eq: Optional[bool] = ..., - order: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - alias: Optional[str] = ..., - type: Optional[type] = ..., -) -> Any: ... - -# This form catches an explicit None or no default and infers the type from the -# other arguments. -@overload -def field( - *, - default: None = ..., - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - alias: Optional[str] = ..., - type: Optional[type] = ..., -) -> _T: ... - -# This form catches an explicit default argument. -@overload -def field( - *, - default: _T, - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - alias: Optional[str] = ..., - type: Optional[type] = ..., -) -> _T: ... - -# This form covers type=non-Type: e.g. forward references (str), Any -@overload -def field( - *, - default: Optional[_T] = ..., - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., + converter: _ConverterType | None = ..., + factory: Callable[[], _T] | None = ..., kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - alias: Optional[str] = ..., - type: Optional[type] = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., ) -> Any: ... @overload @dataclass_transform(order_default=True, field_specifiers=(attrib, field)) def attrs( maybe_cls: _C, - these: Optional[Dict[str, Any]] = ..., - repr_ns: Optional[str] = ..., + these: dict[str, Any] | None = ..., + repr_ns: str | None = ..., repr: bool = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., init: bool = ..., slots: bool = ..., frozen: bool = ..., @@ -327,25 +240,25 @@ def attrs( kw_only: bool = ..., cache_hash: bool = ..., auto_exc: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., auto_detect: bool = ..., collect_by_mro: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., match_args: bool = ..., - unsafe_hash: Optional[bool] = ..., + unsafe_hash: bool | None = ..., ) -> _C: ... @overload @dataclass_transform(order_default=True, field_specifiers=(attrib, field)) def attrs( maybe_cls: None = ..., - these: Optional[Dict[str, Any]] = ..., - repr_ns: Optional[str] = ..., + these: dict[str, Any] | None = ..., + repr_ns: str | None = ..., repr: bool = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., init: bool = ..., slots: bool = ..., frozen: bool = ..., @@ -355,131 +268,24 @@ def attrs( kw_only: bool = ..., cache_hash: bool = ..., auto_exc: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., auto_detect: bool = ..., collect_by_mro: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., - match_args: bool = ..., - unsafe_hash: Optional[bool] = ..., -) -> Callable[[_C], _C]: ... -@overload -@dataclass_transform(field_specifiers=(attrib, field)) -def define( - maybe_cls: _C, - *, - these: Optional[Dict[str, Any]] = ..., - repr: bool = ..., - unsafe_hash: Optional[bool] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[bool] = ..., - order: Optional[bool] = ..., - auto_detect: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., - match_args: bool = ..., -) -> _C: ... -@overload -@dataclass_transform(field_specifiers=(attrib, field)) -def define( - maybe_cls: None = ..., - *, - these: Optional[Dict[str, Any]] = ..., - repr: bool = ..., - unsafe_hash: Optional[bool] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[bool] = ..., - order: Optional[bool] = ..., - auto_detect: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., - match_args: bool = ..., -) -> Callable[[_C], _C]: ... - -mutable = define - -@overload -@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) -def frozen( - maybe_cls: _C, - *, - these: Optional[Dict[str, Any]] = ..., - repr: bool = ..., - unsafe_hash: Optional[bool] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[bool] = ..., - order: Optional[bool] = ..., - auto_detect: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., - match_args: bool = ..., -) -> _C: ... -@overload -@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) -def frozen( - maybe_cls: None = ..., - *, - these: Optional[Dict[str, Any]] = ..., - repr: bool = ..., - unsafe_hash: Optional[bool] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[bool] = ..., - order: Optional[bool] = ..., - auto_detect: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., match_args: bool = ..., + unsafe_hash: bool | None = ..., ) -> Callable[[_C], _C]: ... -def fields(cls: Type[AttrsInstance]) -> Any: ... -def fields_dict(cls: Type[AttrsInstance]) -> Dict[str, Attribute[Any]]: ... +def fields(cls: type[AttrsInstance]) -> Any: ... +def fields_dict(cls: type[AttrsInstance]) -> dict[str, Attribute[Any]]: ... def validate(inst: AttrsInstance) -> None: ... def resolve_types( cls: _A, - globalns: Optional[Dict[str, Any]] = ..., - localns: Optional[Dict[str, Any]] = ..., - attribs: Optional[List[Attribute[Any]]] = ..., + globalns: dict[str, Any] | None = ..., + localns: dict[str, Any] | None = ..., + attribs: list[Attribute[Any]] | None = ..., include_extras: bool = ..., ) -> _A: ... @@ -488,13 +294,13 @@ def resolve_types( # [attr.ib()])` is valid def make_class( name: str, - attrs: Union[List[str], Tuple[str, ...], Dict[str, Any]], - bases: Tuple[type, ...] = ..., - class_body: Optional[Dict[str, Any]] = ..., - repr_ns: Optional[str] = ..., + attrs: list[str] | tuple[str, ...] | dict[str, Any], + bases: tuple[type, ...] = ..., + class_body: dict[str, Any] | None = ..., + repr_ns: str | None = ..., repr: bool = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., + cmp: _EqOrderType | None = ..., + hash: bool | None = ..., init: bool = ..., slots: bool = ..., frozen: bool = ..., @@ -504,11 +310,11 @@ def make_class( kw_only: bool = ..., cache_hash: bool = ..., auto_exc: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., collect_by_mro: bool = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., ) -> type: ... # _funcs -- @@ -522,24 +328,22 @@ def make_class( def asdict( inst: AttrsInstance, recurse: bool = ..., - filter: Optional[_FilterType[Any]] = ..., - dict_factory: Type[Mapping[Any, Any]] = ..., + filter: _FilterType[Any] | None = ..., + dict_factory: type[Mapping[Any, Any]] = ..., retain_collection_types: bool = ..., - value_serializer: Optional[ - Callable[[type, Attribute[Any], Any], Any] - ] = ..., - tuple_keys: Optional[bool] = ..., -) -> Dict[str, Any]: ... + value_serializer: Callable[[type, Attribute[Any], Any], Any] | None = ..., + tuple_keys: bool | None = ..., +) -> dict[str, Any]: ... # TODO: add support for returning NamedTuple from the mypy plugin def astuple( inst: AttrsInstance, recurse: bool = ..., - filter: Optional[_FilterType[Any]] = ..., - tuple_factory: Type[Sequence[Any]] = ..., + filter: _FilterType[Any] | None = ..., + tuple_factory: type[Sequence[Any]] = ..., retain_collection_types: bool = ..., -) -> Tuple[Any, ...]: ... -def has(cls: type) -> TypeGuard[Type[AttrsInstance]]: ... +) -> tuple[Any, ...]: ... +def has(cls: type) -> TypeGuard[type[AttrsInstance]]: ... def assoc(inst: _T, **changes: Any) -> _T: ... def evolve(inst: _T, **changes: Any) -> _T: ... diff --git a/src/attrs/__init__.pyi b/src/attrs/__init__.pyi index 9372cfea1..8debbf049 100644 --- a/src/attrs/__init__.pyi +++ b/src/attrs/__init__.pyi @@ -1,12 +1,11 @@ from typing import ( Any, Callable, - Dict, Mapping, - Optional, Sequence, - Tuple, - Type, + dataclass_transform, + overload, + TypeVar, ) # Because we need to type our own stuff, we have to make everything from @@ -20,48 +19,227 @@ from attr import __title__ as __title__ from attr import __url__ as __url__ from attr import __version__ as __version__ from attr import __version_info__ as __version_info__ -from attr import _FilterType from attr import assoc as assoc from attr import Attribute as Attribute from attr import AttrsInstance as AttrsInstance from attr import cmp_using as cmp_using from attr import converters as converters -from attr import define as define from attr import evolve as evolve from attr import exceptions as exceptions from attr import Factory as Factory -from attr import field as field from attr import fields as fields from attr import fields_dict as fields_dict from attr import filters as filters -from attr import frozen as frozen from attr import has as has from attr import make_class as make_class -from attr import mutable as mutable from attr import NOTHING as NOTHING from attr import resolve_types as resolve_types from attr import setters as setters from attr import validate as validate from attr import validators as validators +from attr import attrib, asdict as asdict, astuple as astuple -# TODO: see definition of attr.asdict/astuple -def asdict( - inst: AttrsInstance, - recurse: bool = ..., - filter: Optional[_FilterType[Any]] = ..., - dict_factory: Type[Mapping[Any, Any]] = ..., - retain_collection_types: bool = ..., - value_serializer: Optional[ - Callable[[type, Attribute[Any], Any], Any] - ] = ..., - tuple_keys: bool = ..., -) -> Dict[str, Any]: ... +_T = TypeVar("_T") +_C = TypeVar("_C", bound=type) -# TODO: add support for returning NamedTuple from the mypy plugin -def astuple( - inst: AttrsInstance, - recurse: bool = ..., - filter: Optional[_FilterType[Any]] = ..., - tuple_factory: Type[Sequence[Any]] = ..., - retain_collection_types: bool = ..., -) -> Tuple[Any, ...]: ... +_EqOrderType = bool | Callable[[Any], Any] +_ValidatorType = Callable[[Any, "Attribute[_T]", _T], Any] +_ConverterType = Callable[[Any], Any] +_ReprType = Callable[[Any], str] +_ReprArgType = bool | _ReprType +_OnSetAttrType = Callable[[Any, "Attribute[Any]", Any], Any] +_OnSetAttrArgType = _OnSetAttrType | list[_OnSetAttrType] | setters._NoOpType +_FieldTransformer = Callable[ + [type, list["Attribute[Any]"]], list["Attribute[Any]"] +] +# FIXME: in reality, if multiple validators are passed they must be in a list +# or tuple, but those are invariant and so would prevent subtypes of +# _ValidatorType from working when passed in a list or tuple. +_ValidatorArgType = _ValidatorType[_T] | Sequence[_ValidatorType[_T]] + +@overload +def field( + *, + default: None = ..., + validator: None = ..., + repr: _ReprArgType = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + converter: None = ..., + factory: None = ..., + kw_only: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., + type: type | None = ..., +) -> Any: ... + +# This form catches an explicit None or no default and infers the type from the +# other arguments. +@overload +def field( + *, + default: None = ..., + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + converter: _ConverterType | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., + type: type | None = ..., +) -> _T: ... + +# This form catches an explicit default argument. +@overload +def field( + *, + default: _T, + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + converter: _ConverterType | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., + type: type | None = ..., +) -> _T: ... + +# This form covers type=non-Type: e.g. forward references (str), Any +@overload +def field( + *, + default: _T | None = ..., + validator: _ValidatorArgType[_T] | None = ..., + repr: _ReprArgType = ..., + hash: bool | None = ..., + init: bool = ..., + metadata: Mapping[Any, Any] | None = ..., + converter: _ConverterType | None = ..., + factory: Callable[[], _T] | None = ..., + kw_only: bool = ..., + eq: _EqOrderType | None = ..., + order: _EqOrderType | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + alias: str | None = ..., + type: type | None = ..., +) -> Any: ... +@overload +@dataclass_transform(field_specifiers=(attrib, field)) +def define( + maybe_cls: _C, + *, + these: dict[str, Any] | None = ..., + repr: bool = ..., + unsafe_hash: bool | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + auto_detect: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@dataclass_transform(field_specifiers=(attrib, field)) +def define( + maybe_cls: None = ..., + *, + these: dict[str, Any] | None = ..., + repr: bool = ..., + unsafe_hash: bool | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + auto_detect: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... + +mutable = define + +@overload +@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) +def frozen( + maybe_cls: _C, + *, + these: dict[str, Any] | None = ..., + repr: bool = ..., + unsafe_hash: bool | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + auto_detect: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., +) -> _C: ... +@overload +@dataclass_transform(frozen_default=True, field_specifiers=(attrib, field)) +def frozen( + maybe_cls: None = ..., + *, + these: dict[str, Any] | None = ..., + repr: bool = ..., + unsafe_hash: bool | None = ..., + hash: bool | None = ..., + init: bool = ..., + slots: bool = ..., + frozen: bool = ..., + weakref_slot: bool = ..., + str: bool = ..., + auto_attribs: bool = ..., + kw_only: bool = ..., + cache_hash: bool = ..., + auto_exc: bool = ..., + eq: bool | None = ..., + order: bool | None = ..., + auto_detect: bool = ..., + getstate_setstate: bool | None = ..., + on_setattr: _OnSetAttrArgType | None = ..., + field_transformer: _FieldTransformer | None = ..., + match_args: bool = ..., +) -> Callable[[_C], _C]: ... From 4ba45bfcb791d3c2ae709ef4cc289d6d208f39fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tin=20Tvrtkovi=C4=87?= Date: Sat, 3 Feb 2024 00:36:11 +0100 Subject: [PATCH 2/6] Modernize the rest of the stubs --- src/attr/_cmp.pyi | 14 ++++++------ src/attr/converters.pyi | 2 +- src/attr/filters.pyi | 6 +++--- src/attr/setters.pyi | 3 ++- src/attr/validators.pyi | 47 ++++++++++++++++++----------------------- 5 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/attr/_cmp.pyi b/src/attr/_cmp.pyi index f3dcdc1a7..cc7893b04 100644 --- a/src/attr/_cmp.pyi +++ b/src/attr/_cmp.pyi @@ -1,13 +1,13 @@ -from typing import Any, Callable, Optional, Type +from typing import Any, Callable _CompareWithType = Callable[[Any, Any], bool] def cmp_using( - eq: Optional[_CompareWithType] = ..., - lt: Optional[_CompareWithType] = ..., - le: Optional[_CompareWithType] = ..., - gt: Optional[_CompareWithType] = ..., - ge: Optional[_CompareWithType] = ..., + eq: _CompareWithType | None = ..., + lt: _CompareWithType | None = ..., + le: _CompareWithType | None = ..., + gt: _CompareWithType | None = ..., + ge: _CompareWithType | None = ..., require_same_type: bool = ..., class_name: str = ..., -) -> Type: ... +) -> type: ... diff --git a/src/attr/converters.pyi b/src/attr/converters.pyi index 5abb49f6d..9ef478f21 100644 --- a/src/attr/converters.pyi +++ b/src/attr/converters.pyi @@ -1,6 +1,6 @@ from typing import Callable, TypeVar, overload -from . import _ConverterType +from attrs import _ConverterType _T = TypeVar("_T") diff --git a/src/attr/filters.pyi b/src/attr/filters.pyi index 8a02fa0fc..974abdcdb 100644 --- a/src/attr/filters.pyi +++ b/src/attr/filters.pyi @@ -1,6 +1,6 @@ -from typing import Any, Union +from typing import Any from . import Attribute, _FilterType -def include(*what: Union[type, str, Attribute[Any]]) -> _FilterType[Any]: ... -def exclude(*what: Union[type, str, Attribute[Any]]) -> _FilterType[Any]: ... +def include(*what: type | str | Attribute[Any]) -> _FilterType[Any]: ... +def exclude(*what: type | str | Attribute[Any]) -> _FilterType[Any]: ... diff --git a/src/attr/setters.pyi b/src/attr/setters.pyi index 72f7ce476..73abf36e7 100644 --- a/src/attr/setters.pyi +++ b/src/attr/setters.pyi @@ -1,6 +1,7 @@ from typing import Any, NewType, NoReturn, TypeVar -from . import Attribute, _OnSetAttrType +from . import Attribute +from attrs import _OnSetAttrType _T = TypeVar("_T") diff --git a/src/attr/validators.pyi b/src/attr/validators.pyi index d194a75ab..caca56c68 100644 --- a/src/attr/validators.pyi +++ b/src/attr/validators.pyi @@ -5,20 +5,15 @@ from typing import ( Container, ContextManager, Iterable, - List, Mapping, Match, - Optional, Pattern, - Tuple, - Type, TypeVar, - Union, overload, ) -from . import _ValidatorType -from . import _ValidatorArgType +from attrs import _ValidatorType +from attrs import _ValidatorArgType _T = TypeVar("_T") _T1 = TypeVar("_T1") @@ -36,42 +31,42 @@ def disabled() -> ContextManager[None]: ... # To be more precise on instance_of use some overloads. # If there are more than 3 items in the tuple then we fall back to Any @overload -def instance_of(type: Type[_T]) -> _ValidatorType[_T]: ... +def instance_of(type: type[_T]) -> _ValidatorType[_T]: ... @overload -def instance_of(type: Tuple[Type[_T]]) -> _ValidatorType[_T]: ... +def instance_of(type: tuple[type[_T]]) -> _ValidatorType[_T]: ... @overload def instance_of( - type: Tuple[Type[_T1], Type[_T2]] -) -> _ValidatorType[Union[_T1, _T2]]: ... + type: tuple[type[_T1], type[_T2]] +) -> _ValidatorType[_T1 | _T2]: ... @overload def instance_of( - type: Tuple[Type[_T1], Type[_T2], Type[_T3]] -) -> _ValidatorType[Union[_T1, _T2, _T3]]: ... + type: tuple[type[_T1], type[_T2], type[_T3]] +) -> _ValidatorType[_T1 | _T2 | _T3]: ... @overload -def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ... +def instance_of(type: tuple[type, ...]) -> _ValidatorType[Any]: ... def provides(interface: Any) -> _ValidatorType[Any]: ... def optional( - validator: Union[ - _ValidatorType[_T], List[_ValidatorType[_T]], Tuple[_ValidatorType[_T]] - ] -) -> _ValidatorType[Optional[_T]]: ... + validator: ( + _ValidatorType[_T] + | list[_ValidatorType[_T]] + | tuple[_ValidatorType[_T]] + ), +) -> _ValidatorType[_T | None]: ... def in_(options: Container[_T]) -> _ValidatorType[_T]: ... def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... def matches_re( - regex: Union[Pattern[AnyStr], AnyStr], + regex: Pattern[AnyStr] | AnyStr, flags: int = ..., - func: Optional[ - Callable[[AnyStr, AnyStr, int], Optional[Match[AnyStr]]] - ] = ..., + func: Callable[[AnyStr, AnyStr, int], Match[AnyStr] | None] | None = ..., ) -> _ValidatorType[AnyStr]: ... def deep_iterable( member_validator: _ValidatorArgType[_T], - iterable_validator: Optional[_ValidatorType[_I]] = ..., + iterable_validator: _ValidatorType[_I] | None = ..., ) -> _ValidatorType[_I]: ... def deep_mapping( key_validator: _ValidatorType[_K], value_validator: _ValidatorType[_V], - mapping_validator: Optional[_ValidatorType[_M]] = ..., + mapping_validator: _ValidatorType[_M] | None = ..., ) -> _ValidatorType[_M]: ... def is_callable() -> _ValidatorType[_T]: ... def lt(val: _T) -> _ValidatorType[_T]: ... @@ -83,6 +78,6 @@ def min_len(length: int) -> _ValidatorType[_T]: ... def not_( validator: _ValidatorType[_T], *, - msg: Optional[str] = None, - exc_types: Union[Type[Exception], Iterable[Type[Exception]]] = ..., + msg: str | None = None, + exc_types: type[Exception] | Iterable[type[Exception]] = ..., ) -> _ValidatorType[_T]: ... From b83f139d645e4b711e69c855fc7bcceb8f45ed84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tin=20Tvrtkovi=C4=87?= Date: Sat, 3 Feb 2024 00:44:51 +0100 Subject: [PATCH 3/6] Fix dataclass_transform import --- src/attrs/__init__.pyi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/attrs/__init__.pyi b/src/attrs/__init__.pyi index 8debbf049..33624666c 100644 --- a/src/attrs/__init__.pyi +++ b/src/attrs/__init__.pyi @@ -1,9 +1,10 @@ +import sys + from typing import ( Any, Callable, Mapping, Sequence, - dataclass_transform, overload, TypeVar, ) @@ -39,6 +40,11 @@ from attr import validate as validate from attr import validators as validators from attr import attrib, asdict as asdict, astuple as astuple +if sys.version_info >= (3, 11): + from typing import dataclass_transform +else: + from typing_extensions import dataclass_transform + _T = TypeVar("_T") _C = TypeVar("_C", bound=type) From 155055e2e562f378741672f523c40de596e49385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tin=20Tvrtkovi=C4=87?= Date: Sat, 3 Feb 2024 00:49:53 +0100 Subject: [PATCH 4/6] Changelog --- changelog.d/1234.change.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog.d/1234.change.md diff --git a/changelog.d/1234.change.md b/changelog.d/1234.change.md new file mode 100644 index 000000000..e3de2ff17 --- /dev/null +++ b/changelog.d/1234.change.md @@ -0,0 +1,2 @@ +Change how our type stubs are organized to optimize VS Code quick-fix import suggestions. +Modernize type stubs. \ No newline at end of file From 7dc670babf81d6c256bfb013b009295ee2abdc0a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 23:50:03 +0000 Subject: [PATCH 5/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- changelog.d/1234.change.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/1234.change.md b/changelog.d/1234.change.md index e3de2ff17..ab9859d84 100644 --- a/changelog.d/1234.change.md +++ b/changelog.d/1234.change.md @@ -1,2 +1,2 @@ Change how our type stubs are organized to optimize VS Code quick-fix import suggestions. -Modernize type stubs. \ No newline at end of file +Modernize type stubs. From e1922dce631e04f7afbf6b3a4e602e3ecc247a41 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Sat, 3 Feb 2024 07:58:59 +0100 Subject: [PATCH 6/6] Update changelog.d/1234.change.md --- changelog.d/1234.change.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changelog.d/1234.change.md b/changelog.d/1234.change.md index ab9859d84..0fbb078f0 100644 --- a/changelog.d/1234.change.md +++ b/changelog.d/1234.change.md @@ -1,2 +1 @@ -Change how our type stubs are organized to optimize VS Code quick-fix import suggestions. -Modernize type stubs. +Our type stubs now use modern type notation and are organized such that VS Code's quick-fix prefers the `attrs` namespace.