fixed list containment (indents) & whitespace
This commit is contained in:
parent
7a9247a8dc
commit
c0bf347be9
158
pep-0318.txt
158
pep-0318.txt
|
@ -2,7 +2,7 @@ PEP: 318
|
||||||
Title: Decorators for Functions, Methods and Classes
|
Title: Decorators for Functions, Methods and Classes
|
||||||
Version: $Revision$
|
Version: $Revision$
|
||||||
Last-Modified: $Date$
|
Last-Modified: $Date$
|
||||||
Author: Kevin D. Smith <Kevin.Smith@theMorgue.org>,
|
Author: Kevin D. Smith <Kevin.Smith@theMorgue.org>,
|
||||||
Jim Jewett <jimjjewett@users.sourceforge.net>,
|
Jim Jewett <jimjjewett@users.sourceforge.net>,
|
||||||
Skip Montanaro <skip@pobox.com>
|
Skip Montanaro <skip@pobox.com>
|
||||||
Status: Draft
|
Status: Draft
|
||||||
|
@ -61,6 +61,7 @@ metaclasses, but using metaclasses is sufficiently obscure that there
|
||||||
is some attraction to having an easier way to make simple
|
is some attraction to having an easier way to make simple
|
||||||
modifications to classes.
|
modifications to classes.
|
||||||
|
|
||||||
|
|
||||||
Background
|
Background
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
@ -73,15 +74,21 @@ the topic`_ on ``python-dev`` shortly after the conference,
|
||||||
attributing the bracketed syntax to an earlier proposal on
|
attributing the bracketed syntax to an earlier proposal on
|
||||||
``comp.lang.python`` by `Gareth McCaughan`_.
|
``comp.lang.python`` by `Gareth McCaughan`_.
|
||||||
|
|
||||||
.. _syntactic support for decorators: http://www.python.org/doc/essays/ppt/python10/py10keynote.pdf
|
.. _syntactic support for decorators:
|
||||||
.. _10th python conference: http://www.python.org/workshops/2002-02/
|
http://www.python.org/doc/essays/ppt/python10/py10keynote.pdf
|
||||||
.. _michael hudson raised the topic: http://mail.python.org/pipermail/python-dev/2002-February/020005.html
|
.. _10th python conference:
|
||||||
.. _he later said: http://mail.python.org/pipermail/python-dev/2002-February/020017.html
|
http://www.python.org/workshops/2002-02/
|
||||||
.. _gareth mccaughan: http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=slrna40k88.2h9o.Gareth.McCaughan%40g.local
|
.. _michael hudson raised the topic:
|
||||||
|
http://mail.python.org/pipermail/python-dev/2002-February/020005.html
|
||||||
|
.. _he later said:
|
||||||
|
http://mail.python.org/pipermail/python-dev/2002-February/020017.html
|
||||||
|
.. _gareth mccaughan:
|
||||||
|
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=slrna40k88.2h9o.Gareth.McCaughan%40g.local
|
||||||
|
|
||||||
Class decorations seem like an obvious next step because class
|
Class decorations seem like an obvious next step because class
|
||||||
definition and function definition are syntactically similar.
|
definition and function definition are syntactically similar.
|
||||||
|
|
||||||
|
|
||||||
Design Goals
|
Design Goals
|
||||||
============
|
============
|
||||||
|
|
||||||
|
@ -109,7 +116,9 @@ The new syntax should
|
||||||
language-sensitive editors and other "`toy parser tools out
|
language-sensitive editors and other "`toy parser tools out
|
||||||
there`_"
|
there`_"
|
||||||
|
|
||||||
.. _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
|
.. _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
|
||||||
|
|
||||||
|
|
||||||
Proposed Syntax
|
Proposed Syntax
|
||||||
===============
|
===============
|
||||||
|
@ -128,6 +137,7 @@ Class decorators are defined in an analogous fashion::
|
||||||
class MyClass(base1, base2) [dec1, dec2, ...]:
|
class MyClass(base1, base2) [dec1, dec2, ...]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
Alternate Proposals
|
Alternate Proposals
|
||||||
===================
|
===================
|
||||||
|
|
||||||
|
@ -141,7 +151,8 @@ decorators across multiple lines, and the keyword "as" doesn't have
|
||||||
the same meaning as its use in the ``import`` statement. Plenty of
|
the same meaning as its use in the ``import`` statement. Plenty of
|
||||||
`alternatives to "as"`_ have been proposed. :-)
|
`alternatives to "as"`_ have been proposed. :-)
|
||||||
|
|
||||||
.. _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
|
.. _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
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -161,7 +172,8 @@ single decorator chosen from a restricted set. For short lists it
|
||||||
works okay, but for long list it separates the argument list from the
|
works okay, but for long list it separates the argument list from the
|
||||||
function name.
|
function name.
|
||||||
|
|
||||||
.. _Python Template Language: http://www.mems-exchange.org/software/quixote/doc/PTL.html
|
.. _Python Template Language:
|
||||||
|
http://www.mems-exchange.org/software/quixote/doc/PTL.html
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
@ -179,6 +191,7 @@ suggests nesting of namespaces that doesn't exist. The name ``foo``
|
||||||
would actually exist at the same scope as the using: block. Finally,
|
would actually exist at the same scope as the using: block. Finally,
|
||||||
it would require the introduction of a new keyword.
|
it would require the introduction of a new keyword.
|
||||||
|
|
||||||
|
|
||||||
Current Implementation
|
Current Implementation
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
@ -199,6 +212,7 @@ 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://starship.python.net/crew/mwh/hacks/meth-syntax-sugar-3.diff
|
||||||
|
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
========
|
========
|
||||||
|
|
||||||
|
@ -211,101 +225,102 @@ some examples of use.
|
||||||
1. Define a function to be executed at exit. Note that the function
|
1. Define a function to be executed at exit. Note that the function
|
||||||
isn't actually "wrapped" in the usual sense.
|
isn't actually "wrapped" in the usual sense.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
def onexit(f):
|
def onexit(f):
|
||||||
import atexit
|
import atexit
|
||||||
atexit.register(f)
|
atexit.register(f)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def func() [onexit]:
|
def func() [onexit]:
|
||||||
...
|
...
|
||||||
|
|
||||||
2. Define a class with a singleton instance. Note that once the class
|
2. Define a class with a singleton instance. Note that once the class
|
||||||
disappears enterprising programmers would have to be more creative
|
disappears enterprising programmers would have to be more creative
|
||||||
to create more instances. (From Shane Hathaway on ``python-dev``.)
|
to create more instances. (From Shane Hathaway on ``python-dev``.)
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
def singleton(cls):
|
def singleton(cls):
|
||||||
return cls()
|
return cls()
|
||||||
|
|
||||||
class MyClass [singleton]:
|
class MyClass [singleton]:
|
||||||
...
|
...
|
||||||
|
|
||||||
3. Decorate a function with release information. (Based on an example
|
3. Decorate a function with release information. (Based on an example
|
||||||
posted by Anders Munch on ``python-dev``.)
|
posted by Anders Munch on ``python-dev``.)
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
def release(**kwds):
|
def release(**kwds):
|
||||||
def decorate(f):
|
def decorate(f):
|
||||||
for k in kwds:
|
for k in kwds:
|
||||||
setattr(f, k, kwds[k])
|
setattr(f, k, kwds[k])
|
||||||
return f
|
return f
|
||||||
return decorate
|
return decorate
|
||||||
|
|
||||||
def mymethod(f) [release(versionadded="2.2",
|
def mymethod(f) [release(versionadded="2.2",
|
||||||
author="Guido van Rossum")]:
|
author="Guido van Rossum")]:
|
||||||
...
|
...
|
||||||
|
|
||||||
4. Enforce function argument and return types.
|
4. Enforce function argument and return types.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
def accepts(*types):
|
def accepts(*types):
|
||||||
def check_accepts(f):
|
def check_accepts(f):
|
||||||
assert len(types) == f.func_code.co_argcount
|
assert len(types) == f.func_code.co_argcount
|
||||||
def new_f(*args, **kwds):
|
def new_f(*args, **kwds):
|
||||||
for (a, t) in zip(args, types):
|
for (a, t) in zip(args, types):
|
||||||
assert isinstance(a, t), \
|
assert isinstance(a, t), \
|
||||||
"arg %r does not match %s" % (a,t)
|
"arg %r does not match %s" % (a,t)
|
||||||
return f(*args, **kwds)
|
return f(*args, **kwds)
|
||||||
return new_f
|
return new_f
|
||||||
return check_accepts
|
return check_accepts
|
||||||
|
|
||||||
def returns(rtype):
|
def returns(rtype):
|
||||||
def check_returns(f):
|
def check_returns(f):
|
||||||
def new_f(*args, **kwds):
|
def new_f(*args, **kwds):
|
||||||
result = f(*args, **kwds)
|
result = f(*args, **kwds)
|
||||||
assert isinstance(result, rtype), \
|
assert isinstance(result, rtype), \
|
||||||
"return value %r does not match %s" % (result,rtype)
|
"return value %r does not match %s" % (result,rtype)
|
||||||
return result
|
return result
|
||||||
return new_f
|
return new_f
|
||||||
return check_returns
|
return check_returns
|
||||||
|
|
||||||
def func(arg1, arg2) [accepts(int, (int,float)),
|
def func(arg1, arg2) [accepts(int, (int,float)),
|
||||||
returns((int,float))]:
|
returns((int,float))]:
|
||||||
return arg1 * arg2
|
return arg1 * arg2
|
||||||
|
|
||||||
5. Declare that a class implements a particular (set of) interface(s).
|
5. Declare that a class implements a particular (set of) interface(s).
|
||||||
This is from a posting by Bob Ippolito on ``python-dev`` based on
|
This is from a posting by Bob Ippolito on ``python-dev`` based on
|
||||||
experience with `PyProtocols`_.
|
experience with `PyProtocols`_.
|
||||||
|
|
||||||
.. _PyProtocols: http://peak.telecommunity.com/PyProtocols.html
|
.. _PyProtocols: http://peak.telecommunity.com/PyProtocols.html
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
def provides(*interfaces):
|
def provides(*interfaces):
|
||||||
"""
|
"""
|
||||||
An actual, working, implementation of provides for
|
An actual, working, implementation of provides for
|
||||||
the current implementation of PyProtocols. Not
|
the current implementation of PyProtocols. Not
|
||||||
particularly important for the PEP text.
|
particularly important for the PEP text.
|
||||||
"""
|
"""
|
||||||
def provides(typ):
|
def provides(typ):
|
||||||
declareImplementation(typ, instancesProvide=interfaces)
|
declareImplementation(typ, instancesProvide=interfaces)
|
||||||
return typ
|
return typ
|
||||||
return provides
|
return provides
|
||||||
|
|
||||||
class IBar(Interface):
|
class IBar(Interface):
|
||||||
"""Declare something about IBar here"""
|
"""Declare something about IBar here"""
|
||||||
|
|
||||||
class Foo(object) [provides(IBar)]:
|
class Foo(object) [provides(IBar)]:
|
||||||
"""Implement something here..."""
|
"""Implement something here..."""
|
||||||
|
|
||||||
Of course, all these examples are possible today, though without the
|
Of course, all these examples are possible today, though without the
|
||||||
syntactic support.
|
syntactic support.
|
||||||
|
|
||||||
|
|
||||||
Open Issues
|
Open Issues
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
@ -315,7 +330,8 @@ Open Issues
|
||||||
(search for ``PEP 318 - posting draft``) on their behalf in
|
(search for ``PEP 318 - posting draft``) on their behalf in
|
||||||
``python-dev``.
|
``python-dev``.
|
||||||
|
|
||||||
.. _strong arguments: http://mail.python.org/pipermail/python-dev/2004-March/thread.html
|
.. _strong arguments:
|
||||||
|
http://mail.python.org/pipermail/python-dev/2004-March/thread.html
|
||||||
|
|
||||||
|
|
||||||
Copyright
|
Copyright
|
||||||
|
|
Loading…
Reference in New Issue