diff --git a/src/attr/__init__.pyi b/src/attr/__init__.pyi index 3cbe709e3..cdf9a9ff0 100644 --- a/src/attr/__init__.pyi +++ b/src/attr/__init__.pyi @@ -1,3 +1,5 @@ +import sys + from typing import ( Any, Callable, @@ -60,13 +62,30 @@ NOTHING: object # NOTE: Factory lies about its return type to make this possible: # `x: List[int] # = Factory(list)` # Work around mypy issue #4554 in the common case by using an overload. -@overload -def Factory(factory: Callable[[], _T]) -> _T: ... -@overload -def Factory( - factory: Union[Callable[[Any], _T], Callable[[], _T]], - takes_self: bool = ..., -) -> _T: ... +if sys.version_info >= (3, 8): + from typing import Literal + + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Callable[[Any], _T], + takes_self: Literal[True], + ) -> _T: ... + @overload + def Factory( + factory: Callable[[], _T], + takes_self: Literal[False], + ) -> _T: ... +else: + @overload + def Factory(factory: Callable[[], _T]) -> _T: ... + @overload + def Factory( + factory: Union[Callable[[Any], _T], Callable[[], _T]], + takes_self: bool = ..., + ) -> _T: ... + class Attribute(Generic[_T]): name: str diff --git a/tests/typing_example.py b/tests/typing_example.py index db05dec3b..13b5638db 100644 --- a/tests/typing_example.py +++ b/tests/typing_example.py @@ -250,3 +250,10 @@ class NGFrozen: @attr.s(collect_by_mro=True) class MRO: pass + + +@attr.s +class FactoryTest: + a: List[int] = attr.ib(default=attr.Factory(list)) + b: List[Any] = attr.ib(default=attr.Factory(list, False)) + c: List[int] = attr.ib(default=attr.Factory((lambda s: s.a), True))