[Python-Dev] PEP 484 update proposal: annotating decorated declarations

Koos Zevenhoven k7hoven at gmail.com
Mon May 15 04:48:57 EDT 2017


On Tue, May 9, 2017 at 8:19 PM, Guido van Rossum <guido at python.org> wrote:
> There's a PR to the peps proposal here:
> https://github.com/python/peps/pull/242
>
> The full text of the current proposal is below. The motivation for this is
> that for complex decorators, even if the type checker can figure out what's
> going on (by taking the signature of the decorator into account), it's
> sometimes helpful to the human reader of the code to be reminded of the type
> after applying the decorators (or a stack thereof). Much discussion can be
> found in the PR. Note that we ended up having `Callable` in the type because
> there's no rule that says a decorator returns a function type (e.g.
> `property` doesn't).
>
> This is a small thing but I'd like to run it by a larger audience than the
> core mypy devs who have commented so far. There was a brief discussion on
> python-ideas (my original, favorable reply by Nick, my response).
>
> Credit for the proposal goes to Naomi Seyfer, with discussion by Ivan
> Levkivskyi and Jukka Lehtosalo.
>
> If there's no further debate here I'll merge it into the PEP and an
> implementation will hopefully appear in the next version of the typing
> module (also hopefully to be included in CPython 3.6.2 and 3.5.4).
>

So the change would only affect early adopters of this typing feature,
who are likely to upgrade to newer python versions often? Could this
be called a 3.7 feature with a clearly documented bonus that it also
works in 3.6.2+ and 3.5.4+? I mean, to prevent 3rd-party libraries
tested with 3.5(.4) from being broken in 3.5.3?

> Here's the proposed text (wordsmithing suggestions in the PR please):
>
> +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::
> +
> + from typing import ContextManager, Iterator, decorated_type
> + from contextlib import contextmanager
> +
> + class DatabaseSession: ...
> +
> + @decorated_type(Callable[[str], ContextManager[DatabaseSession]])
> + @contextmanager
> + def session(url: str) -> Iterator[DatabaseSession]:
> + s = DatabaseSession(url)
> + try:
> + yield s
> + 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``.
> +
>

Would __annotations__ be set by the decorator? To me, not setting them
would seem weird, but cases where the result is not a function could
be weird. I also don't see a mention of this only working in stubs.

I like Jukka's version, as it has a clear distinction between
functions and other attributes. But that might require a language
change to provide __annotations__ in a clean manner? Maybe that
language change would be useful elsewhere.

—Koos



-- 
+ Koos Zevenhoven + http://twitter.com/k7hoven +


More information about the Python-Dev mailing list