From 4a6008c62a6e79615edcaee75e95b1703ff31144 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Tue, 18 Apr 2017 23:25:00 -0700 Subject: [PATCH 1/5] Describe a way of annotating decorated declarations --- pep-0484.txt | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pep-0484.txt b/pep-0484.txt index b15fe3b05db..f222a5e1925 100644 --- a/pep-0484.txt +++ b/pep-0484.txt @@ -276,6 +276,33 @@ implemented by deferring to ``isinstance(x, collections.abc.Callable)``. However, ``isinstance(x, typing.Callable[...])`` is not supported. +Decorators +---------- + +Decorators can modify the types of the functions or classes they +decorate. To annotate a decorated declaration with the eventual +decorated type, put a type comment on the line with the decorator:: + + from typing import ContextManager, Generator + from contextlib import contextmanager + + class DatabaseSession: ... + + @contextmanager # type: Callable[[str], ContextManager[DatabaseSession]] + def session(url: str) -> Generator[DatabaseSession, None, None]: + s = DatabaseSession(url) + try: + yield s + finally: + s.close() + +If both the decorator and the function being decorated have type +annotations, a type checker should make sure the inferred type for the +decorated function is compatible with the declared type. Otherwise, +the checker can assume the declared type of the topmost decorator +is accurate for the decorated function's call sites. + + Generics -------- From d2a8468bbdb04a0ff8eedd0ca5d5a4797de0a0b3 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 26 Apr 2017 18:14:16 -1000 Subject: [PATCH 2/5] Rewrite to use a decorator form --- pep-0484.txt | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pep-0484.txt b/pep-0484.txt index f222a5e1925..43e7b27716c 100644 --- a/pep-0484.txt +++ b/pep-0484.txt @@ -280,15 +280,16 @@ Decorators ---------- Decorators can modify the types of the functions or classes they -decorate. To annotate a decorated declaration with the eventual -decorated type, put a type comment on the line with the decorator:: +decorate. Use the `decorated_type` decorator to declare the type of +the resulting item after all other decorators have been applied.:: - from typing import ContextManager, Generator + from typing import ContextManager, Generator, decorated_type from contextlib import contextmanager class DatabaseSession: ... - @contextmanager # type: Callable[[str], ContextManager[DatabaseSession]] + @decorated_type(Callable[[str], ContextManager[DatabaseSession]]) + @contextmanager def session(url: str) -> Generator[DatabaseSession, None, None]: s = DatabaseSession(url) try: @@ -296,12 +297,12 @@ decorated type, put a type comment on the line with the decorator:: finally: s.close() -If both the decorator and the function being decorated have type -annotations, a type checker should make sure the inferred type for the -decorated function is compatible with the declared type. Otherwise, -the checker can assume the declared type of the topmost decorator -is accurate for the decorated function's call sites. - +The argument of `decorated_type` is a type annotation on the name +being declared (`session`, in the example above). If you have multiple +decorators, `decorated_type` must be topmost. The `decorated_type` +decorator is invalid on a function declaration that is also decorated +with `overload`, but you can annotate the implementation of the +overload series with `decorated_type`. Generics -------- From bcded67e94208a884d750f7be0edf13fae93a671 Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 26 Apr 2017 18:15:22 -1000 Subject: [PATCH 3/5] Use simpler type for generator --- pep-0484.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-0484.txt b/pep-0484.txt index 43e7b27716c..d33e1273246 100644 --- a/pep-0484.txt +++ b/pep-0484.txt @@ -290,7 +290,7 @@ the resulting item after all other decorators have been applied.:: @decorated_type(Callable[[str], ContextManager[DatabaseSession]]) @contextmanager - def session(url: str) -> Generator[DatabaseSession, None, None]: + def session(url: str) -> Iterator[DatabaseSession]: s = DatabaseSession(url) try: yield s From 6b201b9b40d96fb932158970e0d47a592ac856be Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Wed, 26 Apr 2017 18:15:48 -1000 Subject: [PATCH 4/5] Aaa imports --- pep-0484.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pep-0484.txt b/pep-0484.txt index d33e1273246..10fe854e3e4 100644 --- a/pep-0484.txt +++ b/pep-0484.txt @@ -283,7 +283,7 @@ Decorators can modify the types of the functions or classes they decorate. Use the `decorated_type` decorator to declare the type of the resulting item after all other decorators have been applied.:: - from typing import ContextManager, Generator, decorated_type + from typing import ContextManager, Iterator, decorated_type from contextlib import contextmanager class DatabaseSession: ... From 5b23397f59caf09a87cba7bf1b864744cae3446c Mon Sep 17 00:00:00 2001 From: Naomi Seyfer Date: Sat, 29 Apr 2017 21:04:39 -1000 Subject: [PATCH 5/5] Typography --- pep-0484.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pep-0484.txt b/pep-0484.txt index 10fe854e3e4..09c97a5b6bf 100644 --- a/pep-0484.txt +++ b/pep-0484.txt @@ -280,8 +280,8 @@ Decorators ---------- Decorators can modify the types of the functions or classes they -decorate. Use the `decorated_type` decorator to declare the type of -the resulting item after all other decorators have been applied.:: +decorate. Use the ``decorated_type`` decorator to declare the type of +the resulting item after all other decorators have been applied:: from typing import ContextManager, Iterator, decorated_type from contextlib import contextmanager @@ -297,12 +297,12 @@ the resulting item after all other decorators have been applied.:: finally: s.close() -The argument of `decorated_type` is a type annotation on the name -being declared (`session`, in the example above). If you have multiple -decorators, `decorated_type` must be topmost. The `decorated_type` -decorator is invalid on a function declaration that is also decorated -with `overload`, but you can annotate the implementation of the -overload series with `decorated_type`. +The argument of ``decorated_type`` is a type annotation on the name +being declared (``session``, in the example above). If you have +multiple decorators, ``decorated_type`` must be topmost. The +``decorated_type`` decorator is invalid on a function declaration that +is also decorated with ``overload``, but you can annotate the +implementation of the overload series with ``decorated_type``. Generics --------