Skip to content

[WIP] PEP 484: Describe a way of annotating decorated declarations #242

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions pep-0484.txt
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,34 @@ 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. Use the ``decorated_type`` decorator to declare the type of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait, we're going with declared_type instead right?

the resulting item after all other decorators have been applied::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might also tweak the words to indicate that there may not be any other decorators.


from typing import ContextManager, Iterator, decorated_type
from contextlib import contextmanager

class DatabaseSession: ...

@decorated_type(Callable[[str], ContextManager[DatabaseSession]])
@contextmanager
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May need a different example than contextmanager since (at least mypy) now gets the type right there through the use of plugins.

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``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we clarify (via example and/or specification language) that the type in @decorated_type may differ from the naturally inferred type, and that the inferred type must be assignable to the declared type? (Like in assignments or passing an argument to a function.) E.g. either one may have an Any where the other has something more specific.

I'm not sure if the semantics should exactly match those of assignment, though that would be my first approximation until we find a counterexample.


Generics
--------

Expand Down