mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
gh-104825: Remove implicit newline in the line attribute in tokens emitted in the tokenize module (#104846)
This commit is contained in:
parent
c45701e9ef
commit
c8cf9b42eb
5 changed files with 14 additions and 8 deletions
|
@ -201,8 +201,8 @@ class IndentSearcherTest(unittest.TestCase):
|
||||||
test_info = (# text, (block, indent))
|
test_info = (# text, (block, indent))
|
||||||
("", (None, None)),
|
("", (None, None)),
|
||||||
("[1,", (None, None)), # TokenError
|
("[1,", (None, None)), # TokenError
|
||||||
("if 1:\n", ('if 1:\n', None)),
|
("if 1:\n", ('if 1:', None)),
|
||||||
("if 1:\n 2\n 3\n", ('if 1:\n', ' 2\n')),
|
("if 1:\n 2\n 3\n", ('if 1:', ' 2')),
|
||||||
)
|
)
|
||||||
for code, expected_pair in test_info:
|
for code, expected_pair in test_info:
|
||||||
with self.subTest(code=code):
|
with self.subTest(code=code):
|
||||||
|
|
|
@ -222,7 +222,7 @@ class TestCheck(TestCase):
|
||||||
"""
|
"""
|
||||||
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
|
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
|
||||||
out = f"{file_path!r}: *** Line 3: trouble in tab city! ***\n"
|
out = f"{file_path!r}: *** Line 3: trouble in tab city! ***\n"
|
||||||
out += "offending line: '\\tprint(\"world\")\\n'\n"
|
out += "offending line: '\\tprint(\"world\")'\n"
|
||||||
out += "inconsistent use of tabs and spaces in indentation\n"
|
out += "inconsistent use of tabs and spaces in indentation\n"
|
||||||
|
|
||||||
tabnanny.verbose = 1
|
tabnanny.verbose = 1
|
||||||
|
@ -231,7 +231,7 @@ class TestCheck(TestCase):
|
||||||
def test_when_nannynag_error(self):
|
def test_when_nannynag_error(self):
|
||||||
"""A python source code file eligible for raising `tabnanny.NannyNag`."""
|
"""A python source code file eligible for raising `tabnanny.NannyNag`."""
|
||||||
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
|
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
|
||||||
out = f"{file_path} 3 '\\tprint(\"world\")\\n'\n"
|
out = f"{file_path} 3 '\\tprint(\"world\")'\n"
|
||||||
self.verify_tabnanny_check(file_path, out=out)
|
self.verify_tabnanny_check(file_path, out=out)
|
||||||
|
|
||||||
def test_when_no_file(self):
|
def test_when_no_file(self):
|
||||||
|
@ -341,7 +341,7 @@ class TestCommandLine(TestCase):
|
||||||
"""Should display more error information if verbose mode is on."""
|
"""Should display more error information if verbose mode is on."""
|
||||||
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path:
|
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path:
|
||||||
stdout = textwrap.dedent(
|
stdout = textwrap.dedent(
|
||||||
"offending line: '\\tprint(\"world\")\\n'"
|
"offending line: '\\tprint(\"world\")'"
|
||||||
).strip()
|
).strip()
|
||||||
self.validate_cmd("-v", path, stdout=stdout, partial=True)
|
self.validate_cmd("-v", path, stdout=stdout, partial=True)
|
||||||
|
|
||||||
|
@ -349,6 +349,6 @@ class TestCommandLine(TestCase):
|
||||||
"""Should display detailed error information if double verbose is on."""
|
"""Should display detailed error information if double verbose is on."""
|
||||||
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path:
|
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path:
|
||||||
stdout = textwrap.dedent(
|
stdout = textwrap.dedent(
|
||||||
"offending line: '\\tprint(\"world\")\\n'"
|
"offending line: '\\tprint(\"world\")'"
|
||||||
).strip()
|
).strip()
|
||||||
self.validate_cmd("-vv", path, stdout=stdout, partial=True)
|
self.validate_cmd("-vv", path, stdout=stdout, partial=True)
|
||||||
|
|
|
@ -103,7 +103,7 @@ def k(x):
|
||||||
e.exception.msg,
|
e.exception.msg,
|
||||||
'unindent does not match any outer indentation level')
|
'unindent does not match any outer indentation level')
|
||||||
self.assertEqual(e.exception.offset, 9)
|
self.assertEqual(e.exception.offset, 9)
|
||||||
self.assertEqual(e.exception.text, ' x += 5\n')
|
self.assertEqual(e.exception.text, ' x += 5')
|
||||||
|
|
||||||
def test_int(self):
|
def test_int(self):
|
||||||
# Ordinary integers and binary operators
|
# Ordinary integers and binary operators
|
||||||
|
@ -1157,7 +1157,7 @@ class Test_Tokenize(TestCase):
|
||||||
|
|
||||||
# skip the initial encoding token and the end tokens
|
# skip the initial encoding token and the end tokens
|
||||||
tokens = list(_tokenize(readline(), encoding='utf-8'))[:-2]
|
tokens = list(_tokenize(readline(), encoding='utf-8'))[:-2]
|
||||||
expected_tokens = [TokenInfo(3, '"ЉЊЈЁЂ"', (1, 0), (1, 7), '"ЉЊЈЁЂ"\n')]
|
expected_tokens = [TokenInfo(3, '"ЉЊЈЁЂ"', (1, 0), (1, 7), '"ЉЊЈЁЂ"')]
|
||||||
self.assertEqual(tokens, expected_tokens,
|
self.assertEqual(tokens, expected_tokens,
|
||||||
"bytes not decoded with encoding")
|
"bytes not decoded with encoding")
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Tokens emitted by the :mod:`tokenize` module do not include an implicit
|
||||||
|
``\n`` character in the ``line`` attribute anymore. Patch by Pablo Galindo
|
|
@ -123,6 +123,8 @@ _tokenizer_error(struct tok_state *tok)
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
Py_ssize_t size = tok->inp - tok->buf;
|
Py_ssize_t size = tok->inp - tok->buf;
|
||||||
|
assert(tok->buf[size-1] == '\n');
|
||||||
|
size -= 1; // Remove the newline character from the end of the line
|
||||||
error_line = PyUnicode_DecodeUTF8(tok->buf, size, "replace");
|
error_line = PyUnicode_DecodeUTF8(tok->buf, size, "replace");
|
||||||
if (!error_line) {
|
if (!error_line) {
|
||||||
result = -1;
|
result = -1;
|
||||||
|
@ -193,6 +195,8 @@ tokenizeriter_next(tokenizeriterobject *it)
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t size = it->tok->inp - it->tok->buf;
|
Py_ssize_t size = it->tok->inp - it->tok->buf;
|
||||||
|
assert(it->tok->buf[size-1] == '\n');
|
||||||
|
size -= 1; // Remove the newline character from the end of the line
|
||||||
PyObject *line = PyUnicode_DecodeUTF8(it->tok->buf, size, "replace");
|
PyObject *line = PyUnicode_DecodeUTF8(it->tok->buf, size, "replace");
|
||||||
if (line == NULL) {
|
if (line == NULL) {
|
||||||
Py_DECREF(str);
|
Py_DECREF(str);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue