~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Lib/test/test_syntax.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""This module tests SyntaxErrors.
 
2
 
 
3
Here's an example of the sort of thing that is tested.
 
4
 
 
5
>>> def f(x):
 
6
...     global x
 
7
Traceback (most recent call last):
 
8
SyntaxError: name 'x' is parameter and global
 
9
 
 
10
The tests are all raise SyntaxErrors.  They were created by checking
 
11
each C call that raises SyntaxError.  There are several modules that
 
12
raise these exceptions-- ast.c, compile.c, future.c, pythonrun.c, and
 
13
symtable.c.
 
14
 
 
15
The parser itself outlaws a lot of invalid syntax.  None of these
 
16
errors are tested here at the moment.  We should add some tests; since
 
17
there are infinitely many programs with invalid syntax, we would need
 
18
to be judicious in selecting some.
 
19
 
 
20
The compiler generates a synthetic module name for code executed by
 
21
doctest.  Since all the code comes from the same module, a suffix like
 
22
[1] is appended to the module name, As a consequence, changing the
 
23
order of tests in this module means renumbering all the errors after
 
24
it.  (Maybe we should enable the ellipsis option for these tests.)
 
25
 
 
26
In ast.c, syntax errors are raised by calling ast_error().
 
27
 
 
28
Errors from set_context():
 
29
 
 
30
>>> obj.None = 1
 
31
Traceback (most recent call last):
 
32
SyntaxError: invalid syntax
 
33
 
 
34
>>> None = 1
 
35
Traceback (most recent call last):
 
36
SyntaxError: assignment to keyword
 
37
 
 
38
It's a syntax error to assign to the empty tuple.  Why isn't it an
 
39
error to assign to the empty list?  It will always raise some error at
 
40
runtime.
 
41
 
 
42
>>> () = 1
 
43
Traceback (most recent call last):
 
44
SyntaxError: can't assign to ()
 
45
 
 
46
>>> f() = 1
 
47
Traceback (most recent call last):
 
48
SyntaxError: can't assign to function call
 
49
 
 
50
>>> del f()
 
51
Traceback (most recent call last):
 
52
SyntaxError: can't delete function call
 
53
 
 
54
>>> a + 1 = 2
 
55
Traceback (most recent call last):
 
56
SyntaxError: can't assign to operator
 
57
 
 
58
>>> (x for x in x) = 1
 
59
Traceback (most recent call last):
 
60
SyntaxError: can't assign to generator expression
 
61
 
 
62
>>> 1 = 1
 
63
Traceback (most recent call last):
 
64
SyntaxError: can't assign to literal
 
65
 
 
66
>>> "abc" = 1
 
67
Traceback (most recent call last):
 
68
SyntaxError: can't assign to literal
 
69
 
 
70
>>> `1` = 1
 
71
Traceback (most recent call last):
 
72
SyntaxError: invalid syntax
 
73
 
 
74
If the left-hand side of an assignment is a list or tuple, an illegal
 
75
expression inside that contain should still cause a syntax error.
 
76
This test just checks a couple of cases rather than enumerating all of
 
77
them.
 
78
 
 
79
>>> (a, "b", c) = (1, 2, 3)
 
80
Traceback (most recent call last):
 
81
SyntaxError: can't assign to literal
 
82
 
 
83
>>> [a, b, c + 1] = [1, 2, 3]
 
84
Traceback (most recent call last):
 
85
SyntaxError: can't assign to operator
 
86
 
 
87
>>> a if 1 else b = 1
 
88
Traceback (most recent call last):
 
89
SyntaxError: can't assign to conditional expression
 
90
 
 
91
From compiler_complex_args():
 
92
 
 
93
>>> def f(None=1):
 
94
...     pass
 
95
Traceback (most recent call last):
 
96
SyntaxError: invalid syntax
 
97
 
 
98
 
 
99
From ast_for_arguments():
 
100
 
 
101
>>> def f(x, y=1, z):
 
102
...     pass
 
103
Traceback (most recent call last):
 
104
SyntaxError: non-default argument follows default argument
 
105
 
 
106
>>> def f(x, None):
 
