1 import test
.test_support
2 compiler
= test
.test_support
.import_module('compiler', deprecated
=True)
3 from compiler
.ast
import flatten
4 import os
, sys
, time
, unittest
5 from random
import random
6 from StringIO
import StringIO
8 # How much time in seconds can pass before we print a 'Still working' message.
9 _PRINT_WORKING_MSG_INTERVAL
= 5 * 60
11 class TrivialContext(object):
14 def __exit__(self
, *exc_info
):
17 class CompilerTest(unittest
.TestCase
):
19 def testCompileLibrary(self
):
20 # A simple but large test. Compile all the code in the
21 # standard library and its test suite. This doesn't verify
22 # that any of the code is correct, merely the compiler is able
23 # to generate some kind of code for it.
25 next_time
= time
.time() + _PRINT_WORKING_MSG_INTERVAL
26 # warning: if 'os' or 'test_support' are moved in some other dir,
27 # they should be changed here.
28 libdir
= os
.path
.dirname(os
.__file
__)
29 testdir
= os
.path
.dirname(test
.test_support
.__file
__)
31 for dir in [libdir
, testdir
]:
32 for basename
in os
.listdir(dir):
33 # Print still working message since this test can be really slow
34 if next_time
<= time
.time():
35 next_time
= time
.time() + _PRINT_WORKING_MSG_INTERVAL
36 print >>sys
.__stdout
__, \
37 ' testCompileLibrary still working, be patient...'
38 sys
.__stdout
__.flush()
40 if not basename
.endswith(".py"):
42 if not TEST_ALL
and random() < 0.98:
44 path
= os
.path
.join(dir, basename
)
45 if test
.test_support
.verbose
:
46 print "compiling", path
50 if "badsyntax" in basename
or "bad_coding" in basename
:
51 self
.assertRaises(SyntaxError, compiler
.compile,
52 buf
, basename
, "exec")
55 compiler
.compile(buf
, basename
, "exec")
58 args
.append("in file %s]" % basename
)
59 #args[0] += "[in file %s]" % basename
63 def testNewClassSyntax(self
):
64 compiler
.compile("class foo():pass\n\n","<string>","exec")
66 def testYieldExpr(self
):
67 compiler
.compile("def g(): yield\n\n", "<string>", "exec")
69 def testKeywordAfterStarargs(self
):
70 def f(*args
, **kwargs
):
71 self
.assertEqual((args
, kwargs
), ((2,3), {'x': 1, 'y': 4}))
72 c
= compiler
.compile('f(x=1, *(2, 3), y=4)', '<string>', 'exec')
75 self
.assertRaises(SyntaxError, compiler
.parse
, "foo(a=1, b)")
76 self
.assertRaises(SyntaxError, compiler
.parse
, "foo(1, *args, 3)")
78 def testTryExceptFinally(self
):
79 # Test that except and finally clauses in one try stmt are recognized
80 c
= compiler
.compile("try:\n 1//0\nexcept:\n e = 1\nfinally:\n f = 1",
84 self
.assertEqual(dct
.get('e'), 1)
85 self
.assertEqual(dct
.get('f'), 1)
87 def testDefaultArgs(self
):
88 self
.assertRaises(SyntaxError, compiler
.parse
, "def foo(a=1, b): pass")
90 def testDocstrings(self
):
91 c
= compiler
.compile('"doc"', '<string>', 'exec')
92 self
.assertIn('__doc__', c
.co_names
)
93 c
= compiler
.compile('def f():\n "doc"', '<string>', 'exec')
96 self
.assertEqual(g
['f'].__doc
__, "doc")
99 # Test that all nodes except Module have a correct lineno attribute.
101 if filename
.endswith((".pyc", ".pyo")):
102 filename
= filename
[:-1]
103 tree
= compiler
.parseFile(filename
)
104 self
.check_lineno(tree
)
106 def check_lineno(self
, node
):
108 self
._check
_lineno
(node
)
109 except AssertionError:
110 print node
.__class
__, node
.lineno
113 def _check_lineno(self
, node
):
114 if not node
.__class
__ in NOLINENO
:
115 self
.assertIsInstance(node
.lineno
, int,
116 "lineno=%s on %s" % (node
.lineno
, node
.__class
__))
117 self
.assertTrue(node
.lineno
> 0,
118 "lineno=%s on %s" % (node
.lineno
, node
.__class
__))
119 for child
in node
.getChildNodes():
120 self
.check_lineno(child
)
122 def testFlatten(self
):
123 self
.assertEqual(flatten([1, [2]]), [1, 2])
124 self
.assertEqual(flatten((1, (2,))), [1, 2])
126 def testNestedScope(self
):
127 c
= compiler
.compile('def g():\n'
129 ' def f(): return a + 2\n'
136 self
.assertEqual(dct
.get('result'), 3)
138 def testGenExp(self
):
139 c
= compiler
.compile('list((i,j) for i in range(3) if i < 3'
140 ' for j in range(4) if j > 2)',
143 self
.assertEqual(eval(c
), [(0, 3), (1, 3), (2, 3)])
145 def testSetLiteral(self
):
146 c
= compiler
.compile('{1, 2, 3}', '<string>', 'eval')
147 self
.assertEqual(eval(c
), {1,2,3})
148 c
= compiler
.compile('{1, 2, 3,}', '<string>', 'eval')
149 self
.assertEqual(eval(c
), {1,2,3})
151 def testDictLiteral(self
):
152 c
= compiler
.compile('{1:2, 2:3, 3:4}', '<string>', 'eval')
153 self
.assertEqual(eval(c
), {1:2, 2:3, 3:4})
154 c
= compiler
.compile('{1:2, 2:3, 3:4,}', '<string>', 'eval')
155 self
.assertEqual(eval(c
), {1:2, 2:3, 3:4})
157 def testSetComp(self
):
158 c
= compiler
.compile('{x for x in range(1, 4)}', '<string>', 'eval')
159 self
.assertEqual(eval(c
), {1, 2, 3})
160 c
= compiler
.compile('{x * y for x in range(3) if x != 0'
161 ' for y in range(4) if y != 0}',
164 self
.assertEqual(eval(c
), {1, 2, 3, 4, 6})
166 def testDictComp(self
):
167 c
= compiler
.compile('{x:x+1 for x in range(1, 4)}', '<string>', 'eval')
168 self
.assertEqual(eval(c
), {1:2, 2:3, 3:4})
169 c
= compiler
.compile('{(x, y) : y for x in range(2) if x != 0'
170 ' for y in range(3) if y != 0}',
173 self
.assertEqual(eval(c
), {(1, 2): 2, (1, 1): 1})
177 c
= compiler
.compile('from __future__ import with_statement\n'
179 ' with TrivialContext():\n'
184 dct
= {'TrivialContext': TrivialContext
}
186 self
.assertEqual(dct
.get('result'), 1)
188 def testWithAss(self
):
189 c
= compiler
.compile('from __future__ import with_statement\n'
191 ' with TrivialContext() as tc:\n'
196 dct
= {'TrivialContext': TrivialContext
}
198 self
.assertEqual(dct
.get('result'), 1)
200 def testWithMult(self
):
203 def __init__(self
, n
):
206 events
.append(self
.n
)
207 def __exit__(self
, *args
):
209 c
= compiler
.compile('from __future__ import with_statement\n'
211 ' with Ctx(1) as tc, Ctx(2) as tc2:\n'
218 self
.assertEqual(dct
.get('result'), 1)
219 self
.assertEqual(events
, [1, 2])
221 def testGlobal(self
):
222 code
= compiler
.compile('global x\nx=1', '<string>', 'exec')
223 d1
= {'__builtins__': {}}
226 # x should be in the globals dict
227 self
.assertEqual(d1
.get('x'), 1)
229 def testPrintFunction(self
):
230 c
= compiler
.compile('from __future__ import print_function\n'
231 'print("a", "b", sep="**", end="++", '
235 dct
= {'output': StringIO()}
237 self
.assertEqual(dct
['output'].getvalue(), 'a**b++')
239 def _testErrEnc(self
, src
, text
, offset
):
241 compile(src
, "", "exec")
242 except SyntaxError, e
:
243 self
.assertEqual(e
.offset
, offset
)
244 self
.assertEqual(e
.text
, text
)
246 def testSourceCodeEncodingsError(self
):
247 # Test SyntaxError with encoding definition
248 sjis
= "print '\x83\x70\x83\x43\x83\x5c\x83\x93', '\n"
249 ascii
= "print '12345678', '\n"
250 encdef
= "#! -*- coding: ShiftJIS -*-\n"
252 # ascii source without encdef
253 self
._testErrEnc
(ascii
, ascii
, 19)
255 # ascii source with encdef
256 self
._testErrEnc
(encdef
+ascii
, ascii
, 19)
258 # non-ascii source with encdef
259 self
._testErrEnc
(encdef
+sjis
, sjis
, 19)
261 # ShiftJIS source without encdef
262 self
._testErrEnc
(sjis
, sjis
, 19)
265 NOLINENO
= (compiler
.ast
.Module
, compiler
.ast
.Stmt
, compiler
.ast
.Discard
)
267 ###############################################################################
268 # code below is just used to trigger some possible errors, for the benefit of
270 ###############################################################################
278 l
= [(x
, y
) for x
, y
in zip(range(5), range(5,10))]
283 d
= {x
: y
for x
, y
in zip(range(5), range(5,10))}
284 s
= {x
for x
in range(10)}
309 ###############################################################################
313 TEST_ALL
= test
.test_support
.is_resource_enabled("cpu")
314 test
.test_support
.run_unittest(CompilerTest
)
316 if __name__
== "__main__":