Skip to content

Commit 29e36ef

Browse files
bpo-35169: Improve error messages for forbidden assignments.
1 parent 34fd4c2 commit 29e36ef

6 files changed

Lines changed: 146 additions & 99 deletions

File tree

Lib/test/test_dictcomps.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ def test_local_visibility(self):
7373
self.assertEqual(v, "Local variable")
7474

7575
def test_illegal_assignment(self):
76-
with self.assertRaisesRegex(SyntaxError, "can't assign"):
76+
with self.assertRaisesRegex(SyntaxError, "cannot assign"):
7777
compile("{x: y for y, x in ((1, 2), (3, 4))} = 5", "<test>",
7878
"exec")
7979

80-
with self.assertRaisesRegex(SyntaxError, "can't assign"):
80+
with self.assertRaisesRegex(SyntaxError, "cannot assign"):
8181
compile("{x: y for y, x in ((1, 2), (3, 4))} += 5", "<test>",
8282
"exec")
8383

Lib/test/test_generators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,12 +1865,12 @@ def printsolution(self, x):
18651865
>>> def f(): (yield bar) = y
18661866
Traceback (most recent call last):
18671867
...
1868-
SyntaxError: can't assign to yield expression
1868+
SyntaxError: cannot assign to yield expression
18691869
18701870
>>> def f(): (yield bar) += y
18711871
Traceback (most recent call last):
18721872
...
1873-
SyntaxError: can't assign to yield expression
1873+
SyntaxError: cannot assign to yield expression
18741874
18751875
18761876
Now check some throw() conditions:

Lib/test/test_genexps.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,12 @@
137137
>>> (y for y in (1,2)) = 10
138138
Traceback (most recent call last):
139139
...
140-
SyntaxError: can't assign to generator expression
140+
SyntaxError: cannot assign to generator expression
141141
142142
>>> (y for y in (1,2)) += 10
143143
Traceback (most recent call last):
144144
...
145-
SyntaxError: can't assign to generator expression
145+
SyntaxError: cannot assign to generator expression
146146
147147
148148
########### Tests borrowed from or inspired by test_generators.py ############

Lib/test/test_syntax.py

