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