(original) (raw)
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).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
+ 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\`\`.
+