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 libdir
= os
.path
.dirname(unittest
.__file
__)
27 testdir
= os
.path
.dirname(test
.test_support
.__file
__)
29 for dir in [libdir
, testdir
]:
30 for basename
in os
.listdir(dir):
31 # Print still working message since this test can be really slow
32 if next_time
<= time
.time():
33 next_time
= time
.time() + _PRINT_WORKING_MSG_INTERVAL
34 print >>sys
.__stdout
__, \
35 ' testCompileLibrary still working, be patient...'
36 sys
.__stdout
__.flush()
38 if not basename
.endswith(".py"):
40 if not TEST_ALL
and random() < 0.98:
42 path
= os
.path
.join(dir, basename
)
43 if test
.test_support
.verbose
:
44 print "compiling", path
48 if "badsyntax" in basename
or "bad_coding" in basename
:
49 self
.assertRaises(SyntaxError, compiler
.compile,
50 buf
, basename
, "exec")
53 compiler
.compile(buf
, basename
, "exec")
56 args
.append("in file %s]" % basename
)
57 #args[0] += "[in file %s]" % basename
61 def testNewClassSyntax(self
):
62 compiler
.compile("class foo():pass\n\n","<string>","exec")
64 def testYieldExpr(self
):
65 compiler
.compile("def g(): yield\n\n", "<string>", "exec")
67 def testKeywordAfterStarargs(self
):
68 def f(*args
, **kwargs
):
69 self
.assertEqual((args
, kwargs
), ((2,3), {'x': 1, 'y': 4}))
70 c
= compiler
.compile('f(x=1, *(2, 3), y=4)', '<string>', 'exec')
73 self
.assertRaises(SyntaxError, compiler
.parse
, "foo(a=1, b)")
74 self
.assertRaises(SyntaxError, compiler
.parse
, "foo(1, *args, 3)")
76 def testTryExceptFinally(self
):
77 # Test that except and finally clauses in one try stmt are recognized
78 c
= compiler
.compile("try:\n 1/0\nexcept:\n e = 1\nfinally:\n f = 1",
82 self
.assertEquals(dct
.get('e'), 1)
83 self
.assertEquals(dct
.get('f'), 1)
85 def testDefaultArgs(self
):
86 self
.assertRaises(SyntaxError, compiler
.parse
, "def foo(a=1, b): pass")
88 def testDocstrings(self
):
89 c
= compiler
.compile('"doc"', '<string>', 'exec')
90 self
.assertTrue('__doc__' in c
.co_names
)
91 c
= compiler
.compile('def f():\n "doc"', '<string>', 'exec')
94 self
.assertEquals(g
['f'].__doc
__, "doc")
97 # Test that all nodes except Module have a correct lineno attribute.
99 if filename
.endswith((".pyc", ".pyo")):
100 filename
= filename
[:-1]
101 tree
= compiler
.parseFile(filename
)
102 self
.check_lineno(tree
)
104 def check_lineno(self
, node
):
106 self
._check
_lineno
(node
)
107 except AssertionError:
108 print node
.__class
__, node
.lineno
111 def _check_lineno(self
, node
):
112 if not node
.__class
__ in NOLINENO
:
113 self
.assertTrue(isinstance(node
.lineno
, int),
114 "lineno=%s on %s" % (node
.lineno
, node
.__class
__))
115 self
.assertTrue(node
.lineno
> 0,
116 "lineno=%s on %s" % (node
.lineno
, node
.__class
__))
117 for child
in node
.getChildNodes():
118 self
.check_lineno(child
)
120 def testFlatten(self
):
121 self
.assertEquals(flatten([1, [2]]), [1, 2])
122 self
.assertEquals(flatten((1, (2,))), [1, 2])
124 def testNestedScope(self
):
125 c
= compiler
.compile('def g():\n'
127 ' def f(): return a + 2\n'
134 self
.assertEquals(dct
.get('result'), 3)
136 def testGenExp(self
):
137 c
= compiler
.compile('list((i,j) for i in range(3) if i < 3'
138 ' for j in range(4) if j > 2)',
141 self
.assertEquals(eval(c
), [(0, 3), (1, 3), (2, 3)])
143 def testSetLiteral(self
):
144 c
= compiler
.compile('{1, 2, 3}', '<string>', 'eval')
145 self
.assertEquals(eval(c
), {1,2,3})
146 c
= compiler
.compile('{1, 2, 3,}', '<string>', 'eval')
147 self
.assertEquals(eval(c
), {1,2,3})
149 def testDictLiteral(self
):
150 c
= compiler
.compile('{1:2, 2:3, 3:4}', '<string>', 'eval')
151 self
.assertEquals(eval(c
), {1:2, 2:3, 3:4})
152 c
= compiler
.compile('{1:2, 2:3, 3:4,}', '<string>', 'eval')
153 self
.assertEquals(eval(c
), {1:2, 2:3, 3:4})
155 def testSetComp(self
):
156 c
= compiler
.compile('{x for x in range(1, 4)}', '<string>', 'eval')
157 self
.assertEquals(eval(c
), {1, 2, 3})
158 c
= compiler
.compile('{x * y for x in range(3) if x != 0'
159 ' for y in range(4) if y != 0}',
162 self
.assertEquals(eval(c
), {1, 2, 3, 4, 6})
164 def testDictComp(self
):
165 c
= compiler
.compile('{x:x+1 for x in range(1, 4)}', '<string>', 'eval')
166 self
.assertEquals(eval(c
), {1:2, 2:3, 3:4})
167 c
= compiler
.compile('{(x, y) : y for x in range(2) if x != 0'
168 ' for y in range(3) if y != 0}',
171 self
.assertEquals(eval(c
), {(1, 2): 2, (1, 1): 1})
175 c
= compiler
.compile('from __future__ import with_statement\n'
177 ' with TrivialContext():\n'
182 dct
= {'TrivialContext': TrivialContext
}
184 self
.assertEquals(dct
.get('result'), 1)
186 def testWithAss(self
):
187 c
= compiler
.compile('from __future__ import with_statement\n'
189 ' with TrivialContext() as tc:\n'
194 dct
= {'TrivialContext': TrivialContext
}
196 self
.assertEquals(dct
.get('result'), 1)
198 def testWithMult(self
):
201 def __init__(self
, n
):
204 events
.append(self
.n
)
205 def __exit__(self
, *args
):
207 c
= compiler
.compile('from __future__ import with_statement\n'
209 ' with Ctx(1) as tc, Ctx(2) as tc2:\n'
216 self
.assertEquals(dct
.get('result'), 1)
217 self
.assertEquals(events
, [1, 2])
219 def testGlobal(self
):
220 code
= compiler
.compile('global x\nx=1', '<string>', 'exec')
221 d1
= {'__builtins__': {}}
224 # x should be in the globals dict
225 self
.assertEquals(d1
.get('x'), 1)
227 def testPrintFunction(self
):
228 c
= compiler
.compile('from __future__ import print_function\n'
229 'print("a", "b", sep="**", end="++", '
233 dct
= {'output': StringIO()}
235 self
.assertEquals(dct
['output'].getvalue(), 'a**b++')
237 def _testErrEnc(self
, src
, text
, offset
):
239 compile(src
, "", "exec")
240 except SyntaxError, e
:
241 self
.assertEquals(e
.offset
, offset
)
242 self
.assertEquals(e
.text
, text
)
244 def testSourceCodeEncodingsError(self
):
245 # Test SyntaxError with encoding definition
246 sjis
= "print '\x83\x70\x83\x43\x83\x5c\x83\x93', '\n"
247 ascii
= "print '12345678', '\n"
248 encdef
= "#! -*- coding: ShiftJIS -*-\n"
250 # ascii source without encdef
251 self
._testErrEnc
(ascii
, ascii
, 19)
253 # ascii source with encdef
254 self
._testErrEnc
(encdef
+ascii
, ascii
, 19)
256 # non-ascii source with encdef
257 self
._testErrEnc
(encdef
+sjis
, sjis
, 19)
259 # ShiftJIS source without encdef
260 self
._testErrEnc
(sjis
, sjis
, 19)
263 NOLINENO
= (compiler
.ast
.Module
, compiler
.ast
.Stmt
, compiler
.ast
.Discard
)
265 ###############################################################################
266 # code below is just used to trigger some possible errors, for the benefit of
268 ###############################################################################
276 l
= [(x
, y
) for x
, y
in zip(range(5), range(5,10))]
281 d
= {x
: y
for x
, y
in zip(range(5), range(5,10))}
282 s
= {x
for x
in range(10)}
307 ###############################################################################
311 TEST_ALL
= test
.test_support
.is_resource_enabled("compiler")
312 test
.test_support
.run_unittest(CompilerTest
)
314 if __name__
== "__main__":