107
...     pass
 
108
Traceback (most recent call last):
 
109
SyntaxError: invalid syntax
 
110
 
 
111
>>> def f(*None):
 
112
...     pass
 
113
Traceback (most recent call last):
 
114
SyntaxError: invalid syntax
 
115
 
 
116
>>> def f(**None):
 
117
...     pass
 
118
Traceback (most recent call last):
 
119
SyntaxError: invalid syntax
 
120
 
 
121
 
 
122
From ast_for_funcdef():
 
123
 
 
124
>>> def None(x):
 
125
...     pass
 
126
Traceback (most recent call last):
 
127
SyntaxError: invalid syntax
 
128
 
 
129
 
 
130
From ast_for_call():
 
131
 
 
132
>>> def f(it, *varargs):
 
133
...     return list(it)
 
134
>>> L = range(10)
 
135
>>> f(x for x in L)
 
136
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 
137
>>> f(x for x in L, 1)
 
138
Traceback (most recent call last):
 
139
SyntaxError: Generator expression must be parenthesized if not sole argument
 
140
>>> f((x for x in L), 1)
 
141
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 
142
 
 
143
>>> f(i0,  i1,  i2,  i3,  i4,  i5,  i6,  i7,  i8,  i9,  i10,  i11,
 
144
...   i12,  i13,  i14,  i15,  i16,  i17,  i18,  i19,  i20,  i21,  i22,
 
145
...   i23,  i24,  i25,  i26,  i27,  i28,  i29,  i30,  i31,  i32,  i33,
 
146
...   i34,  i35,  i36,  i37,  i38,  i39,  i40,  i41,  i42,  i43,  i44,
 
147
...   i45,  i46,  i47,  i48,  i49,  i50,  i51,  i52,  i53,  i54,  i55,
 
148
...   i56,  i57,  i58,  i59,  i60,  i61,  i62,  i63,  i64,  i65,  i66,
 
149
...   i67,  i68,  i69,  i70,  i71,  i72,  i73,  i74,  i75,  i76,  i77,
 
150
...   i78,  i79,  i80,  i81,  i82,  i83,  i84,  i85,  i86,  i87,  i88,
 
151
...   i89,  i90,  i91,  i92,  i93,  i94,  i95,  i96,  i97,  i98,  i99,
 
152
...   i100,  i101,  i102,  i103,  i104,  i105,  i106,  i107,  i108,
 
153
...   i109,  i110,  i111,  i112,  i113,  i114,  i115,  i116,  i117,
 
154
...   i118,  i119,  i120,  i121,  i122,  i123,  i124,  i125,  i126,
 
155
...   i127,  i128,  i129,  i130,  i131,  i132,  i133,  i134,  i135,
 
156
...   i136,  i137,  i138,  i139,  i140,  i141,  i142,  i143,  i144,
 
157
...   i145,  i146,  i147,  i148,  i149,  i150,  i151,  i152,  i153,
 
158
...   i154,  i155,  i156,  i157,  i158,  i159,  i160,  i161,  i162,
 
159
...   i163,  i164,  i165,  i166,  i167,  i168,  i169,  i170,  i171,
 
160
...   i172,  i173,  i174,  i175,  i176,  i177,  i178,  i179,  i180,
 
161
...   i181,  i182,  i183,  i184,  i185,  i186,  i187,  i188,  i189,
 
162
...   i190,  i191,  i192,  i193,  i194,  i195,  i196,  i197,  i198,
 
163
...   i199,  i200,  i201,  i202,  i203,  i204,  i205,  i206,  i207,
 
164
...   i208,  i209,  i210,  i211,  i212,  i213,  i214,  i215,  i216,
 
165
...   i217,  i218,  i219,  i220,  i221,  i222,  i223,  i224,  i225,
 
166
...   i226,  i227,  i228,  i229,  i230,  i231,  i232,  i233,  i234,
 
167
...   i235,  i236,  i237,  i238,  i239,  i240,  i241,  i242,  i243,
 
168
...   i244,  i245,  i246,  i247,  i248,  i249,  i250,  i251,  i252,
 
169
...   i253,  i254,  i255)
 
