1 import unittest 2 from test import test_support 3 import sys 4 new = test_support.import_module('new', deprecated=True) 5 6 class NewTest(unittest.TestCase): 7 def test_spam(self): 8 class Eggs: 9 def get_yolks(self): 10 return self.yolks 11 12 m = new.module('Spam') 13 m.Eggs = Eggs 14 sys.modules['Spam'] = m 15 import Spam 16 17 def get_more_yolks(self): 18 return self.yolks + 3 19 20 # new.classobj() 21 C = new.classobj('Spam', (Spam.Eggs,), {'get_more_yolks': get_more_yolks}) 22 23 # new.instance() 24 c = new.instance(C, {'yolks': 3}) 25 26 o = new.instance(C) 27 self.assertEqual(o.__dict__, {}, "new __dict__ should be empty") 28 del o 29 o = new.instance(C, None) 30 self.assertEqual(o.__dict__, {}, "new __dict__ should be empty") 31 del o 32 33 def break_yolks(self): 34 self.yolks = self.yolks - 2 35 36 # new.instancemethod() 37 im = new.instancemethod(break_yolks, c, C) 38 39 self.assertEqual(c.get_yolks(), 3, 40 'Broken call of hand-crafted class instance') 41 self.assertEqual(c.get_more_yolks(), 6, 42 'Broken call of hand-crafted class instance') 43 44 im() 45 self.assertEqual(c.get_yolks(), 1, 46 'Broken call of hand-crafted instance method') 47 self.assertEqual(c.get_more_yolks(), 4, 48 'Broken call of hand-crafted instance method') 49 50 im = new.instancemethod(break_yolks, c) 51 im() 52 self.assertEqual(c.get_yolks(), -1) 53 54 # Verify that dangerous instance method creation is forbidden 55 self.assertRaises(TypeError, new.instancemethod, break_yolks, None) 56 57 # Verify that instancemethod() doesn't allow keyword args 58 self.assertRaises(TypeError, new.instancemethod, break_yolks, c, kw=1) 59 60 def test_scope(self): 61 # It's unclear what the semantics should be for a code object compiled 62 # at module scope, but bound and run in a function. In CPython, `c' is 63 # global (by accident?) while in Jython, `c' is local. The intent of 64 # the test clearly is to make `c' global, so let's be explicit about it. 65 codestr = ''' 66 global c 67 a = 1 68 b = 2 69 c = a + b 70 ''' 71 72 codestr = "\n".join(l.strip() for l in codestr.splitlines()) 73 74 ccode = compile(codestr, '<string>', 'exec') 75 # Jython doesn't have a __builtins__, so use a portable alternative 76 import __builtin__ 77 g = {'c': 0, '__builtins__': __builtin__} 78 79 # this test could be more robust 80 func = new.function(ccode, g) 81 func() 82 self.assertEqual(g['c'], 3, 'Could not create a proper function object') 83 84 def test_function(self): 85 # test the various extended flavors of function.new 86 def f(x): 87 def g(y): 88 return x + y 89 return g 90 g = f(4) 91 new.function(f.func_code, {}, "blah") 92 g2 = new.function(g.func_code, {}, "blah", (2,), g.func_closure) 93 self.assertEqual(g2(), 6) 94 g3 = new.function(g.func_code, {}, "blah", None, g.func_closure) 95 self.assertEqual(g3(5), 9) 96 def test_closure(func, closure, exc): 97 self.assertRaises(exc, new.function, func.func_code, {}, "", None, closure) 98 99 test_closure(g, None, TypeError) # invalid closure 100 test_closure(g, (1,), TypeError) # non-cell in closure 101 test_closure(g, (1, 1), ValueError) # closure is wrong size 102 test_closure(f, g.func_closure, ValueError) # no closure needed 103 104 # Note: Jython will never have new.code() 105 if hasattr(new, 'code'): 106 def test_code(self): 107 # bogus test of new.code() 108 def f(a): pass 109 110 c = f.func_code 111 argcount = c.co_argcount 112 nlocals = c.co_nlocals 113 stacksize = c.co_stacksize 114 flags = c.co_flags 115 codestring = c.co_code 116 constants = c.co_consts 117 names = c.co_names 118 varnames = c.co_varnames 119 filename = c.co_filename 120 name = c.co_name 121 firstlineno = c.co_firstlineno 122 lnotab = c.co_lnotab 123 freevars = c.co_freevars 124 cellvars = c.co_cellvars 125 126 d = new.code(argcount, nlocals, stacksize, flags, codestring, 127 constants, names, varnames, filename, name, 128 firstlineno, lnotab, freevars, cellvars) 129 130 # test backwards-compatibility version with no freevars or cellvars 131 d = new.code(argcount, nlocals, stacksize, flags, codestring, 132 constants, names, varnames, filename, name, 133 firstlineno, lnotab) 134 135 # negative co_argcount used to trigger a SystemError 136 self.assertRaises(ValueError, new.code, 137 -argcount, nlocals, stacksize, flags, codestring, 138 constants, names, varnames, filename, name, firstlineno, lnotab) 139 140 # negative co_nlocals used to trigger a SystemError 141 self.assertRaises(ValueError, new.code, 142 argcount, -nlocals, stacksize, flags, codestring, 143 constants, names, varnames, filename, name, firstlineno, lnotab) 144 145 # non-string co_name used to trigger a Py_FatalError 146 self.assertRaises(TypeError, new.code, 147 argcount, nlocals, stacksize, flags, codestring, 148 constants, (5,), varnames, filename, name, firstlineno, lnotab) 149 150 # new.code used to be a way to mutate a tuple... 151 class S(str): 152 pass 153 t = (S("ab"),) 154 d = new.code(argcount, nlocals, stacksize, flags, codestring, 155 constants, t, varnames, filename, name, 156 firstlineno, lnotab) 157 self.assertTrue(type(t[0]) is S, "eek, tuple changed under us!") 158 159 def test_main(): 160 test_support.run_unittest(NewTest) 161 162 if __name__ == "__main__": 163 test_main() 164