mirror of
https://github.com/python/cpython.git
synced 2025-08-07 18:38:38 +00:00
Correct the order of application for decorators. Meant to be bottom-up and not
top-down. Now matches the PEP.
This commit is contained in:
parent
31f8350f43
commit
add33601c2
3 changed files with 23 additions and 8 deletions
|
@ -129,7 +129,8 @@ class TestDecorators(unittest.TestCase):
|
||||||
# XXX: This doesn't work unless memoize is the last decorator -
|
# XXX: This doesn't work unless memoize is the last decorator -
|
||||||
# see the comment in countcalls.
|
# see the comment in countcalls.
|
||||||
counts = {}
|
counts = {}
|
||||||
@countcalls(counts) @memoize
|
@memoize
|
||||||
|
@countcalls(counts)
|
||||||
def double(x):
|
def double(x):
|
||||||
return x * 2
|
return x * 2
|
||||||
|
|
||||||
|
@ -186,12 +187,20 @@ class TestDecorators(unittest.TestCase):
|
||||||
self.assertEqual(C.foo.booh, 42)
|
self.assertEqual(C.foo.booh, 42)
|
||||||
|
|
||||||
def test_order(self):
|
def test_order(self):
|
||||||
class C(object):
|
# Test that decorators are conceptually applied right-recursively;
|
||||||
@funcattrs(abc=1) @staticmethod
|
# that means bottom-up
|
||||||
def foo(): return 42
|
def ordercheck(num):
|
||||||
# This wouldn't work if staticmethod was called first
|
def deco(func):
|
||||||
self.assertEqual(C.foo(), 42)
|
return lambda: num
|
||||||
self.assertEqual(C().foo(), 42)
|
return deco
|
||||||
|
|
||||||
|
# Should go ordercheck(1)(ordercheck(2)(blah)) which should lead to
|
||||||
|
# blah() == 1
|
||||||
|
@ordercheck(1)
|
||||||
|
@ordercheck(2)
|
||||||
|
def blah(): pass
|
||||||
|
self.assertEqual(blah(), 1, "decorators are meant to be applied "
|
||||||
|
"bottom-up")
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test_support.run_unittest(TestDecorators)
|
test_support.run_unittest(TestDecorators)
|
||||||
|
|
|
@ -12,6 +12,9 @@ What's New in Python 2.4 alpha 3?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Fix the order of application of decorators. The proper order is bottom-up;
|
||||||
|
the first decorator listed is the last one called.
|
||||||
|
|
||||||
- SF patch #1005778. Fix a seg fault if the list size changed while
|
- SF patch #1005778. Fix a seg fault if the list size changed while
|
||||||
calling list.index(). This could happen if a rich comparison function
|
calling list.index(). This could happen if a rich comparison function
|
||||||
modified the list.
|
modified the list.
|
||||||
|
|
|
@ -4132,7 +4132,10 @@ com_decorators(struct compiling *c, node *n)
|
||||||
REQ(CHILD(n, nch - 1), NEWLINE);
|
REQ(CHILD(n, nch - 1), NEWLINE);
|
||||||
|
|
||||||
ndecorators = 0;
|
ndecorators = 0;
|
||||||
for (i = NCH(n) - 1; i >= 0; --i) {
|
/* the application order for decorators is the reverse of how they are
|
||||||
|
listed; bottom-up */
|
||||||
|
nch -= 1;
|
||||||
|
for (i = 0; i < nch; i+=1) {
|
||||||
node *ch = CHILD(n, i);
|
node *ch = CHILD(n, i);
|
||||||
if (TYPE(ch) != NEWLINE) {
|
if (TYPE(ch) != NEWLINE) {
|
||||||
com_decorator(c, ch);
|
com_decorator(c, ch);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue