I think you're right that the redefinition style is easier to read for 
complicated stuff... It also seems more complicated in a way I can't put my 
finger on. 

The overload precedent helps. 

Currently leaning towards Jukka being right, vague worries about extra 
complication be damned. 

Readability is more important. 

> On May 10, 2017, at 5:23 AM, Jukka Lehtosalo <jlehtos...@gmail.com> wrote:
> 
> Even if Callable types will soon support keyword arguments, the syntax for 
> Callables will look quite different from function definitions and this 
> inconsistency may hurt readability, at least for more complex signatures. We 
> could work around this by using the def syntax for the declared type of a 
> decorator. For example:
> 
> @declared_type
> def session(url: str) -> ContextManager[DatabaseSession]: ...  # Explicit 
> '...'
> 
> @contextmanager
> def session(url: str) -> Iterator[DatabaseSession]:
>     s = DatabaseSession(url)
>     ...
> 
> This would be quite similar to how overloads work, so there is a precedent 
> for something like this. We could require or recommend that the declared type 
> comes immediately before the implementation so that the entire definition of 
> a single function would not be too spread out.
> 
> This won't help if the decorated type is not a callable. We could support 
> this use case by using the normal variable annotation syntax:
> 
> thing: Decorated  # Declared type of 'thing'
> 
> @decorator
> def thing() -> int:
>     ...
> 
> Jukka
> 
>> On Wed, May 10, 2017 at 12:27 AM, Naomi Seyfer <na...@seyfer.org> wrote:
>> Stay tuned for the pep that allows callable to take keyword args. 
>> 
>>> On May 9, 2017, at 3:59 PM, Brett Cannon <br...@python.org> wrote:
>>> 
>>> The idea seems reasonable to me when viewing type hints as a form of 
>>> documentation as it helps remind people how they are expected to call the 
>>> final function.
>>> 
>>> One worry I do have, though, is Callable doesn't support keyword-only 
>>> parameters, so declared_type won't work in all cases without Callable 
>>> gaining such support (for those that don't know, Callable didn't start with 
>>> that support as Callable has been meant for callback scenarios up to this 
>>> point).
>>> 
>>>> On Tue, 9 May 2017 at 10:21 Guido van Rossum <gu...@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).
>>>> 
>>>> 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``.
>>>> +
>>>> 
>>>> -- 
>>>> --Guido van Rossum (python.org/~guido)
>>>> _______________________________________________
>>>> Python-Dev mailing list
>>>> Python-Dev@python.org
>>>> https://mail.python.org/mailman/listinfo/python-dev
>>>> Unsubscribe: 
>>>> https://mail.python.org/mailman/options/python-dev/brett%40python.org
>> 
>> _______________________________________________
>> Python-Dev mailing list
>> Python-Dev@python.org
>> https://mail.python.org/mailman/listinfo/python-dev
>> Unsubscribe: 
>> https://mail.python.org/mailman/options/python-dev/jlehtosalo%40gmail.com
>> 
> 
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to