Skip to content

Commit da8d72c

Browse files
bpo-12458: Fix line numbers for multiline expressions. (GH-8774)
1 parent 5e99b56 commit da8d72c

File tree

9 files changed

+3738
-3706
lines changed

9 files changed

+3738
-3706
lines changed

Lib/test/test_dis.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ def bug708901():
124124
2 LOAD_CONST 1 (1)
125125
126126
%3d 4 LOAD_CONST 2 (10)
127-
6 CALL_FUNCTION 2
127+
128+
%3d 6 CALL_FUNCTION 2
128129
8 GET_ITER
129130
>> 10 FOR_ITER 4 (to 16)
130131
12 STORE_FAST 0 (res)
@@ -134,6 +135,7 @@ def bug708901():
134135
18 RETURN_VALUE
135136
""" % (bug708901.__code__.co_firstlineno + 1,
136137
bug708901.__code__.co_firstlineno + 2,
138+
bug708901.__code__.co_firstlineno + 1,
137139
bug708901.__code__.co_firstlineno + 3)
138140

139141

@@ -154,7 +156,8 @@ def bug1333982(x=[]):
154156
16 CALL_FUNCTION 1
155157
156158
%3d 18 LOAD_CONST 4 (1)
157-
20 BINARY_ADD
159+
160+
%3d 20 BINARY_ADD
158161
22 CALL_FUNCTION 1
159162
24 RAISE_VARARGS 1
160163
@@ -164,6 +167,7 @@ def bug1333982(x=[]):
164167
__file__,
165168
bug1333982.__code__.co_firstlineno + 1,
166169
bug1333982.__code__.co_firstlineno + 2,
170+
bug1333982.__code__.co_firstlineno + 1,
167171
bug1333982.__code__.co_firstlineno + 3)
168172

169173
_BIG_LINENO_FORMAT = """\

Lib/test/test_doctest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2719,7 +2719,7 @@ def test_unicode(): """
27192719
Exception raised:
27202720
Traceback (most recent call last):
27212721
File ...
2722-
compileflags, 1), test.globs)
2722+
exec(compile(example.source, filename, "single",
27232723
File "<doctest foo-bär@baz[0]>", line 1, in <module>
27242724
raise Exception('clé')
27252725
Exception: clé

Lib/test/test_faulthandler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ def funcA():
400400
if filename:
401401
lineno = 9
402402
elif fd is not None:
403-
lineno = 12
403+
lineno = 11
404404
else:
405405
lineno = 14
406406
expected = [

Lib/test/test_traceback.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -995,11 +995,11 @@ def some_inner(k, v):
995995
s = some_inner(3, 4)
996996
self.assertEqual(
997997
[' File "%s", line %d, in some_inner\n'
998-
' traceback.walk_stack(None), capture_locals=True, limit=1)\n'
998+
' return traceback.StackSummary.extract(\n'
999999
' a = 1\n'
10001000
' b = 2\n'
10011001
' k = 3\n'
1002-
' v = 4\n' % (__file__, some_inner.__code__.co_firstlineno + 4)
1002+
' v = 4\n' % (__file__, some_inner.__code__.co_firstlineno + 3)
10031003
], s.format())
10041004

10051005
class TestTracebackException(unittest.TestCase):

Lib/test/test_tracemalloc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ def get_traceback(self):
936936
return None
937937

938938
def track(self, release_gil=False, nframe=1):
939-
frames = get_frames(nframe, 2)
939+
frames = get_frames(nframe, 1)
940940
_testcapi.tracemalloc_track(self.domain, self.ptr, self.size,
941941
release_gil)
942942
return frames
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Tracebacks show now correct line number for subexpressions in multiline
2+
expressions. Tracebacks show now the line number of the first line for
3+
multiline expressions instead of the line number of the last subexpression.

Python/compile.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4089,10 +4089,6 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
40894089
is_async_generator = c->u->u_ste->ste_coroutine;
40904090

40914091
if (is_async_generator && !is_async_function && type != COMP_GENEXP) {
4092-
if (e->lineno > c->u->u_lineno) {
4093-
c->u->u_lineno = e->lineno;
4094-
c->u->u_lineno_set = 0;
4095-
}
40964092
compiler_error(c, "asynchronous comprehension outside of "
40974093
"an asynchronous function");
40984094
goto error_in_scope;
@@ -4430,17 +4426,8 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
44304426
}
44314427

44324428
static int
4433-
compiler_visit_expr(struct compiler *c, expr_ty e)
4429+
compiler_visit_expr1(struct compiler *c, expr_ty e)
44344430
{
4435-
/* If expr e has a different line number than the last expr/stmt,
4436-
set a new line number for the next instruction.
4437-
*/
4438-
if (e->lineno > c->u->u_lineno) {
4439-
c->u->u_lineno = e->lineno;
4440-
c->u->u_lineno_set = 0;
4441-
}
4442-
/* Updating the column offset is always harmless. */
4443-
c->u->u_col_offset = e->col_offset;
44444431
switch (e->kind) {
44454432
case BoolOp_kind:
44464433
return compiler_boolop(c, e);
@@ -4609,6 +4596,31 @@ compiler_visit_expr(struct compiler *c, expr_ty e)
46094596
return 1;
46104597
}
46114598

4599+
static int
4600+
compiler_visit_expr(struct compiler *c, expr_ty e)
4601+
{
4602+
/* If expr e has a different line number than the last expr/stmt,
4603+
set a new line number for the next instruction.
4604+
*/
4605+
int old_lineno = c->u->u_lineno;
4606+
int old_col_offset = c->u->u_col_offset;
4607+
if (e->lineno != c->u->u_lineno) {
4608+
c->u->u_lineno = e->lineno;
4609+
c->u->u_lineno_set = 0;
4610+
}
4611+
/* Updating the column offset is always harmless. */
4612+
c->u->u_col_offset = e->col_offset;
4613+
4614+
int res = compiler_visit_expr1(c, e);
4615+
4616+
if (old_lineno != c->u->u_lineno) {
4617+
c->u->u_lineno = old_lineno;
4618+
c->u->u_lineno_set = 0;
4619+
}
4620+
c->u->u_col_offset = old_col_offset;
4621+
return res;
4622+
}
4623+
46124624
static int
46134625
compiler_augassign(struct compiler *c, stmt_ty s)
46144626
{

0 commit comments

Comments
 (0)