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