Back to index

python3.2  3.2.2
Public Member Functions | Public Attributes
test.test_decorators.TestDecorators Class Reference

List of all members.

Public Member Functions

def test_single
def test_staticmethod_function
def test_dotted
def test_argforms
def test_dbcheck
def test_memoize
def test_errors
def test_double
def test_order
def test_eval_order

Public Attributes

 index

Detailed Description

Definition at line 71 of file test_decorators.py.


Member Function Documentation

Definition at line 93 of file test_decorators.py.

00093 
00094     def test_argforms(self):
00095         # A few tests of argument passing, as we use restricted form
00096         # of expressions for decorators.
00097 
00098         def noteargs(*args, **kwds):
00099             def decorate(func):
00100                 setattr(func, 'dbval', (args, kwds))
00101                 return func
00102             return decorate
00103 
00104         args = ( 'Now', 'is', 'the', 'time' )
00105         kwds = dict(one=1, two=2)
00106         @noteargs(*args, **kwds)
00107         def f1(): return 42
00108         self.assertEqual(f1(), 42)
00109         self.assertEqual(f1.dbval, (args, kwds))
00110 
00111         @noteargs('terry', 'gilliam', eric='idle', john='cleese')
00112         def f2(): return 84
00113         self.assertEqual(f2(), 84)
00114         self.assertEqual(f2.dbval, (('terry', 'gilliam'),
00115                                      dict(eric='idle', john='cleese')))
00116 
00117         @noteargs(1, 2,)
00118         def f3(): pass
00119         self.assertEqual(f3.dbval, ((1, 2), {}))

Here is the call graph for this function:

Definition at line 120 of file test_decorators.py.

00120 
00121     def test_dbcheck(self):
00122         @dbcheck('args[1] is not None')
00123         def f(a, b):
00124             return a + b
00125         self.assertEqual(f(1, 2), 3)
00126         self.assertRaises(DbcheckError, f, 1, None)

Here is the call graph for this function:

Definition at line 86 of file test_decorators.py.

00086 
00087     def test_dotted(self):
00088         decorators = MiscDecorators()
00089         @decorators.author('Cleese')
00090         def foo(): return 42
00091         self.assertEqual(foo(), 42)
00092         self.assertEqual(foo.author, 'Cleese')

Here is the call graph for this function:

Definition at line 183 of file test_decorators.py.

00183 
00184     def test_double(self):
00185         class C(object):
00186             @funcattrs(abc=1, xyz="haha")
00187             @funcattrs(booh=42)
00188             def foo(self): return 42
00189         self.assertEqual(C().foo(), 42)
00190         self.assertEqual(C.foo.abc, 1)
00191         self.assertEqual(C.foo.xyz, "haha")
00192         self.assertEqual(C.foo.booh, 42)

Here is the call graph for this function:

Definition at line 154 of file test_decorators.py.

00154 
00155     def test_errors(self):
00156         # Test syntax restrictions - these are all compile-time errors:
00157         #
00158         for expr in [ "1+2", "x[3]", "(1, 2)" ]:
00159             # Sanity check: is expr is a valid expression by itself?
00160             compile(expr, "testexpr", "exec")
00161 
00162             codestr = "@%s\ndef f(): pass" % expr
00163             self.assertRaises(SyntaxError, compile, codestr, "test", "exec")
00164 
00165         # You can't put multiple decorators on a single line:
00166         #
00167         self.assertRaises(SyntaxError, compile,
00168                           "@f1 @f2\ndef f(): pass", "test", "exec")
00169 
00170         # Test runtime errors
00171 
00172         def unimp(func):
00173             raise NotImplementedError
00174         context = dict(nullval=None, unimp=unimp)
00175 
00176         for expr, exc in [ ("undef", NameError),
00177                            ("nullval", TypeError),
00178                            ("nullval.attr", AttributeError),
00179                            ("unimp", NotImplementedError)]:
00180             codestr = "@%s\ndef f(): pass\nassert f() is None" % expr
00181             code = compile(codestr, "test", "exec")
00182             self.assertRaises(exc, eval, code, context)

Here is the call graph for this function:

Definition at line 208 of file test_decorators.py.

