diff options
author | Brett Cannon <bcannon@gmail.com> | 2004-08-15 07:21:25 (GMT) |
---|---|---|
committer | Brett Cannon <bcannon@gmail.com> | 2004-08-15 07:21:25 (GMT) |
commit | add33601c2826a151718da295b15fbb8cf656e53 (patch) | |
tree | 5b06b8571dd84cba7d1d0da67143fd2f5a98b38b | |
parent | 31f8350f439c3219c3975d127f8c5037d2362427 (diff) | |
download | cpython-add33601c2826a151718da295b15fbb8cf656e53.zip cpython-add33601c2826a151718da295b15fbb8cf656e53.tar.gz cpython-add33601c2826a151718da295b15fbb8cf656e53.tar.bz2 |
Correct the order of application for decorators. Meant to be bottom-up and not
top-down. Now matches the PEP.
-rw-r--r-- | Lib/test/test_decorators.py | 23 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Python/compile.c | 5 |
3 files changed, 23 insertions, 8 deletions
diff --git a/Lib/test/test_decorators.py b/Lib/test/test_decorators.py index dbe45cf..8010ea3 100644 --- a/Lib/test/test_decorators.py +++ b/Lib/test/test_decorators.py @@ -129,7 +129,8 @@ class TestDecorators(unittest.TestCase): # XXX: This doesn't work unless memoize is the last decorator - # see the comment in countcalls. counts = {} - @countcalls(counts) @memoize + @memoize + @countcalls(counts) def double(x): return x * 2 @@ -186,12 +187,20 @@ class TestDecorators(unittest.TestCase): self.assertEqual(C.foo.booh, 42) def test_order(self): - class C(object): - @funcattrs(abc=1) @staticmethod - def foo(): return 42 - # This wouldn't work if staticmethod was called first - self.assertEqual(C.foo(), 42) - self.assertEqual(C().foo(), 42) + # Test that decorators are conceptually applied right-recursively; + # that means bottom-up + def ordercheck(num): + def deco(func): + return lambda: num + 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(): test_support.run_unittest(TestDecorators) @@ -12,6 +12,9 @@ What's New in Python 2.4 alpha 3? 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 calling list.index(). This could happen if a rich comparison function modified the list. diff --git a/Python/compile.c b/Python/compile.c index de29536..79620c2 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4132,7 +4132,10 @@ com_decorators(struct compiling *c, node *n) REQ(CHILD(n, nch - 1), NEWLINE); 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); if (TYPE(ch) != NEWLINE) { com_decorator(c, ch); |