From 8b7cf89f94643c5688b6409c4cc54d292051ba81 Mon Sep 17 00:00:00 2001 From: Diego Argueta Date: Thu, 11 Mar 2021 11:47:27 -0800 Subject: [PATCH 1/3] Narrower typing on Factory called with takes_self --- src/attr/__init__.pyi | 11 +++++++++-- tests/typing_example.py | 7 +++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/attr/__init__.pyi b/src/attr/__init__.pyi index 3cbe709e3..e78fae07c 100644 --- a/src/attr/__init__.pyi +++ b/src/attr/__init__.pyi @@ -4,6 +4,7 @@ from typing import ( Dict, Generic, List, + Literal, Mapping, Optional, Sequence, @@ -64,9 +65,15 @@ NOTHING: object def Factory(factory: Callable[[], _T]) -> _T: ... @overload def Factory( - factory: Union[Callable[[Any], _T], Callable[[], _T]], - takes_self: bool = ..., + factory: Callable[[Any], _T], + takes_self: Literal[True], ) -> _T: ... +@overload +def Factory( + factory: Callable[[], _T], + takes_self: Literal[False], +) -> _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)) From 05cc09650bb296d2b267f930ff12db36934170fb Mon Sep 17 00:00:00 2001 From: Diego Argueta Date: Mon, 22 Mar 2021 11:05:10 -0700 Subject: [PATCH 2/3] Make Literal annotation depend on Python version --- src/attr/__init__.pyi | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/attr/__init__.pyi b/src/attr/__init__.pyi index e78fae07c..072547c23 100644 --- a/src/attr/__init__.pyi +++ b/src/attr/__init__.pyi @@ -1,10 +1,10 @@ +import sys from typing import ( Any, Callable, Dict, Generic, List, - Literal, Mapping, Optional, Sequence, @@ -61,18 +61,29 @@ 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: Callable[[Any], _T], - takes_self: Literal[True], -) -> _T: ... -@overload -def Factory( - factory: Callable[[], _T], - takes_self: Literal[False], -) -> _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]): From 4adb22b5d09e830562c476038f6614cfee271ebc Mon Sep 17 00:00:00 2001 From: Diego Argueta Date: Tue, 23 Mar 2021 10:08:42 -0700 Subject: [PATCH 3/3] Fix linting error --- src/attr/__init__.pyi | 1 + 1 file changed, 1 insertion(+) diff --git a/src/attr/__init__.pyi b/src/attr/__init__.pyi index 072547c23..cdf9a9ff0 100644 --- a/src/attr/__init__.pyi +++ b/src/attr/__init__.pyi @@ -1,4 +1,5 @@ import sys + from typing import ( Any, Callable,