00208 
00209     def test_eval_order(self):
00210         # Evaluating a decorated function involves four steps for each
00211         # decorator-maker (the function that returns a decorator):
00212         #
00213         #    1: Evaluate the decorator-maker name
00214         #    2: Evaluate the decorator-maker arguments (if any)
00215         #    3: Call the decorator-maker to make a decorator
00216         #    4: Call the decorator
00217         #
00218         # When there are multiple decorators, these steps should be
00219         # performed in the above order for each decorator, but we should
00220         # iterate through the decorators in the reverse of the order they
00221         # appear in the source.
00222 
00223         actions = []
00224 
00225         def make_decorator(tag):
00226             actions.append('makedec' + tag)
00227             def decorate(func):
00228                 actions.append('calldec' + tag)
00229                 return func
00230             return decorate
00231 
00232         class NameLookupTracer (object):
00233             def __init__(self, index):
00234                 self.index = index
00235 
00236             def __getattr__(self, fname):
00237                 if fname == 'make_decorator':
00238                     opname, res = ('evalname', make_decorator)
00239                 elif fname == 'arg':
00240                     opname, res = ('evalargs', str(self.index))
00241                 else:
00242                     assert False, "Unknown attrname %s" % fname
00243                 actions.append('%s%d' % (opname, self.index))
00244                 return res
00245 
00246         c1, c2, c3 = map(NameLookupTracer, [ 1, 2, 3 ])
00247 
00248         expected_actions = [ 'evalname1', 'evalargs1', 'makedec1',
00249                              'evalname2', 'evalargs2', 'makedec2',
00250                              'evalname3', 'evalargs3', 'makedec3',
00251                              'calldec3', 'calldec2', 'calldec1' ]
00252 
00253         actions = []
00254         @c1.make_decorator(c1.arg)
00255         @c2.make_decorator(c2.arg)
00256         @c3.make_decorator(c3.arg)
00257         def foo(): return 42
00258         self.assertEqual(foo(), 42)
00259 
00260         self.assertEqual(actions, expected_actions)
00261 
00262         # Test the equivalence claim in chapter 7 of the reference manual.
00263         #
00264         actions = []
00265         def bar(): return 42
00266         bar = c1.make_decorator(c1.arg)(c2.make_decorator(c2.arg)(c3.make_decorator(c3.arg)(bar)))
00267         self.assertEqual(bar(), 42)
00268         self.assertEqual(actions, expected_actions)

Here is the call graph for this function:

Definition at line 127 of file test_decorators.py.

00127 
00128     def test_memoize(self):
00129         counts = {}
00130 
00131         @memoize
00132         @countcalls(counts)
00133         def double(x):
00134             return x * 2
00135         self.assertEqual(double.__name__, 'double')
00136 
00137         self.assertEqual(counts, dict(double=0))
00138 
00139         # Only the first call with a given argument bumps the call count:
00140         #
00141         self.assertEqual(double(2), 4)
00142         self.assertEqual(counts['double'], 1)
00143         self.assertEqual(double(2), 4)
00144         self.assertEqual(counts['double'], 1)
00145         self.assertEqual(double(3), 6)
00146         self.assertEqual(counts['double'], 2)
00147 
00148         # Unhashable arguments do not get memoized:
00149         #
00150         self.assertEqual(double([10]), [10, 10])
00151         self.assertEqual(counts['double'], 3)
00152         self.assertEqual(double([10]), [10, 10])
00153         self.assertEqual(counts['double'], 4)

Here is the call graph for this function:

Definition at line 193 of file test_decorators.py.

00193 
00194     def test_order(self):
00195         # Test that decorators are applied in the proper order to the function
00196         # they are decorating.
00197         def callnum(num):
00198             """Decorator factory that returns a decorator that replaces the
00199             passed-in function with one that returns the value of 'num'"""
00200             def deco(func):
00201                 return lambda: num
00202             return deco
00203         @callnum(2)
00204         @callnum(1)
00205         def foo(): return 42
00206         self.assertEqual(foo(), 2,
00207                             "Application order of decorators is incorrect")

Here is the call graph for this function:

Definition at line 73 of file test_decorators.py.

00073 
00074     def test_single(self):
00075         class C(object):
00076             @staticmethod
00077             def foo(): return 42
00078         self.assertEqual(C.foo(), 42)
00079         self.assertEqual(C().foo(), 42)

Here is the call graph for this function:

Definition at line 80 of file test_decorators.py.

00080 
00081     def test_staticmethod_function(self):
00082         @staticmethod
00083         def notamethod(x):
00084             return x
00085         self.assertRaises(TypeError, notamethod, 1)

Here is the call graph for this function:


Member Data Documentation

Definition at line 233 of file test_decorators.py.


The documentation for this class was generated from the following file: