[Python-checkins] python/nondist/peps pep-0318.txt,1.27,1.28
anthonybaxter at users.sourceforge.net
anthonybaxter at users.sourceforge.net
Mon Aug 30 15:16:59 CEST 2004
Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27053
Modified Files:
pep-0318.txt
Log Message:
I'm done with this now. It'll need a further update when Guido makes a
decision.
Index: pep-0318.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0318.txt,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- pep-0318.txt 25 Aug 2004 13:47:29 -0000 1.27
+++ pep-0318.txt 30 Aug 2004 13:16:56 -0000 1.28
@@ -2,28 +2,23 @@
Title: Decorators for Functions and Methods
Version: $Revision$
Last-Modified: $Date$
-Author: Kevin D. Smith <Kevin.Smith at theMorgue.org>,
- Jim Jewett <jimjjewett at users.sourceforge.net>,
- Skip Montanaro <skip at pobox.com>,
- Anthony Baxter <anthony at python.org>
+Author: Kevin D. Smith, Jim Jewett, Skip Montanaro, Anthony Baxter
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 05-Jun-2003
Python-Version: 2.4
-Post-History: 09-Jun-2003, 10-Jun-2003, 27-Feb-2004, 23-Mar-2004
+Post-History: 09-Jun-2003, 10-Jun-2003, 27-Feb-2004, 23-Mar-2004, 30-Aug-2004
WarningWarningWarning
=====================
-This is not yet complete. This is still a work-in-progress. Feedback
-to anthony. Please note that the point of this PEP is *not* to
-provide an open-slather of plusses and minuses for each syntax, but is
-instead to justify the choice made. If, in 2.4a3, the syntax is
-changed, the PEP will be updated to match this, complete with the
-arguments for the change.
-
+The final decision on the syntax for 2.4a3 is not yet made. This
+will be done before 2.4a3, and this document will be updated to
+match. Note also that this document does not attempt to cover the
+huge number of potential alternative syntaxes, nor is it an attempt
+to exhaustively list all the positives and negatives of each form.
Abstract
========
@@ -112,6 +107,10 @@
decorator concept before encountering it in Python. There's just no
strong preexisting meme that captures the concept.
+* Syntax discussions in general appear to cause more contention than
+ almost anything else. Readers are pointed to the ternary operator
+ discussions that were associated with PEP 308 for another example of
+ this.
Background
==========
@@ -263,7 +262,7 @@
rather than attempting to work through these individual syntaxes, it's
worthwhile to break the syntax discussion down into a number of areas.
Attempting to discuss `each possible syntax`_ individually would be an
-act of madness, and produce a completely unwieldly PEP.
+act of madness, and produce a completely unwieldy PEP.
.. _a large number:
http://www.python.org/moin/PythonDecorators
@@ -295,7 +294,7 @@
will be in 2.4a3 will also require one decorator per line (in a2,
multiple decorators can be specified on the same line).
-People also complained that the syntax got unwieldly quickly when
+People also complained that the syntax got unworldly quickly when
multiple decorators were used. The point was made, though, that the
chances of a large number of decorators being used on a single function
were small and thus this was not a large worry.
@@ -310,6 +309,13 @@
properly without having to go back and change your initial perceptions
if the syntax did not come before the function definition.
+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
+
The second form is the decorators between the def and the function
name, or the function name and the argument list::
@@ -341,7 +347,7 @@
def bar(low,high) @accepts(int,int), at returns(float):
pass
-Guido `summarised the arguments`_ against this form (many of which
+Guido `summarized the arguments`_ against this form (many of which
also apply to the previous form) as:
- it hides crucial information (e.g. that it is a static method)
@@ -353,7 +359,7 @@
- it's cumbersome to cut and paste a decorator list for reuse, because
it starts and ends in the middle of a line
-.. _summarised the arguments:
+.. _summarized the arguments:
http://mail.python.org/pipermail/python-dev/2004-August/047112.html
The next form is that the decorator syntax go inside the method
@@ -399,26 +405,70 @@
Syntax forms
------------
-* ``@decorator``
+* ``@decorator``::
+
+ @classmethod
+ def foo(arg1,arg2):
+ pass
+
+ @accepts(int,int)
+ @returns(float)
+ def bar(low,high):
+ pass
The major objections against this syntax are that the @ symbol is
not currently used in Python (and is used in both IPython and Leo),
- that the @ symbol is not meaningful,
+ and that the @ symbol is not meaningful. Another objection is that
+ this "wastes" a currently unused character (from a limited set) on
+ something that is not perceived as a major use.
-* ``|decorator``
+* ``|decorator``::
+
+ |classmethod
+ def foo(arg1,arg2):
+ pass
+
+ |accepts(int,int)
+ |returns(float)
+ def bar(low,high):
+ pass
This is a variant on the @decorator syntax -- it has the advantage
that it does not break IPython and Leo. Its major disadvantage
compared to the @syntax is that the | symbol looks like both a
capital I and a lowercase l.
-* list syntax
+* list syntax::
+
+ [classmethod]
+ def foo(arg1,arg2):
+ pass
+
+ [accepts(int,int), returns(float)]
+ def bar(low,high):
+ pass
The major objection to the list syntax is that it's currently
meaningful (when used in the form before the method). It's also
lacking any indication that the expression is a decorator.
-* list syntax using other brackets (``<...>``, ``[[...]]``, ...)
+* list syntax using other brackets (``<...>``, ``[[...]]``, ...)::
+
+ <classmethod>
+ def foo(arg1,arg2):
+ pass
+
+ <accepts(int,int), returns(float)>
+ def bar(low,high):
+ pass
+
+ None of these alternatives 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.
* ``decorate()``
@@ -427,116 +477,7 @@
following function. Both Jp Calderone and Philip Eby produced
implementations of functions that did this. Guido was pretty firmly
against this -- with no new syntax, the magicness of a function like
- this is extremely high.
-
-* new keyword (and block)
-
-
-Alternate Proposals
-===================
-
-The text in this section will be integrated into the previous section.
-They're here for hysterical raisins for now.
-
-
-Several other syntaxes have been proposed::
-
- def func(arg1, arg2, ...) as dec1, dec2, ...:
- pass
-
-The absence of brackets makes it cumbersome to break long lists of
-decorators across multiple lines, and the keyword "as" doesn't have
-the same meaning as its use in the ``import`` statement. Plenty of
-`alternatives to "as"`_ have been proposed. :-) ::
-
- def [dec1, dec2, ...] func(arg1, arg2, ...):
- pass
-
-.. _alternatives to "as":
- http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=mailman.236.1079968472.742.python-list%40python.org&rnum=2&prev=/groups%3Fq%3Dpython%2Bpep%2B318%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3Dmailman.236.1079968472.742.python-list%2540python.org%26rnum%3D2
-
-This form has the disadvantage that the decorators visually assume
-higher priority than the function name and argument list. ::
-
- def func [dec1, dec2, ...] (arg1, arg2, ...):
- pass
-
-Quixote's `Python Template Language`_ uses this form, but only
-supports a single decorator chosen from a restricted set. For short
-lists it works okay, but for long list it separates the argument list
-from the function name. ::
-
- using:
- dec1
- dec2
- ...
- def foo(arg1, arg2, ...):
- pass
-
-.. _Python Template Language:
- http://www.mems-exchange.org/software/quixote/doc/PTL.html
-
-The function definition is not nested within the using: block making
-it impossible to tell which objects following the block will be
-decorated. Nesting the function definition within the using: block
-suggests nesting of namespaces that doesn't exist. The name ``foo``
-would actually exist at the same scope as the using: block. Finally,
-it would require the introduction of a new keyword.
-
-The obvious alternative that nests the function within the block ::
-
- using:
- dec1
- dec2
- ...
- def foo(arg1, arg2, ...):
- pass
-
-has its own set of drawbacks. Having the minimal indent level be
-three deep for methods is painful for those using limited-width
-windows. The inconsistent indentation between methods of the same
-class with and without decorators would be a readability problem.
-Finally, adding or removing decorators would require reindenting the
-entire function/method body.
-
-Guido proposed and implemented a patch to support interpretation of
-a `list of decorators`_ as a prefix to function definitions ::
-
- [dec1, dec2, ...]
- def foo(arg1, arg2, ...):
- pass
-
-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.
-
-One attraction people later had to the syntax, though, was the
-possibility of implementing a backwards-compatible implementation of
-decorators so that versions prior to 2.4 (back to 2.2) could also use
-the new syntax. But it was decided this was not a valid argument;
-Since the feature is new it should not be restricted just so that
-previous versions could possibly use it.
-
-.. _list of decorators:
- http://python.org/sf/926860
-
-Another variant on the list syntax that was initially favored was::
-
- def func(arg1, arg2, ...) [dec1, dec2]:
- pass
-
-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:
+ this is extremely high:
Using functions with "action-at-a-distance" through
sys.settraceback may be okay for an obscure feature that can't be
@@ -548,14 +489,29 @@
their design needs to be forward-looking, not constrained by what
can be implemented in 2.3.
-A `page on the Python Wiki`_ was created to summarize a number of the
-proposals. Once it stabilizes perhaps someone would care to
-incorporate its content into this PEP (hint, hint).
+* new keyword (and block)
-.. _page on the Python Wiki:
- http://www.python.org/moin/PythonDecorators
+ This idea was the consensus alternate from comp.lang.python. Robert
+ Brewer wrote up a detailed `J2 proposal`_ document outlining the arguments
+ in favor of this. The issues with this form are that it requires a new
+ keyword (and therefore a ``from __future__ import decorators`` statement),
+ it seems like there is no obvious choice for the keyword (``using`` is
+ the choice of the proposal and implementation), and that the form
+ produces something that looks like a normal code block, but isn't. Attempts
+ to use statements in this block will cause a syntax error. It's also
+ going to potentially confuse users who don't expect a block to contain
+ bare expressions.
+
+
+.. _J2 proposal:
+ http://www.aminus.org/rbre/python/pydec.html
+There are plenty of other variants and proposals on `the wiki page`_.
+
+.. _the wiki page:
+ http://www.python.org/moin/PythonDecorators
+
Why @?
------
@@ -570,13 +526,8 @@
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.
+``[|...|]``, ``*[...]*``, and ``<...>``.
+
.. _Javadoc comments:
http://java.sun.com/j2se/javadoc/writingdoccomments/
@@ -584,10 +535,10 @@
http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
-Current Implementation
-======================
+Current Implementation, History
+===============================
-Guido asked for a voluteer to implement his preferred syntax, and Mark
+Guido asked for a volunteer to implement his preferred syntax, and Mark
Russell stepped up and posted a `patch`_ to SF. The syntax accepted
for 2.4a2 is::
@@ -610,6 +561,24 @@
.. _patch: http://www.python.org/sf/979728
.. _previous patch: http://starship.python.net/crew/mwh/hacks/meth-syntax-sugar-3.diff
+After 2.4a2 was released, in response to community reaction, Guido
+stated that he'd re-examine a community proposal, if the community
+could come up with a community consensus, a decent proposal, and an
+implementation.
+
+After an amazing number of posts, collecting a vast number of alternatives
+in the `Python wiki`_, the proposed J2 syntax (the new keyword ``using``
+in a block before the def). Robert Brewer wrote a `detailed proposal`_
+for this form, and Michael Sparks produced `a patch`_. As at time of
+writing, we're waiting for Guido's decision.
+
+.. _Python wiki:
+ http://www.python.org/moin/PythonDecorators
+.. _detailed proposal:
+ http://www.aminus.org/rbre/python/pydec.html
+.. _a patch:
+ http://www.python.org/sf/1013835
+
Examples
========
@@ -632,6 +601,9 @@
def func():
...
+ Note that this example is probably not suitable for real usage, but
+ is for example purposes only.
+
2. Define a class with a singleton instance. Note that once the class
disappears enterprising programmers would have to be more creative
to create more instances. (From Shane Hathaway on ``python-dev``.)
@@ -664,9 +636,9 @@
def mymethod(f):
...
-4. Enforce function argument and return types. (Note that this is not
- exactly correct, as the returned new_f doesn't have "func" as its
- func_name attribute.) ::
+4. Enforce function argument and return types. Note that this
+ copies the func_name attribute from the old to the new function.
+ func_name was made writable in Python 2.4a3::
def accepts(*types):
def check_accepts(f):
@@ -676,6 +648,7 @@
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)
return f(*args, **kwds)
+ new_f.func_name = f.func_name
return new_f
return check_accepts
@@ -686,6 +659,7 @@
assert isinstance(result, rtype), \
"return value %r does not match %s" % (result,rtype)
return result
+ new_f.func_name = f.func_name
return new_f
return check_returns
More information about the Python-checkins
mailing list