170
Traceback (most recent call last):
 
171
SyntaxError: more than 255 arguments
 
172
 
 
173
The actual error cases counts positional arguments, keyword arguments,
 
174
and generator expression arguments separately.  This test combines the
 
175
three.
 
176
 
 
177
>>> f(i0,  i1,  i2,  i3,  i4,  i5,  i6,  i7,  i8,  i9,  i10,  i11,
 
178
...   i12,  i13,  i14,  i15,  i16,  i17,  i18,  i19,  i20,  i21,  i22,
 
179
...   i23,  i24,  i25,  i26,  i27,  i28,  i29,  i30,  i31,  i32,  i33,
 
180
...   i34,  i35,  i36,  i37,  i38,  i39,  i40,  i41,  i42,  i43,  i44,
 
181
...   i45,  i46,  i47,  i48,  i49,  i50,  i51,  i52,  i53,  i54,  i55,
 
182
...   i56,  i57,  i58,  i59,  i60,  i61,  i62,  i63,  i64,  i65,  i66,
 
183
...   i67,  i68,  i69,  i70,  i71,  i72,  i73,  i74,  i75,  i76,  i77,
 
184
...   i78,  i79,  i80,  i81,  i82,  i83,  i84,  i85,  i86,  i87,  i88,
 
185
...   i89,  i90,  i91,  i92,  i93,  i94,  i95,  i96,  i97,  i98,  i99,
 
186
...   i100,  i101,  i102,  i103,  i104,  i105,  i106,  i107,  i108,
 
187
...   i109,  i110,  i111,  i112,  i113,  i114,  i115,  i116,  i117,
 
188
...   i118,  i119,  i120,  i121,  i122,  i123,  i124,  i125,  i126,
 
189
...   i127,  i128,  i129,  i130,  i131,  i132,  i133,  i134,  i135,
 
190
...   i136,  i137,  i138,  i139,  i140,  i141,  i142,  i143,  i144,
 
191
...   i145,  i146,  i147,  i148,  i149,  i150,  i151,  i152,  i153,
 
192
...   i154,  i155,  i156,  i157,  i158,  i159,  i160,  i161,  i162,
 
193
...   i163,  i164,  i165,  i166,  i167,  i168,  i169,  i170,  i171,
 
194
...   i172,  i173,  i174,  i175,  i176,  i177,  i178,  i179,  i180,
 
195
...   i181,  i182,  i183,  i184,  i185,  i186,  i187,  i188,  i189,
 
196
...   i190,  i191,  i192,  i193,  i194,  i195,  i196,  i197,  i198,
 
197
...   i199,  i200,  i201,  i202,  i203,  i204,  i205,  i206,  i207,
 
198
...   i208,  i209,  i210,  i211,  i212,  i213,  i214,  i215,  i216,
 
199
...   i217,  i218,  i219,  i220,  i221,  i222,  i223,  i224,  i225,
 
200
...   i226,  i227,  i228,  i229,  i230,  i231,  i232,  i233,  i234,
 
201
...   i235, i236,  i237,  i238,  i239,  i240,  i241,  i242,  i243,
 
202
...   (x for x in i244),  i245,  i246,  i247,  i248,  i249,  i250,  i251,
 
203
...    i252=1, i253=1,  i254=1,  i255=1)
 
204
Traceback (most recent call last):
 
205
SyntaxError: more than 255 arguments
 
206
 
 
207
>>> f(lambda x: x[0] = 3)
 
208
Traceback (most recent call last):
 
209
SyntaxError: lambda cannot contain assignment
 
210
 
 
211
The grammar accepts any test (basically, any expression) in the
 
212
keyword slot of a call site.  Test a few different options.
 
213
 
 
214
>>> f(x()=2)
 
215
Traceback (most recent call last):
 
216
SyntaxError: keyword can't be an expression
 
217
>>> f(a or b=1)
 
218
Traceback (most recent call last):
 
219
SyntaxError: keyword can't be an expression
 
220
>>> f(x.y=1)
 
221
Traceback (most recent call last):
 
222
SyntaxError: keyword can't be an expression
 
