Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit add3360

Browse files
committed
Correct the order of application for decorators. Meant to be bottom-up and not
top-down. Now matches the PEP.
1 parent 31f8350 commit add3360

3 files changed

Lines changed: 23 additions & 8 deletions

File tree

Lib/test/test_decorators.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ def test_memoize(self):
129129
# XXX: This doesn't work unless memoize is the last decorator -
130130
# see the comment in countcalls.
131131
counts = {}
132-
@countcalls(counts) @memoize
132+
@memoize
133+
@countcalls(counts)
133134
def double(x):
134135
return x * 2
135136

@@ -186,12 +187,20 @@ def foo(self): return 42
186187
self.assertEqual(C.foo.booh, 42)
187188

188189
def test_order(self):
189-
class C(object):
190-
@funcattrs(abc=1) @staticmethod
191-
def foo(): return 42
192-
# This wouldn't work if staticmethod was called first
193-
self.assertEqual(C.foo(), 42)
194-
self.assertEqual(C().foo(), 42)
190+
# Test that decorators are conceptually applied right-recursively;
191+
# that means bottom-up
192+
def ordercheck(num):
193+
def deco(func):
194+
return lambda: num
195+
return deco
196+
197+
# Should go ordercheck(1)(ordercheck(2)(blah)) which should lead to
198+
# blah() == 1
199+
@ordercheck(1)
200+
@ordercheck(2)
201+
def blah(): pass
202+
self.assertEqual(blah(), 1, "decorators are meant to be applied "
203+
"bottom-up")
195204

196205
def test_main():
197206
test_support.run_unittest(TestDecorators)

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.4 alpha 3?
1212
Core and builtins
1313
-----------------
1414

15+
- Fix the order of application of decorators. The proper order is bottom-up;
16+
the first decorator listed is the last one called.
17+
1518
- SF patch #1005778. Fix a seg fault if the list size changed while
1619
calling list.index(). This could happen if a rich comparison function
1720
modified the list.

Python/compile.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4132,7 +4132,10 @@ com_decorators(struct compiling *c, node *n)
41324132
REQ(CHILD(n, nch - 1), NEWLINE);
41334133

41344134
ndecorators = 0;
4135-
for (i = NCH(n) - 1; i >= 0; --i) {
4135+
/* the application order for decorators is the reverse of how they are
4136+
listed; bottom-up */
4137+
nch -= 1;
4138+
for (i = 0; i < nch; i+=1) {
41364139
node *ch = CHILD(n, i);
41374140
if (TYPE(ch) != NEWLINE) {
41384141
com_decorator(c, ch);

0 commit comments

Comments
 (0)