2007-05-01 14:31:51 -04:00
|
|
|
|
PEP: 3129
|
|
|
|
|
Title: Class Decorators
|
2007-05-07 15:05:28 -04:00
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
2010-01-20 20:23:17 -05:00
|
|
|
|
Author: Collin Winter <collinwinter@google.com>
|
2007-05-18 13:09:42 -04:00
|
|
|
|
Status: Final
|
2007-05-01 14:31:51 -04:00
|
|
|
|
Type: Standards Track
|
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
|
Created: 1-May-2007
|
|
|
|
|
Python-Version: 3.0
|
2007-05-07 15:05:28 -04:00
|
|
|
|
Post-History: 7-May-2007
|
2007-05-01 14:31:51 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
This PEP proposes class decorators, an extension to the function
|
|
|
|
|
and method decorators introduced in PEP 318.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
When function decorators were originally debated for inclusion in
|
|
|
|
|
Python 2.4, class decorators were seen as obscure and unnecessary
|
|
|
|
|
[#obscure]_ thanks to metaclasses. After several years' experience
|
|
|
|
|
with the Python 2.4.x series of releases and an increasing
|
|
|
|
|
familiarity with function decorators and their uses, the BDFL and
|
|
|
|
|
the community re-evaluated class decorators and recommended their
|
|
|
|
|
inclusion in Python 3.0 [#approval]_.
|
|
|
|
|
|
|
|
|
|
The motivating use-case was to make certain constructs more easily
|
|
|
|
|
expressed and less reliant on implementation details of the CPython
|
|
|
|
|
interpreter. While it is possible to express class decorator-like
|
|
|
|
|
functionality using metaclasses, the results are generally
|
2007-05-01 15:08:28 -04:00
|
|
|
|
unpleasant and the implementation highly fragile [#motivation]_. In
|
|
|
|
|
addition, metaclasses are inherited, whereas class decorators are not,
|
|
|
|
|
making metaclasses unsuitable for some, single class-specific uses of
|
|
|
|
|
class decorators. The fact that large-scale Python projects like Zope
|
|
|
|
|
were going through these wild contortions to achieve something like
|
|
|
|
|
class decorators won over the BDFL.
|
2007-05-01 14:31:51 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Semantics
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
The semantics and design goals of class decorators are the same as
|
|
|
|
|
for function decorators ([#semantics]_, [#goals]_); the only
|
|
|
|
|
difference is that you're decorating a class instead of a function.
|
2007-05-18 13:09:42 -04:00
|
|
|
|
The following two snippets are semantically identical::
|
2007-05-01 14:31:51 -04:00
|
|
|
|
|
|
|
|
|
class A:
|
|
|
|
|
pass
|
|
|
|
|
A = foo(bar(A))
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
|
|
|
|
|
2007-05-01 14:31:51 -04:00
|
|
|
|
@foo
|
|
|
|
|
@bar
|
|
|
|
|
class A:
|
|
|
|
|
pass
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 14:31:51 -04:00
|
|
|
|
For a detailed examination of decorators, please refer to PEP 318.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Implementation
|
|
|
|
|
==============
|
|
|
|
|
|
2009-07-02 11:58:38 -04:00
|
|
|
|
Adapting Python's grammar to support class decorators requires
|
2007-05-18 13:09:42 -04:00
|
|
|
|
modifying two rules and adding a new rule::
|
2007-05-01 16:14:28 -04:00
|
|
|
|
|
|
|
|
|
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 16:14:28 -04:00
|
|
|
|
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt |
|
|
|
|
|
with_stmt | funcdef | classdef
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 16:14:28 -04:00
|
|
|
|
need to be changed to ::
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 16:14:28 -04:00
|
|
|
|
decorated: decorators (classdef | funcdef)
|
|
|
|
|
|
|
|
|
|
funcdef: 'def' NAME parameters ['->' test] ':' suite
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 16:14:28 -04:00
|
|
|
|
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt |
|
|
|
|
|
with_stmt | funcdef | classdef | decorated
|
|
|
|
|
|
|
|
|
|
Adding ``decorated`` is necessary to avoid an ambiguity in the
|
|
|
|
|
grammar.
|
2007-05-01 14:31:51 -04:00
|
|
|
|
|
|
|
|
|
The Python AST and bytecode must be modified accordingly.
|
|
|
|
|
|
|
|
|
|
A reference implementation [#implementation]_ has been provided by
|
|
|
|
|
Jack Diederich.
|
|
|
|
|
|
|
|
|
|
|
2007-05-18 13:09:42 -04:00
|
|
|
|
Acceptance
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
There was virtually no discussion following the posting of this PEP,
|
|
|
|
|
meaning that everyone agreed it should be accepted.
|
|
|
|
|
|
|
|
|
|
The patch was committed to Subversion as revision 55430.
|
|
|
|
|
|
|
|
|
|
|
2007-05-01 14:31:51 -04:00
|
|
|
|
References
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
.. [#obscure]
|
|
|
|
|
http://www.python.org/dev/peps/pep-0318/#motivation
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 14:31:51 -04:00
|
|
|
|
.. [#approval]
|
2017-06-11 15:02:39 -04:00
|
|
|
|
https://mail.python.org/pipermail/python-dev/2006-March/062942.html
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 14:31:51 -04:00
|
|
|
|
.. [#motivation]
|
2017-06-11 15:02:39 -04:00
|
|
|
|
https://mail.python.org/pipermail/python-dev/2006-March/062888.html
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 14:31:51 -04:00
|
|
|
|
.. [#semantics]
|
|
|
|
|
http://www.python.org/dev/peps/pep-0318/#current-syntax
|
|
|
|
|
|
|
|
|
|
.. [#goals]
|
|
|
|
|
http://www.python.org/dev/peps/pep-0318/#design-goals
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 14:31:51 -04:00
|
|
|
|
.. [#implementation]
|
|
|
|
|
http://python.org/sf/1671208
|
2017-03-24 17:11:33 -04:00
|
|
|
|
|
2007-05-01 14:31:51 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
This document has been placed in the public domain.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
..
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
sentence-end-double-space: t
|
|
|
|
|
fill-column: 70
|
|
|
|
|
coding: utf-8
|
|
|
|
|
End:
|