223
 
 
224
 
 
225
From ast_for_expr_stmt():
 
226
 
 
227
>>> (x for x in x) += 1
 
228
Traceback (most recent call last):
 
229
SyntaxError: augmented assignment to generator expression not possible
 
230
>>> None += 1
 
231
Traceback (most recent call last):
 
232
SyntaxError: assignment to keyword
 
233
>>> f() += 1
 
234
Traceback (most recent call last):
 
235
SyntaxError: illegal expression for augmented assignment
 
236
 
 
237
 
 
238
Test continue in finally in weird combinations.
 
239
 
 
240
continue in for loop under finally shouuld be ok.
 
241
 
 
242
    >>> def test():
 
243
    ...     try:
 
244
    ...         pass
 
245
    ...     finally:
 
246
    ...         for abc in range(10):
 
247
    ...             continue
 
248
    ...     print(abc)
 
249
    >>> test()
 
250
    9
 
251
 
 
252
Start simple, a continue in a finally should not be allowed.
 
253
 
 
254
    >>> def test():
 
255
    ...    for abc in range(10):
 
256
    ...        try:
 
257
    ...            pass
 
258
    ...        finally:
 
259
    ...            continue
 
260
    Traceback (most recent call last):
 
261
      ...
 
262
    SyntaxError: 'continue' not supported inside 'finally' clause
 
263
 
 
264
This is essentially a continue in a finally which should not be allowed.
 
265
 
 
266
    >>> def test():
 
267
    ...    for abc in range(10):
 
268
    ...        try:
 
269
    ...            pass
 
270
    ...        finally:
 
271
    ...            try:
 
272
    ...                continue
 
273
    ...            except:
 
274
    ...                pass
 
275
    Traceback (most recent call last):
 
276
      ...
 
277
    SyntaxError: 'continue' not supported inside 'finally' clause
 
278
 
 
279
    >>> def foo():
 
280
    ...     try:
 
281
    ...         pass
 
282
    ...     finally:
 
283
    ...         continue
 
284
    Traceback (most recent call last):
 
285
      ...
 
286
    SyntaxError: 'continue' not supported inside 'finally' clause
 
287
 
 
288
    >>> def foo():
 
289
    ...     for a in ():
 
290
    ...       try:
 
291
    ...           pass
 
292
    ...       finally:
 
293
    ...           continue
 
294
    Traceback (most recent call last):
 
295
      ...
 
296
    SyntaxError: 'continue' not supported inside 'finally' clause
 
297
 
 
298
    >>> def foo():
 
299
    ...     for a in ():
 
300
    ...         try:
 
301
    ...             pass
 
302
    ...         finally:
 
303
    ...             try:
 
304
    ...                 continue
 
305
    ...             finally:
 
306
    ...                 pass
 
307
    Traceback (most recent call last):
 
308
      ...
 
309
    SyntaxError: 'continue' not supported inside 'finally' clause
 
310
 
 
311
    >>> def foo():
 
312
    ...  for a in ():
 
313
    ...   try: pass
 
314
    ...   finally:
 
315
    ...    try:
 
316
    ...     pass
 
317
    ...    except:
 
318
    ...     continue
 
319
    Traceback (most recent call last):
 
320
      ...
 
321
    SyntaxError: 'continue' not supported inside 'finally' clause
 
322
 
 
323
There is one test for a break that is not in a loop.  The compiler
 
324
uses a single data structure to keep track of try-finally and loops,
 
325
so we need to be sure that a break is actually inside a loop.  If it
 
326
isn't, there should be a syntax error.
 
327
 
 
328
   >>> try:
 
329
   ...     print(1)
 
330
   ...     break
 
331
   ...     print(2)
 
332
   ... finally:
 
333
   ...     print(3)
 
334
   Traceback (most recent call last):
 
335
     ...
 
336
   SyntaxError: 'break' outside loop
 
337
 
 
338
This should probably raise a better error than a SystemError (or none at all).
 
339
In 2.5 there was a missing exception and an assert was triggered in a debug
 
340
build.  The number of blocks must be greater than CO_MAXBLOCKS.  SF #1565514
 
