[Python-ideas] @return?

Conrad Irwin conrad.irwin at googlemail.com
Tue Apr 13 23:36:24 CEST 2010


Dear All,

I have an idea, though the acceptability of it is a matter for debate.
It seems that this would be the appropriate place to post, but if not,
or if you've already tired of this proposal, sorry.

A common pattern when creating decorators is something of the form:

    def decorator(func):
        def wrapper(*args):
            func(modulate(args))
        return wrapper

This is surprisingly reminiscent of the kind of code decorators were
introduced to avoid:

    class Example(object):
        def method(cls, *args):
            modulate(args)
        method = classmethod(method)

The proposal is thus to introduce "@return" that returns the decorated
object, a hybrid of the behavior of the return statement and decorators.
I think the intended semantics are clear, providing you know the basics
of how decorators work:

    def decorator(func):
        @return
        def wrapper(*args):
            func(modulate(args))

Much as the class declaration was beautified to:

    def Example(object):
        @classmethod
        def method(cls, *args):
            modulate(args)

An alternative I considered, and rejected through ugliness, was allowing
a funcdef in a return statement:

    def decorator(func):
        return def wrapper(*args):
            func(modulate(args))

The syntax of "@return" has the advantage of matching the decorator
syntax, particularly beneficial given its most obvious use-case.

There are uglinesses though, a simplistic reading of "@return" would
imply the existence of a function called "return", and while the return
statement can be used with brackets, it certainly should not be turned
into a function. Also:

    from functools import wraps

    def decorator1(func):
        @return
        @wraps(func)
        def wrapper(*args):
            func(modulate(args))

    def decorator2(func):
        @wraps(func)  # Yuck! (not called, I think)
        @return
        def wrapper(*args):
            func(modulate(args))

Obviously, as this is currently a syntax error, there are few
backward-compatibility concerns, and many forward-compatibility issues.
If it were to be added, then a case might be made for allowing "@yield"
"@throw" (class decorator) and (along with yield, eventually, maybe)
"@continue".

Does anyone have thoughts they'd like to share, or shall I return to the
depths of obscurity from whence I came?

Yours
Conrad



More information about the Python-ideas mailing list