Lines changed: 81 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,55 @@
3333
3434
>>> None = 1
3535
Traceback (most recent call last):
36-
SyntaxError: can't assign to keyword
36+
SyntaxError: cannot assign to None
37+
38+
>>> obj.True = 1
39+
Traceback (most recent call last):
40+
SyntaxError: invalid syntax
41+
42+
>>> True = 1
43+
Traceback (most recent call last):
44+
SyntaxError: cannot assign to True
45+
46+
>>> obj.__debug__ = 1
47+
Traceback (most recent call last):
48+
SyntaxError: cannot assign to __debug__
49+
50+
>>> __debug__ = 1
51+
Traceback (most recent call last):
52+
SyntaxError: cannot assign to __debug__
3753
3854
>>> f() = 1
3955
Traceback (most recent call last):
40-
SyntaxError: can't assign to function call
56+
SyntaxError: cannot assign to function call
4157
4258
>>> del f()
4359
Traceback (most recent call last):
44-
SyntaxError: can't delete function call
60+
SyntaxError: cannot delete function call
4561
4662
>>> a + 1 = 2
4763
Traceback (most recent call last):
48-
SyntaxError: can't assign to operator
64+
SyntaxError: cannot assign to operator
4965
5066
>>> (x for x in x) = 1
5167
Traceback (most recent call last):
52-
SyntaxError: can't assign to generator expression
68+
SyntaxError: cannot assign to generator expression
5369
5470
>>> 1 = 1
5571
Traceback (most recent call last):
56-
SyntaxError: can't assign to literal
72+
SyntaxError: cannot assign to literal
5773
5874
>>> "abc" = 1
5975
Traceback (most recent call last):
60-
SyntaxError: can't assign to literal
76+
SyntaxError: cannot assign to literal
6177
6278
>>> b"" = 1
6379
Traceback (most recent call last):
64-
SyntaxError: can't assign to literal
80+
SyntaxError: cannot assign to literal
81+
82+
>>> ... = 1
83+
Traceback (most recent call last):
84+
SyntaxError: cannot assign to Ellipsis
6585
6686
>>> `1` = 1
6787
Traceback (most recent call last):
@@ -74,15 +94,31 @@
7494
7595
>>> (a, "b", c) = (1, 2, 3)
7696
Traceback (most recent call last):
77-
SyntaxError: can't assign to literal
97+
SyntaxError: cannot assign to literal
98+
99+
>>> (a, True, c) = (1, 2, 3)
100+
Traceback (most recent call last):
101+
SyntaxError: cannot assign to True
102+
103+
>>> (a, __debug__, c) = (1, 2, 3)
104+
Traceback (most recent call last):
105+
SyntaxError: cannot assign to __debug__
106+
107+
>>> (a, *True, c) = (1, 2, 3)
108+
Traceback (most recent call last):
109+
SyntaxError: cannot assign to True
110+
111+
>>> (a, *__debug__, c) = (1, 2, 3)
112+
Traceback (most recent call last):
113+
SyntaxError: cannot assign to __debug__
78114
79115
>>> [a, b, c + 1] = [1, 2, 3]
80116
Traceback (most recent call last):
81-
SyntaxError: can't assign to operator
117+
SyntaxError: cannot assign to operator
82118
83119
>>> a if 1 else b = 1
84120
Traceback (most recent call last):
85-
SyntaxError: can't assign to conditional expression
121+
SyntaxError: cannot assign to conditional expression
86122
87123
From compiler_complex_args():
88124
@@ -255,36 +291,39 @@
255291
256292
>>> f(lambda x: x[0] = 3)
257293
Traceback (most recent call last):
258-
SyntaxError: lambda cannot contain assignment
294+
SyntaxError: expression cannot contain assignment, perhaps you meant "=="?
259295
260296
The grammar accepts any test (basically, any expression) in the
261297
keyword slot of a call site. Test a few different options.
262298
263299
>>> f(x()=2)
264300
Traceback (most recent call last):
265-
SyntaxError: keyword can't be an expression
301+
SyntaxError: expression cannot contain assignment, perhaps you meant "=="?
266302
>>> f(a or b=1)
267303
Traceback (most recent call last):
268-
SyntaxError: keyword can't be an expression
304+
SyntaxError: expression cannot contain assignment, perhaps you meant "=="?
269305
>>> f(x.y=1)
270306
Traceback (most recent call last):
271-
SyntaxError: keyword can't be an expression
307+
SyntaxError: expression cannot contain assignment, perhaps you meant "=="?
272308
>>> f((x)=2)
273309
Traceback (most recent call last):
274-
SyntaxError: keyword can't be an expression
310+
SyntaxError: expression cannot contain assignment, perhaps you meant "=="?
275311
276312
277313
More set_context():
278314
279315
>>> (x for x in x) += 1
280316
Traceback (most recent call last):
281-
SyntaxError: can't assign to generator expression
317+
SyntaxError: cannot assign to generator expression
282318
>>> None += 1
283319
Traceback (most recent call last):
284-
SyntaxError: can't assign to keyword
320+
SyntaxError: cannot assign to None
321+
>>> __debug__ += 1
322+
Traceback (most recent call last):
323+
SyntaxError: cannot assign to __debug__
285324
>>> f() += 1
286325
Traceback (most recent call last):
287-
SyntaxError: can't assign to function call
326+
SyntaxError: cannot assign to function call
288327
289328
290329
Test continue in finally in weird combinations.
@@ -481,15 +520,15 @@
481520
... pass
482521
Traceback (most recent call last):
483522
...
484-
SyntaxError: can't assign to function call
523+
SyntaxError: cannot assign to function call
485524
486525
>>> if 1:
487526
... pass
488527
... elif 1:
489528
... x() = 1
490529
Traceback (most recent call last):
491530
...
492-
SyntaxError: can't assign to function call
531+
SyntaxError: cannot assign to function call
493532
494533
>>> if 1:
495534
... x() = 1
@@ -499,7 +538,7 @@
499538
... pass
500539
Traceback (most recent call last):
501540
...
502-
SyntaxError: can't assign to function call
541+
SyntaxError: cannot assign to function call
503542
504543
>>> if 1:
505544
... pass
@@ -509,7 +548,7 @@
509548
... pass
510549
Traceback (most recent call last):
511550
...
512-
SyntaxError: can't assign to function call
551+
SyntaxError: cannot assign to function call
513552
514553
>>> if 1:
515554
... pass
@@ -519,7 +558,7 @@
519558
... x() = 1
520559
Traceback (most recent call last):
521560
...
522-
SyntaxError: can't assign to function call
561+
SyntaxError: cannot assign to function call
523562
524563
Make sure that the old "raise X, Y[, Z]" form is gone:
525564
>>> raise X, Y
@@ -539,21 +578,33 @@
539578
540579
>>> {1, 2, 3} = 42
541580
Traceback (most recent call last):
542-
SyntaxError: can't assign to literal
581+
SyntaxError: cannot assign to set display
582+
583+
>>> {1: 2, 3: 4} = 42
584+
Traceback (most recent call last):
585+
SyntaxError: cannot assign to dict display
586+
587+
>>> f'{x}' = 42
588+
Traceback (most recent call last):
589+
SyntaxError: cannot assign to f-string expression
590+
591+
>>> f'{x}-{y}' = 42
592+
Traceback (most recent call last):
593+
SyntaxError: cannot assign to f-string expression
543594
544595
Corner-cases that used to fail to raise the correct error:
545596
546597
>>> def f(*, x=lambda __debug__:0): pass
547598
Traceback (most recent call last):
548-
SyntaxError: assignment to keyword
599+
SyntaxError: cannot assign to __debug__
549600
550601
>>> def f(*args:(lambda __debug__:0)): pass
551602
Traceback (most recent call last):
552-
SyntaxError: assignment to keyword
603+
SyntaxError: cannot assign to __debug__
553604
554605
>>> def f(**kwargs:(lambda __debug__:0)): pass
555606
Traceback (most recent call last):
556-
SyntaxError: assignment to keyword
607+
SyntaxError: cannot assign to __debug__
557608
558609
>>> with (lambda *:0): pass
559610
Traceback (most recent call last):
@@ -563,11 +614,11 @@
563614
564615
>>> def f(**__debug__): pass
565616
Traceback (most recent call last):
566-
SyntaxError: assignment to keyword
617+
SyntaxError: cannot assign to __debug__
567618
568619
>>> def f(*xx, __debug__): pass
569620
Traceback (most recent call last):
570-
SyntaxError: assignment to keyword
621+
SyntaxError: cannot assign to __debug__
571622
572623
"""
573624

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved error messages for forbidden assignments.

0 commit comments

Comments
 (0)