Skip to content

Commit c2a5a63

Browse files
committed
PEP-0318, @decorator-style. In Guido's words:
"@ seems the syntax that everybody can hate equally" Implementation by Mark Russell, from SF #979728.
1 parent fd7dc51 commit c2a5a63

28 files changed

+2562
-1932
lines changed

Doc/lib/asttable.tex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@
7373
\lineiii{Continue}{}{}
7474
\hline
7575

76+
\lineiii{Decorators}{\member{nodes}}{List of function decorator expressions}
77+
\hline
78+
7679
\lineiii{Dict}{\member{items}}{}
7780
\hline
7881

@@ -101,7 +104,8 @@
101104
\lineiii{}{\member{names}}{}
102105
\hline
103106

104-
\lineiii{Function}{\member{name}}{name used in def, a string}
107+
\lineiii{Function}{\member{decorators}}{\class{Decorators} or \code{None}}
108+
\lineiii{}{\member{name}}{name used in def, a string}
105109
\lineiii{}{\member{argnames}}{list of argument names, as strings}
106110
\lineiii{}{\member{defaults}}{list of default values}
107111
\lineiii{}{\member{flags}}{xxx}

Doc/lib/libfuncs.tex

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,14 @@ \section{Built-in Functions \label{built-in-funcs}}
109109

110110
\begin{verbatim}
111111
class C:
112+
@classmethod
112113
def f(cls, arg1, arg2, ...): ...
113-
f = classmethod(f)
114114
\end{verbatim}
115115

116+
The \code{@classmethod} form is a function decorator -- see the description
117+
of function definitions in chapter 7 of the
118+
\citetitle[../ref/ref.html]{Python Reference Manual} for details.
119+
116120
It can be called either on the class (such as \code{C.f()}) or on an
117121
instance (such as \code{C().f()}). The instance is ignored except for
118122
its class.
@@ -122,6 +126,7 @@ \section{Built-in Functions \label{built-in-funcs}}
122126
Class methods are different than \Cpp{} or Java static methods.
123127
If you want those, see \function{staticmethod()} in this section.
124128
\versionadded{2.2}
129+
Function decorator syntax added in version 2.4.
125130
\end{funcdesc}
126131

127132
\begin{funcdesc}{cmp}{x, y}
@@ -936,10 +941,14 @@ \section{Built-in Functions \label{built-in-funcs}}
936941

937942
\begin{verbatim}
938943
class C:
944+
@staticmethod
939945
def f(arg1, arg2, ...): ...
940-
f = staticmethod(f)
941946
\end{verbatim}
942947

948+
The \code{@staticmethod} form is a function decorator -- see the description
949+
of function definitions in chapter 7 of the
950+
\citetitle[../ref/ref.html]{Python Reference Manual} for details.
951+
943952
It can be called either on the class (such as \code{C.f()}) or on an
944953
instance (such as \code{C().f()}). The instance is ignored except
945954
for its class.

Doc/ref/ref7.tex

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,12 @@ \section{Function definitions\label{function}}
315315

