gh-153569: read diagnostic lines through the source API · python/cpython@afd9d72 · GitHub
Skip to content

Commit afd9d72

Browse files
committed
gh-153569: read diagnostic lines through the source API
1 parent 841b57e commit afd9d72

4 files changed

Lines changed: 56 additions & 15 deletions

File tree

Modules/_testinternalcapi/tokenizer.c

Lines changed: 27 additions & 0 deletions

Parser/pegen_errors.c

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -226,22 +226,10 @@ _PyPegen_raise_error(Parser *p, PyObject *errtype, int use_mark, const char *err
226226
static PyObject *
227227
get_error_line_from_source(Parser *p, Py_ssize_t lineno)
228228
{
229-
const char *cur_line = _PyTok_SourceData(&p->tok->source);
230-
231229
Py_ssize_t relative_lineno = p->starting_lineno ? lineno - p->starting_lineno + 1 : lineno;
232-
const char *buf_end = cur_line + p->tok->source.len;
233-
234-
for (int i = 0; i < relative_lineno - 1; i++) {
235-
const char *new_line = memchr(cur_line, '\n', buf_end - cur_line);
236-
if (new_line == NULL) {
237-
break;
238-
}
239-
cur_line = new_line + 1;
240-
}
241-
242-
const char *next_newline = memchr(cur_line, '\n', buf_end - cur_line);
243-
next_newline = next_newline != NULL ? next_newline : buf_end;
244-
return PyUnicode_DecodeUTF8(cur_line, next_newline - cur_line, "replace");
230+
Py_ssize_t len;
231+
const char *line = _PyTok_SourceLineView(&p->tok->source, relative_lineno, &len);
232+
return PyUnicode_DecodeUTF8(line, len, "replace");
245233
}
246234

247235
void *

Parser/tokenizer/source.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,26 @@ _PyTok_SourceAppendLine(_PyTok_SourceText *source, const char *bytes,
134134
return start;
135135
}
136136

137+
const char *
138+
_PyTok_SourceLineView(const _PyTok_SourceText *source, Py_ssize_t lineno,
139+
Py_ssize_t *len)
140+
{
141+
assert(len != NULL);
142+
const char *line = _PyTok_SourceData(source);
143+
const char *end = line + source->len;
144+
while (lineno > 1) {
145+
const char *newline = memchr(line, '\n', end - line);
146+
if (newline == NULL) {
147+
break;
148+
}
149+
line = newline + 1;
150+
lineno--;
151+
}
152+
const char *newline = memchr(line, '\n', end - line);
153+
*len = (newline != NULL ? newline : end) - line;
154+
return line;
155+
}
156+
137157
int
138158
_PyTok_SourceLineIsImplicit(const _PyTok_SourceText *source, int lineno)
139159
{

Parser/tokenizer/source.h

Lines changed: 6 additions & 0 deletions

0 commit comments

Comments
 (0)