341
 
 
342
   >>> while 1:
 
343
   ...  while 2:
 
344
   ...   while 3:
 
345
   ...    while 4:
 
346
   ...     while 5:
 
347
   ...      while 6:
 
348
   ...       while 8:
 
349
   ...        while 9:
 
350
   ...         while 10:
 
351
   ...          while 11:
 
352
   ...           while 12:
 
353
   ...            while 13:
 
354
   ...             while 14:
 
355
   ...              while 15:
 
356
   ...               while 16:
 
357
   ...                while 17:
 
358
   ...                 while 18:
 
359
   ...                  while 19:
 
360
   ...                   while 20:
 
361
   ...                    while 21:
 
362
   ...                     while 22:
 
363
   ...                      break
 
364
   Traceback (most recent call last):
 
365
     ...
 
366
   SystemError: too many statically nested blocks
 
367
 
 
368
Misuse of the nonlocal statement can lead to a few unique syntax errors.
 
369
 
 
370
   >>> def f(x):
 
371
   ...     nonlocal x
 
372
   Traceback (most recent call last):
 
373
     ...
 
374
   SyntaxError: name 'x' is parameter and nonlocal
 
375
 
 
376
   >>> def f():
 
377
   ...     global x
 
378
   ...     nonlocal x
 
379
   Traceback (most recent call last):
 
380
     ...
 
381
   SyntaxError: name 'x' is nonlocal and global
 
382
 
 
383
   >>> def f():
 
384
   ...     nonlocal x
 
385
   Traceback (most recent call last):
 
386
     ...
 
387
   SyntaxError: no binding for nonlocal 'x' found
 
388
 
 
389
From SF bug #1705365
 
390
   >>> nonlocal x
 
391
   Traceback (most recent call last):
 
392
     ...
 
393
   SyntaxError: nonlocal declaration not allowed at module level
 
394
 
 
395
TODO(jhylton): Figure out how to test SyntaxWarning with doctest.
 
396
 
 
397
##   >>> def f(x):
 
398
##   ...     def f():
 
399
##   ...         print(x)
 
400
##   ...         nonlocal x
 
401
##   Traceback (most recent call last):
 
402
##     ...
 
403
##   SyntaxWarning: name 'x' is assigned to before nonlocal declaration
 
404
 
 
405
##   >>> def f():
 
406
##   ...     x = 1
 
407
##   ...     nonlocal x
 
408
##   Traceback (most recent call last):
 
409
##     ...
 
410
##   SyntaxWarning: name 'x' is assigned to before nonlocal declaration
 
411
 
 
412
 
 
413
This tests assignment-context; there was a bug in Python 2.5 where compiling
 
414
a complex 'if' (one with 'elif') would fail to notice an invalid suite,
 
415
leading to spurious errors.
 
416
 
 
417
   >>> if 1:
 
418
   ...   x() = 1
 
419
   ... elif 1:
 
420
   ...   pass
 
421
   Traceback (most recent call last):
 
422
     ...
 
423
   SyntaxError: can't assign to function call
 
424
 
 
425
   >>> if 1:
 
426
   ...   pass
 
427
   ... elif 1:
 
428
   ...   x() = 1
 
429
   Traceback (most recent call last):
 
430
     ...
 
431
   SyntaxError: can't assign to function call
 
432
 
 
433
   >>> if 1:
 
434
   ...   x() = 1
 
435
   ... elif 1:
 
436
   ...   pass
 
437
   ... else:
 
438
   ...   pass
 
439
   Traceback (most recent call last):
 
440
     ...
 
441
   SyntaxError: can't assign to function call
 
442
 
 
443
   >>> if 1:
 
444
   ...   pass
 
445
   ... elif 1:
 
446
   ...   x() = 1
 
447
   ... else:
 
448
   ...   pass
 
449
   Traceback (most recent call last):
 
450
     ...
 
451
   SyntaxError: can't assign to function call
 
452
 
 
453
   >>> if 1:
 
454
   ...   pass
 
455
   ... elif 1:
 
456
   ...   pass
 
457
   ... else:
 
458
   ...   x() = 1
 
459
   Traceback (most recent call last):
 