316316
\begin{productionlist}
317317
\production{funcdef}
318-
{"def" \token{funcname} "(" [\token{parameter_list}] ")"
318+
{[\token{decorators}] "def" \token{funcname} "(" [\token{parameter_list}] ")"
319319
":" \token{suite}}
320+
\production{decorators}
321+
{\token{decorator} ([NEWLINE] \token{decorator})* NEWLINE}
322+
\production{decorator}
323+
{"@" \token{dotted_name} ["(" [\token{argument_list} [","]] ")"]}
320324
\production{parameter_list}
321325
{(\token{defparameter} ",")*}
322326
\productioncont{("*" \token{identifier} [, "**" \token{identifier}]}
@@ -343,6 +347,27 @@ \section{Function definitions\label{function}}
343347
The function definition does not execute the function body; this gets
344348
executed only when the function is called.
345349

350+
A function definition may be wrapped by one or more decorator expressions.
351+
Decorator expressions are evaluated when the function is defined, in the scope
352+
that contains the function definition. The result must be a callable,
353+
which is invoked with the function object as the only argument.
354+
The returned value is bound to the function name instead of the function
355+
object. If there are multiple decorators, they are applied in reverse
356+
order. For example, the following code:
357+
358+
\begin{verbatim}
359+
@f1
360+
@f2
361+
def func(): pass
362+
\end{verbatim}
363+
364+
is equivalent to:
365+
366+
\begin{verbatim}
367+
def func(): pass
368+
func = f2(f1(func))
369+
\end{verbatim}
370+
346371
When one or more top-level parameters have the form \var{parameter}
347372
\code{=} \var{expression}, the function is said to have ``default
348373
parameter values.'' For a parameter with a

Grammar/Grammar

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
2828
file_input: (NEWLINE | stmt)* ENDMARKER
2929
eval_input: testlist NEWLINE* ENDMARKER
3030

31-
funcdef: 'def' NAME parameters ':' suite
31+
decorator: '@' dotted_name [ '(' [arglist] ')' ]
32+
decorators: decorator ([NEWLINE] decorator)* NEWLINE
33+
funcdef: [decorators] 'def' NAME parameters ':' suite
3234
parameters: '(' [varargslist] ')'
3335
varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
3436
fpdef: NAME | '(' fplist ')'

Include/graminit.h

Lines changed: 71 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,74 @@
11
#define single_input 256
22
#define file_input 257
33
#define eval_input 258
4-
#define funcdef 259
5-
#define parameters 260
6-
#define varargslist 261
7-
#define fpdef 262
8-
#define fplist 263
9-
#define stmt 264
10-
#define simple_stmt 265
11-
#define small_stmt 266
12-
#define expr_stmt 267
13-
#define augassign 268
14-
#define print_stmt 269
15-
#define del_stmt 270
16-
#define pass_stmt 271
17-
#define flow_stmt 272
18-
#define break_stmt 273
19-
#define continue_stmt 274
20-
#define return_stmt 275
21-
#define yield_stmt 276
22-
#define raise_stmt 277
23-
#define import_stmt 278
24-
#define import_as_name 279
25-
#define dotted_as_name 280
26-
#define dotted_name 281
27-
#define global_stmt 282
28-
#define exec_stmt 283
29-
#define assert_stmt 284
30-
#define compound_stmt 285
31-
#define if_stmt 286
32-
#define while_stmt 287
33-
#define for_stmt 288
34-
#define try_stmt 289
35-
#define except_clause 290
36-
#define suite 291
37-
#define test 292
38-
#define and_test 293
39-
#define not_test 294
40-
#define comparison 295
41-
#define comp_op 296
42-
#define expr 297
43-
#define xor_expr 298
44-
#define and_expr 299
45-
#define shift_expr 300
46-
#define arith_expr 301
47-
#define term 302
48-
#define factor 303
49-
#define power 304
50-
#define atom 305
51-
#define listmaker 306
52-
#define testlist_gexp 307
53-
#define lambdef 308
54-
#define trailer 309
55-
#define subscriptlist 310
56-
#define subscript 311
57-
#define sliceop 312
58-
#define exprlist 313
59-
#define testlist 314
60-
#define testlist_safe 315
61-
#define dictmaker 316
62-
#define classdef 317
63-
#define arglist 318
64-
#define argument 319
65-
#define list_iter 320
66-
#define list_for 321
67-
#define list_if 322
68-
#define gen_iter 323
69-
#define gen_for 324
70-
#define gen_if 325
71-
#define testlist1 326
72-
#define encoding_decl 327
4+
#define decorator 259
5+
#define decorators 260
6+
#define funcdef 261
7+
#define parameters 262
8+
#define varargslist 263
9+
#define fpdef 264
10+
#define fplist 265
11+
#define stmt 266
12+
#define simple_stmt 267
13+
#define small_stmt 268
14+
#define expr_stmt 269
15+
#define augassign 270
16+
#define print_stmt 271
17+
#define del_stmt 272
18+
#define pass_stmt 273
19+
#define flow_stmt 274
20+
#define break_stmt 275
21+
#define continue_stmt 276
22+
#define return_stmt 277
23+
#define yield_stmt 278
24+
#define raise_stmt 279
25+
#define import_stmt 280
26+
#define import_as_name 281
27+
#define dotted_as_name 282
28+
#define dotted_name 283
29+
#define global_stmt 284
30+
#define exec_stmt 285
31+
#define assert_stmt 286
32+
#define compound_stmt 287
33+
#define if_stmt 288
34+
#define while_stmt 289
35+
#define for_stmt 290
36+
#define try_stmt 291
37+
#define except_clause 292
38+
#define suite 293
39+
#define test 294
40+
#define and_test 295
41+
#define not_test 296
42+
#define comparison 297
43+
#define comp_op 298
44+
#define expr 299
45+
#define xor_expr 300
46+
#define and_expr 301
47+
#define shift_expr 302
48+
#define arith_expr 303
49+
#define term 304
50+
#define factor 305
51+
#define power 306
52+
#define atom 307
53+
#define listmaker 308
54+
#define testlist_gexp 309
55+
#define lambdef 310
56+
#define trailer 311
57+
#define subscriptlist 312
58+
#define subscript 313
59+
#define sliceop 314
60+
#define exprlist 315
61+
#define testlist 316
62+
#define testlist_safe 317
63+
#define dictmaker 318
64+
#define classdef 319
65+
#define arglist 320
66+
#define argument 321
67+
#define list_iter 322
68+
#define list_for 323
69+
#define list_if 324
70+
#define gen_iter 325
71+
#define gen_for 326
72+
#define gen_if 327
73+
#define testlist1 328
74+
#define encoding_decl 329

Include/node.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ PyAPI_FUNC(void) PyNode_Free(node *n);
2222

2323
/* Node access functions */
2424
#define NCH(n) ((n)->n_nchildren)
25+
2526
#define CHILD(n, i) (&(n)->n_child[i])
27+
#define RCHILD(n, i) (CHILD(n, NCH(n) + i))
2628
#define TYPE(n) ((n)->n_type)
2729
#define STR(n) ((n)->n_str)
2830

Include/token.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ extern "C" {
5757
#define DOUBLESTAREQUAL 47
5858
#define DOUBLESLASH 48
5959
#define DOUBLESLASHEQUAL 49
60+
#define AT 50
6061
/* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */
61-
#define OP 50
62-
#define ERRORTOKEN 51
63-
#define N_TOKENS 52
62+
#define OP 51
63+
#define ERRORTOKEN 52
64+
#define N_TOKENS 53
6465

6566
/* Special definitions for cooperation with parser */
6667

0 commit comments

Comments
 (0)