blob: 797a8c349f3181577913de04de0f11b27fe42851 [file] [log] [blame]
Thomas Woutersb2137042007-02-01 18:02:27 +00001import unittest
2from test import test_support
3import sys, new
Barry Warsaw924e5d51996-12-10 16:28:53 +00004
Thomas Woutersb2137042007-02-01 18:02:27 +00005class NewTest(unittest.TestCase):
6 def test_spam(self):
7 class Eggs:
8 def get_yolks(self):
9 return self.yolks
Barry Warsaw924e5d51996-12-10 16:28:53 +000010
Thomas Woutersb2137042007-02-01 18:02:27 +000011 m = new.module('Spam')
12 m.Eggs = Eggs
13 sys.modules['Spam'] = m
14 import Spam
Barry Warsaw924e5d51996-12-10 16:28:53 +000015
Thomas Woutersb2137042007-02-01 18:02:27 +000016 def get_more_yolks(self):
17 return self.yolks + 3
Barry Warsaw924e5d51996-12-10 16:28:53 +000018
Thomas Woutersb2137042007-02-01 18:02:27 +000019 # new.classobj()
20 C = new.classobj('Spam', (Spam.Eggs,), {'get_more_yolks': get_more_yolks})
Barry Warsaw924e5d51996-12-10 16:28:53 +000021
Thomas Woutersb2137042007-02-01 18:02:27 +000022 def break_yolks(self):
23 self.yolks = self.yolks - 2
Barry Warsaw924e5d51996-12-10 16:28:53 +000024
Thomas Woutersb2137042007-02-01 18:02:27 +000025 # new.instancemethod()
26 c = C()
27 c.yolks = 3
28 im = new.instancemethod(break_yolks, c, C)
Barry Warsaw924e5d51996-12-10 16:28:53 +000029
Thomas Woutersb2137042007-02-01 18:02:27 +000030 self.assertEqual(c.get_yolks(), 3,
31 'Broken call of hand-crafted class instance')
32 self.assertEqual(c.get_more_yolks(), 6,
33 'Broken call of hand-crafted class instance')
Michael W. Hudsone2749cb2005-03-30 16:32:10 +000034
Thomas Woutersb2137042007-02-01 18:02:27 +000035 im()
36 self.assertEqual(c.get_yolks(), 1,
37 'Broken call of hand-crafted instance method')
38 self.assertEqual(c.get_more_yolks(), 4,
39 'Broken call of hand-crafted instance method')
Thomas Wouters89f507f2006-12-13 04:49:30 +000040
Thomas Woutersb2137042007-02-01 18:02:27 +000041 im = new.instancemethod(break_yolks, c)
42 im()
43 self.assertEqual(c.get_yolks(), -1)
Barry Warsaw924e5d51996-12-10 16:28:53 +000044
Thomas Woutersb2137042007-02-01 18:02:27 +000045 # Verify that dangerous instance method creation is forbidden
46 self.assertRaises(TypeError, new.instancemethod, break_yolks, None)
Barry Warsaw924e5d51996-12-10 16:28:53 +000047
Thomas Woutersb2137042007-02-01 18:02:27 +000048 # Verify that instancemethod() doesn't allow keyword args
49 self.assertRaises(TypeError, new.instancemethod, break_yolks, c, kw=1)
Jeremy Hyltondf3f7932002-07-11 18:30:27 +000050
Thomas Woutersb2137042007-02-01 18:02:27 +000051 def test_scope(self):
52 # It's unclear what the semantics should be for a code object compiled
53 # at module scope, but bound and run in a function. In CPython, `c' is
54 # global (by accident?) while in Jython, `c' is local. The intent of
55 # the test clearly is to make `c' global, so let's be explicit about it.
56 codestr = '''
57 global c
58 a = 1
59 b = 2
60 c = a + b
61 '''
Jeremy Hyltondf3f7932002-07-11 18:30:27 +000062
Thomas Woutersb2137042007-02-01 18:02:27 +000063 codestr = "\n".join(l.strip() for l in codestr.splitlines())
Tim Petersbf9ac4b2004-08-13 03:57:22 +000064
Thomas Woutersb2137042007-02-01 18:02:27 +000065 ccode = compile(codestr, '<string>', 'exec')
66 # Jython doesn't have a __builtins__, so use a portable alternative
67 import __builtin__
68 g = {'c': 0, '__builtins__': __builtin__}
Tim Petersbf9ac4b2004-08-13 03:57:22 +000069
Thomas Woutersb2137042007-02-01 18:02:27 +000070 # this test could be more robust
71 func = new.function(ccode, g)
72 func()
73 self.assertEqual(g['c'], 3, 'Could not create a proper function object')
Tim Petersbf9ac4b2004-08-13 03:57:22 +000074
Thomas Woutersb2137042007-02-01 18:02:27 +000075 def test_function(self):
76 # test the various extended flavors of function.new
77 def f(x):
78 def g(y):
79 return x + y
80 return g
81 g = f(4)
Neal Norwitz221085d2007-02-25 20:55:47 +000082 new.function(f.__code__, {}, "blah")
83 g2 = new.function(g.__code__, {}, "blah", (2,), g.__closure__)
Thomas Woutersb2137042007-02-01 18:02:27 +000084 self.assertEqual(g2(), 6)
Neal Norwitz221085d2007-02-25 20:55:47 +000085 g3 = new.function(g.__code__, {}, "blah", None, g.__closure__)
Thomas Woutersb2137042007-02-01 18:02:27 +000086 self.assertEqual(g3(5), 9)
87 def test_closure(func, closure, exc):
Neal Norwitz221085d2007-02-25 20:55:47 +000088 self.assertRaises(exc, new.function, func.__code__, {}, "", None, closure)
Tim Petersbf9ac4b2004-08-13 03:57:22 +000089
Thomas Woutersb2137042007-02-01 18:02:27 +000090 test_closure(g, None, TypeError) # invalid closure
91 test_closure(g, (1,), TypeError) # non-cell in closure
92 test_closure(g, (1, 1), ValueError) # closure is wrong size
Neal Norwitz221085d2007-02-25 20:55:47 +000093 test_closure(f, g.__closure__, ValueError) # no closure needed
Michael W. Hudson60934622004-08-12 17:56:29 +000094
Thomas Woutersb2137042007-02-01 18:02:27 +000095 # Note: Jython will never have new.code()
96 if hasattr(new, 'code'):
97 def test_code(self):
98 # bogus test of new.code()
99 def f(a): pass
Tim Petersbf9ac4b2004-08-13 03:57:22 +0000100
Neal Norwitz221085d2007-02-25 20:55:47 +0000101 c = f.__code__
Thomas Woutersb2137042007-02-01 18:02:27 +0000102 argcount = c.co_argcount
103 kwonlyargcount = c.co_kwonlyargcount
104 nlocals = c.co_nlocals
105 stacksize = c.co_stacksize
106 flags = c.co_flags
107 codestring = c.co_code
108 constants = c.co_consts
109 names = c.co_names
110 varnames = c.co_varnames
111 filename = c.co_filename
112 name = c.co_name
113 firstlineno = c.co_firstlineno
114 lnotab = c.co_lnotab
115 freevars = c.co_freevars
116 cellvars = c.co_cellvars
Michael W. Hudson60934622004-08-12 17:56:29 +0000117
Thomas Woutersb2137042007-02-01 18:02:27 +0000118 d = new.code(argcount, kwonlyargcount, nlocals, stacksize, flags,
119 codestring, constants, names, varnames, filename,
120 name, firstlineno, lnotab, freevars, cellvars)
Michael W. Hudson60934622004-08-12 17:56:29 +0000121
Thomas Woutersb2137042007-02-01 18:02:27 +0000122 # test backwards-compatibility version with no freevars or cellvars
123 d = new.code(argcount, kwonlyargcount, nlocals, stacksize,
124 flags, codestring, constants, names, varnames,
125 filename, name, firstlineno, lnotab)
126
127 # negative co_argcount used to trigger a SystemError
128 self.assertRaises(ValueError, new.code,
129 -argcount, kwonlyargcount, nlocals, stacksize, flags,
130 codestring, constants, names, varnames, filename, name,
131 firstlineno, lnotab)
132
133 # negative co_nlocals used to trigger a SystemError
134 self.assertRaises(ValueError, new.code,
135 argcount, kwonlyargcount, -nlocals, stacksize, flags,
136 codestring, constants, names, varnames, filename, name,
137 firstlineno, lnotab)
138
139 # non-string co_name used to trigger a Py_FatalError
140 self.assertRaises(TypeError, new.code,
141 argcount, kwonlyargcount, nlocals, stacksize, flags,
142 codestring, constants, (5,), varnames, filename, name,
143 firstlineno, lnotab)
144
145 # new.code used to be a way to mutate a tuple...
Martin v. Löwis5b222132007-06-10 09:51:05 +0000146 class S(str):
Thomas Woutersb2137042007-02-01 18:02:27 +0000147 pass
148 t = (S("ab"),)
149 d = new.code(argcount, kwonlyargcount, nlocals, stacksize,
150 flags, codestring, constants, t, varnames,
151 filename, name, firstlineno, lnotab)
152 self.assert_(type(t[0]) is S, "eek, tuple changed under us!")
153
154def test_main():
155 test_support.run_unittest(NewTest)
156
157if __name__ == "__main__":
158 test_main()