[Python-3000] PEP 3129: Class Decorators
Collin Winter
collinw at gmail.com
Mon May 7 20:29:25 CEST 2007
Guido pointed out that this PEP hadn't been sent to the list yet.
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
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.
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.
The following two snippets are semantically identical: ::
class A:
pass
A = foo(bar(A))
@foo
@bar
class A:
pass
For a detailed examination of decorators, please refer to PEP 318.
Implementation
==============
Adapating Python's grammar to support class decorators requires
modifying two rules and adding a new rule ::
funcdef: [decorators] 'def' NAME parameters ['->' test] ':' suite
compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt |
with_stmt | funcdef | classdef
need to be changed to ::
decorated: decorators (classdef | funcdef)
funcdef: 'def' NAME parameters ['->' test] ':' suite
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.
The Python AST and bytecode must be modified accordingly.
A reference implementation [#implementation]_ has been provided by
Jack Diederich.
References
==========
.. [#obscure]
http://www.python.org/dev/peps/pep-0318/#motivation
.. [#approval]
http://mail.python.org/pipermail/python-dev/2006-March/062942.html
.. [#motivation]
http://mail.python.org/pipermail/python-dev/2006-March/062888.html
.. [#semantics]
http://www.python.org/dev/peps/pep-0318/#current-syntax
.. [#goals]
http://www.python.org/dev/peps/pep-0318/#design-goals
.. [#implementation]
http://python.org/sf/1671208
More information about the Python-3000
mailing list