blob: c243b59e91bc93637759c32701cfa976184c22f5 [file] [log] [blame]
Walter Dörwald71cd5512007-01-20 23:07:28 +00001import unittest
2from test import test_support
3import sys, new
Barry Warsaw924e5d51996-12-10 16:28:53 +00004
Walter Dörwald71cd5512007-01-20 23:07:28 +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
Walter Dörwald71cd5512007-01-20 23:07:28 +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
Walter Dörwald71cd5512007-01-20 23:07:28 +000016 def get_more_yolks(self):
17 return self.yolks + 3
Barry Warsaw924e5d51996-12-10 16:28:53 +000018
Walter Dörwald71cd5512007-01-20 23:07:28 +000019 # new.classobj()
20 C = new.classobj('Spam', (Spam.Eggs,), {'get_more_yolks': get_more_yolks})
Barry Warsaw924e5d51996-12-10 16:28:53 +000021
Walter Dörwald71cd5512007-01-20 23:07:28 +000022 # new.instance()
23 c = new.instance(C, {'yolks': 3})
Barry Warsaw924e5d51996-12-10 16:28:53 +000024
Walter Dörwald71cd5512007-01-20 23:07:28 +000025 o = new.instance(C)
26 self.assertEqual(o.__dict__, {}, "new __dict__ should be empty")
27 del o
28 o = new.instance(C, None)
29 self.assertEqual(o.__dict__, {}, "new __dict__ should be empty")
30 del o
Barry Warsaw924e5d51996-12-10 16:28:53 +000031
Walter Dörwald71cd5512007-01-20 23:07:28 +000032 def break_yolks(self):
33 self.yolks = self.yolks - 2
Michael W. Hudsone2749cb2005-03-30 16:32:10 +000034
Walter Dörwald71cd5512007-01-20 23:07:28 +000035 # new.instancemethod()
36 im = new.instancemethod(break_yolks, c, C)
Georg Brandl5d59c092006-09-30 08:43:30 +000037
Walter Dörwald71cd5512007-01-20 23:07:28 +000038 self.assertEqual(c.get_yolks(), 3,
39 'Broken call of hand-crafted class instance')
40 self.assertEqual(c.get_more_yolks(), 6,
41 'Broken call of hand-crafted class instance')
Barry Warsaw924e5d51996-12-10 16:28:53 +000042
Walter Dörwald71cd5512007-01-20 23:07:28 +000043 im()
44 self.assertEqual(c.get_yolks(), 1,
45 'Broken call of hand-crafted instance method')
46 self.assertEqual(c.get_more_yolks(), 4,
47 'Broken call of hand-crafted instance method')
Barry Warsaw924e5d51996-12-10 16:28:53 +000048
Walter Dörwald71cd5512007-01-20 23:07:28 +000049 im = new.instancemethod(break_yolks, c)
50 im()
51 self.assertEqual(c.get_yolks(), -1)
Jeremy Hyltondf3f7932002-07-11 18:30:27 +000052
Walter Dörwald71cd5512007-01-20 23:07:28 +000053 # Verify that dangerous instance method creation is forbidden
54 self.assertRaises(TypeError, new.instancemethod, break_yolks, None)
Jeremy Hyltondf3f7932002-07-11 18:30:27 +000055
Walter Dörwald71cd5512007-01-20 23:07:28 +000056 # Verify that instancemethod() doesn't allow keyword args
57 self.assertRaises(TypeError, new.instancemethod, break_yolks, c, kw=1)
Tim Petersbf9ac4b2004-08-13 03:57:22 +000058
Walter Dörwald71cd5512007-01-20 23:07:28 +000059 def test_scope(self):
60 # It's unclear what the semantics should be for a code object compiled
61 # at module scope, but bound and run in a function. In CPython, `c' is
62 # global (by accident?) while in Jython, `c' is local. The intent of
63 # the test clearly is to make `c' global, so let's be explicit about it.
64 codestr = '''
65 global c
66 a = 1
67 b = 2
68 c = a + b
69 '''
Tim Petersbf9ac4b2004-08-13 03:57:22 +000070
Walter Dörwald71cd5512007-01-20 23:07:28 +000071 codestr = "\n".join(l.strip() for l in codestr.splitlines())
Tim Petersbf9ac4b2004-08-13 03:57:22 +000072
Walter Dörwald71cd5512007-01-20 23:07:28 +000073 ccode = compile(codestr, '<string>', 'exec')
74 # Jython doesn't have a __builtins__, so use a portable alternative
75 import __builtin__
76 g = {'c': 0, '__builtins__': __builtin__}
Tim Petersbf9ac4b2004-08-13 03:57:22 +000077
Walter Dörwald71cd5512007-01-20 23:07:28 +000078 # this test could be more robust
79 func = new.function(ccode, g)
80 func()
81 self.assertEqual(g['c'], 3, 'Could not create a proper function object')
Michael W. Hudson60934622004-08-12 17:56:29 +000082
Walter Dörwald71cd5512007-01-20 23:07:28 +000083 def test_function(self):
84 # test the various extended flavors of function.new
85 def f(x):
86 def g(y):
87 return x + y
88 return g
89 g = f(4)
90 new.function(f.func_code, {}, "blah")
91 g2 = new.function(g.func_code, {}, "blah", (2,), g.func_closure)
92 self.assertEqual(g2(), 6)
93 g3 = new.function(g.func_code, {}, "blah", None, g.func_closure)
94 self.assertEqual(g3(5), 9)
95 def test_closure(func, closure, exc):
96 self.assertRaises(exc, new.function, func.func_code, {}, "", None, closure)
Tim Petersbf9ac4b2004-08-13 03:57:22 +000097
Walter Dörwald71cd5512007-01-20 23:07:28 +000098 test_closure(g, None, TypeError) # invalid closure
99 test_closure(g, (1,), TypeError) # non-cell in closure
100 test_closure(g, (1, 1), ValueError) # closure is wrong size
101 test_closure(f, g.func_closure, ValueError) # no closure needed
Michael W. Hudson60934622004-08-12 17:56:29 +0000102
Walter Dörwald71cd5512007-01-20 23:07:28 +0000103 # Note: Jython will never have new.code()
104 if hasattr(new, 'code'):
105 def test_code(self):
106 # bogus test of new.code()
107 def f(a): pass
Michael W. Hudson60934622004-08-12 17:56:29 +0000108
Walter Dörwald71cd5512007-01-20 23:07:28 +0000109 c = f.func_code
110 argcount = c.co_argcount
111 nlocals = c.co_nlocals
112 stacksize = c.co_stacksize
113 flags = c.co_flags
114 codestring = c.co_code
115 constants = c.co_consts
116 names = c.co_names
117 varnames = c.co_varnames
118 filename = c.co_filename
119 name = c.co_name
120 firstlineno = c.co_firstlineno
121 lnotab = c.co_lnotab
122 freevars = c.co_freevars
123 cellvars = c.co_cellvars
124
125 d = new.code(argcount, nlocals, stacksize, flags, codestring,
126 constants, names, varnames, filename, name,
127 firstlineno, lnotab, freevars, cellvars)
128
129 # test backwards-compatibility version with no freevars or cellvars
130 d = new.code(argcount, nlocals, stacksize, flags, codestring,
131 constants, names, varnames, filename, name,
132 firstlineno, lnotab)
133
134 # negative co_argcount used to trigger a SystemError
135 self.assertRaises(ValueError, new.code,
136 -argcount, nlocals, stacksize, flags, codestring,
137 constants, names, varnames, filename, name, firstlineno, lnotab)
138
139 # negative co_nlocals used to trigger a SystemError
140 self.assertRaises(ValueError, new.code,
141 argcount, -nlocals, stacksize, flags, codestring,
142 constants, names, varnames, filename, name, firstlineno, lnotab)
143
144 # non-string co_name used to trigger a Py_FatalError
145 self.assertRaises(TypeError, new.code,
146 argcount, nlocals, stacksize, flags, codestring,
147 constants, (5,), varnames, filename, name, firstlineno, lnotab)
148
149 # new.code used to be a way to mutate a tuple...
150 class S(str):
151 pass
152 t = (S("ab"),)
153 d = new.code(argcount, nlocals, stacksize, flags, codestring,
154 constants, t, varnames, filename, name,
155 firstlineno, lnotab)
156 self.assert_(type(t[0]) is S, "eek, tuple changed under us!")
157
158def test_main():
159 test_support.run_unittest(NewTest)
160
161if __name__ == "__main__":
162 test_main()