PEP: 3129 Title: Class Decorators Version: $Revision$ Last-Modified: $Date$ Author: Collin Winter Status: Final Type: Standards Track Content-Type: text/x-rst Created: 1-May-2007 Python-Version: 3.0 Post-History: 7-May-2007 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 ============== Adapting 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. 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. 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 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: