Factor in Anthony's text regarding the @ syntax and toss in a couple other

odd bits.
This commit is contained in:
Skip Montanaro 2004-08-06 03:36:09 +00:00
parent fe10049f8e
commit 8945c589a4
1 changed files with 102 additions and 22 deletions

View File

@ -51,7 +51,9 @@ replace::
with an alternative that places the decoration in the function's
declaration::
def foo(cls) using [synchronized(lock), classmethod]:
@classmethod
@synchronized(lock)
def foo(cls):
pass
Modifying classes in this fashion is also possible, though the
@ -59,7 +61,8 @@ benefits are not as immediately apparent. Almost certainly, anything
which could be done with class decorators could be done using
metaclasses, but using metaclasses is sufficiently obscure that there
is some attraction to having an easier way to make simple
modifications to classes.
modifications to classes. For Python 2.4, only function decorators
are being added.
Background
@ -88,6 +91,26 @@ attributing the bracketed syntax to an earlier proposal on
Class decorations seem like an obvious next step because class
definition and function definition are syntactically similar.
The discussion continued on and off on python-dev from February 2002
through July 2004. Many hundreds of posts were made, with people
proposing many possible syntax variations. Guido took a list of
proposals to `EuroPython 2004`_, where a discussion took place.
Subsequent to this, he decided that for 2.4a2 we'd have the Java-style
@decorator syntax. Barry Warsaw named this the 'pie-decorator'
syntax, in honor of the Pie-thon Parrot shootout which was announced
about the same time as the decorator syntax, and because the @ looks a
little like a pie. Guido `outlined his case`_ on Python-dev,
including `this piece`_ on the various rejected forms.
.. EuroPython 2004:
http://www.python.org/doc/essays/ppt/euro2004/euro2004.pdf
.. outlined his case:
http://mail.python.org/pipermail/python-dev/2004-August/authors.html
.. this piece:
http://mail.python.org/pipermail/python-dev/2004-August/046672.html
Design Goals
============
@ -95,7 +118,7 @@ Design Goals
The new syntax should
* work for arbitrary wrappers, including user-defined callables and
the existing builtins ``classmethod()`` and ``staticmethod``
the existing builtins ``classmethod()`` and ``staticmethod()``
* work with multiple wrappers per definition
@ -119,23 +142,38 @@ The new syntax should
.. _toy parser tools out there:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=mailman.1010809396.32158.python-list%40python.org
Andrew Kuchling has links to a bunch of the discussions about motivations
`in his blog`_.
.. in his blog:
http://www.amk.ca/diary/archives/cat_python.html#003255
Proposed Syntax
===============
The currently proposed syntax for function decorators is::
The current syntax for function decorators as implemented in Python
2.4a2 is::
def func(arg1, arg2, ...) [dec1, dec2, ...]:
@dec2
@dec1
def func(arg1, arg2, ...):
pass
This is equivalent to::
def func(arg1, arg2, ...):
pass
func = dec2(dec1(func))
The decorators are near the declaration of the function's API but are
clearly secondary. The square brackets make it possible to fairly
easily break long lists of decorators across multiple lines.
clearly secondary. The @ sign makes it clear that something new is
going on here.
Class decorators are defined in an analogous fashion::
The decorator statement is limited in what it can accept - arbitrary
expressions will not work. Guido preferred this because of a `gut feeling`_
class MyClass(base1, base2) [dec1, dec2, ...]:
pass
.. gut feeling:
http://mail.python.org/pipermail/python-dev/2004-August/046711.html
Alternate Proposals
@ -198,36 +236,73 @@ a `list of decorators`_ as a prefix to function definitions ::
def foo(arg1, arg2, ...):
pass
This appears to be his current favorite, but negative sentiment runs
For a while this was Guido's preferred solution, but negative sentiment ran
high, mostly because that syntax, though useless except for side
effects of the list, is already legal and thus creates a special case.
.. _list of decorators:
http://python.org/sf/926860
Another variant on the list syntax that was initially favored was::
Why [...]?
----------
def func(arg1, arg2, ...) [dec1, dec2]:
pass
For syntax options which use a list-like syntax to specify the
decorators a few alternatives have been proposed: ``[|...|]``,
``*[...]*``, and ``<...>``. None have gained traction. The
alternatives which involve square brackets only serve to make it
Guido decided `he preferred`_ having the decorators on the line before
the 'def', because it was felt that a long argument list would mean
that the decorators would be 'hidden'
.. he preferred:
http://mail.python.org/pipermail/python-dev/2004-March/043756.html
Phillip Eby and Jp Calderone both proposed variants that required
no new syntax, but instead used some fairly advanced introspection
to provide decorator-like behavoiur, but Guido was unimpressed by
these, stating::
Using functions with "action-at-a-distance" through
sys.settraceback may be okay for an obscure feature that can't be
had any other way yet doesn't merit changes to the language, but
that's not the situation for decorators. The widely held view
here is that decorators need to be added as a syntactic feature to
avoid the problems with the postfix notation used in 2.2 and 2.3.
Decorators are slated to be an important new language feature and
their design needs to be forward-looking, not constrained by what
can be implemented in 2.3.
Why @?
------
There is some history in Java using @ initially as a marker in
`Javadoc comments`_ and later in ... mumble mumble ... The fact that
@ was previously unused as a token in Python also means it's clear
there is no possibility of such code being parsed by an earlier
version of Python, leading to possibly subtle semantic bugs.
For syntax options which use a list-like syntax (no matter where it
appears) to specify the decorators a few alternatives were proposed:
``[|...|]``, ``*[...]*``, and ``<...>``. None gained much traction.
The alternatives which involve square brackets only serve to make it
obvious that the decorator construct is not a list. They do nothing
to make parsing any easier. The '<...>' alternative presents parsing
problems because '<' and '>' already parse as un-paired. They present
a further parsing ambiguity because a right angle bracket might be a
greater than symbol instead of a closer for the decorators.
.. Javadoc comments:
http://java.sun.com/j2se/javadoc/writingdoccomments/
Current Implementation
======================
Michael Hudson posted a `patch`_ at Starship, which implements the
proposed syntax changes for both functions and classes and left-first
application of decorators::
Guido asked for a voluteer to implement his preferred syntax, and Mark
Russell stepped up and posted a `patch`_ to SF. The syntax accepted
for 2.4a2 is::
def func(arg1, arg2, ...) [dec1, dec2]:
@dec2
@dec1
def func(arg1, arg2, ...):
pass
is equivalent to::
@ -238,7 +313,12 @@ is equivalent to::
though without the intermediate creation of a variable named ``func``.
.. _patch: http://starship.python.net/crew/mwh/hacks/meth-syntax-sugar-3.diff
.. _patch: http://www.python.org/sf/979728
A `previous patch`_ from Michael Hudson which implements the
list-after-def syntax is also still kicking around.
.. _previous patch: http://starship.python.net/crew/mwh/hacks/meth-syntax-sugar-3.diff
Examples