460
     ...
 
461
   SyntaxError: can't assign to function call
 
462
 
 
463
Make sure that the old "raise X, Y[, Z]" form is gone:
 
464
   >>> raise X, Y
 
465
   Traceback (most recent call last):
 
466
     ...
 
467
   SyntaxError: invalid syntax
 
468
   >>> raise X, Y, Z
 
469
   Traceback (most recent call last):
 
470
     ...
 
471
   SyntaxError: invalid syntax
 
472
 
 
473
 
 
474
>>> f(a=23, a=234)
 
475
Traceback (most recent call last):
 
476
   ...
 
477
SyntaxError: keyword argument repeated
 
478
 
 
479
"""
 
480
 
 
481
import re
 
482
import unittest
 
483
import warnings
 
484
 
 
485
from test import support
 
486
 
 
487
class SyntaxTestCase(unittest.TestCase):
 
488
 
 
489
    def _check_error(self, code, errtext,
 
490
                     filename="<testcase>", mode="exec", subclass=None):
 
491
        """Check that compiling code raises SyntaxError with errtext.
 
492
 
 
493
        errtest is a regular expression that must be present in the
 
494
        test of the exception raised.  If subclass is specified it
 
495
        is the expected subclass of SyntaxError (e.g. IndentationError).
 
496
        """
 
497
        try:
 
498
            compile(code, filename, mode)
 
499
        except SyntaxError as err:
 
500
            if subclass and not isinstance(err, subclass):
 
501
                self.fail("SyntaxError is not a %s" % subclass.__name__)
 
502
            mo = re.search(errtext, str(err))
 
503
            if mo is None:
 
504
                self.fail("SyntaxError did not contain '%r'" % (errtext,))
 
505
        else:
 
506
            self.fail("compile() did not raise SyntaxError")
 
507
 
 
508
    def test_assign_call(self):
 
509
        self._check_error("f() = 1", "assign")
 
510
 
 
511
    def test_assign_del(self):
 
512
        self._check_error("del f()", "delete")
 
513
 
 
514
    def test_global_err_then_warn(self):
 
515
        # Bug tickler:  The SyntaxError raised for one global statement
 
516
        # shouldn't be clobbered by a SyntaxWarning issued for a later one.
 
517
        source = re.sub('(?m)^ *:', '', """\
 
518
            :def error(a):
 
519
            :    global a  # SyntaxError
 
520
            :def warning():
 
521
            :    b = 1
 
522
            :    global b  # SyntaxWarning
 
523
            :""")
 
524
        warnings.filterwarnings(action='ignore', category=SyntaxWarning)
 
525
        self._check_error(source, "global")
 
526
        warnings.filters.pop(0)
 
527
 
 
528
    def test_break_outside_loop(self):
 
529
        self._check_error("break", "outside loop")
 
530
 
 
531
    def test_delete_deref(self):
 
532
        source = re.sub('(?m)^ *:', '', """\
 
533
            :def foo(x):
 
534
            :  def bar():
 
535
            :    print(x)
 
536
            :  del x
 
537
            :""")
 
538
        self._check_error(source, "nested scope")
 
539
 
 
540
    def test_unexpected_indent(self):
 
541
        self._check_error("foo()\n bar()\n", "unexpected indent",
 
542
                          subclass=IndentationError)
 
543
 
 
544
    def test_no_indent(self):
 
545
        self._check_error("if 1:\nfoo()", "expected an indented block",
 
546
                          subclass=IndentationError)
 
547
 
 
548
    def test_bad_outdent(self):
 
549
        self._check_error("if 1:\n  foo()\n bar()",
 
550
                          "unindent does not match .* level",
 
551
                          subclass=IndentationError)
 
552
 
 
553
    def test_kwargs_last(self):
 
554
        self._check_error("int(base=10, '2')", "non-keyword arg")
 
555
 
 
556
def test_main():
 
557
    support.run_unittest(SyntaxTestCase)
 
558
    from test import test_syntax
 
559
    support.run_doctest(test_syntax, verbosity=True)
 
560
 
 
561
if __name__ == "__main__":
 
562
    test_main()