Skip to content

Commit 582e25b

Browse files
authored
Update tabnanny.py from 3.13.5 (#6021)
1 parent d897f9e commit 582e25b

File tree

2 files changed

+45
-28
lines changed

2 files changed

+45
-28
lines changed

Lib/tabnanny.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
import os
2424
import sys
2525
import tokenize
26-
if not hasattr(tokenize, 'NL'):
27-
raise ValueError("tokenize.NL doesn't exist -- tokenize module too old")
2826

2927
__all__ = ["check", "NannyNag", "process_tokens"]
3028

@@ -37,6 +35,7 @@ def errprint(*args):
3735
sys.stderr.write(sep + str(arg))
3836
sep = " "
3937
sys.stderr.write("\n")
38+
sys.exit(1)
4039

4140
def main():
4241
import getopt
@@ -46,15 +45,13 @@ def main():
4645
opts, args = getopt.getopt(sys.argv[1:], "qv")
4746
except getopt.error as msg:
4847
errprint(msg)
49-
return
5048
for o, a in opts:
5149
if o == '-q':
5250
filename_only = filename_only + 1
5351
if o == '-v':
5452
verbose = verbose + 1
5553
if not args:
5654
errprint("Usage:", sys.argv[0], "[-v] file_or_directory ...")
57-
return
5855
for arg in args:
5956
check(arg)
6057

@@ -114,6 +111,10 @@ def check(file):
114111
errprint("%r: Indentation Error: %s" % (file, msg))
115112
return
116113

114+
except SyntaxError as msg:
115+
errprint("%r: Syntax Error: %s" % (file, msg))
116+
return
117+
117118
except NannyNag as nag:
118119
badline = nag.get_lineno()
119120
line = nag.get_line()
@@ -275,6 +276,12 @@ def format_witnesses(w):
275276
return prefix + " " + ', '.join(firsts)
276277

277278
def process_tokens(tokens):
279+
try:
280+
_process_tokens(tokens)
281+
except TabError as e:
282+
raise NannyNag(e.lineno, e.msg, e.text)
283+
284+
def _process_tokens(tokens):
278285
INDENT = tokenize.INDENT
279286
DEDENT = tokenize.DEDENT
280287
NEWLINE = tokenize.NEWLINE

Lib/test/test_tabnanny.py

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
findfile)
1515
from test.support.os_helper import unlink
1616

17-
import unittest # XXX: RUSTPYTHON
17+
import unittest # TODO: RUSTPYTHON
1818

1919

2020
SOURCE_CODES = {
@@ -112,9 +112,10 @@ def test_errprint(self):
112112

113113
for args, expected in tests:
114114
with self.subTest(arguments=args, expected=expected):
115-
with captured_stderr() as stderr:
116-
tabnanny.errprint(*args)
117-
self.assertEqual(stderr.getvalue() , expected)
115+
with self.assertRaises(SystemExit):
116+
with captured_stderr() as stderr:
117+
tabnanny.errprint(*args)
118+
self.assertEqual(stderr.getvalue() , expected)
118119

119120

120121
class TestNannyNag(TestCase):
@@ -199,53 +200,54 @@ def test_correct_directory(self):
199200
with TemporaryPyFile(SOURCE_CODES["error_free"], directory=tmp_dir):
200201
self.verify_tabnanny_check(tmp_dir)
201202

202-
# TODO: RUSTPYTHON
203-
@unittest.expectedFailure
204203
def test_when_wrong_indented(self):
205204
"""A python source code file eligible for raising `IndentationError`."""
206205
with TemporaryPyFile(SOURCE_CODES["wrong_indented"]) as file_path:
207206
err = ('unindent does not match any outer indentation level'
208207
' (<tokenize>, line 3)\n')
209208
err = f"{file_path!r}: Indentation Error: {err}"
210-
self.verify_tabnanny_check(file_path, err=err)
209+
with self.assertRaises(SystemExit):
210+
self.verify_tabnanny_check(file_path, err=err)
211211

212212
def test_when_tokenize_tokenerror(self):
213213
"""A python source code file eligible for raising 'tokenize.TokenError'."""
214214
with TemporaryPyFile(SOURCE_CODES["incomplete_expression"]) as file_path:
215215
err = "('EOF in multi-line statement', (7, 0))\n"
216216
err = f"{file_path!r}: Token Error: {err}"
217-
self.verify_tabnanny_check(file_path, err=err)
217+
with self.assertRaises(SystemExit):
218+
self.verify_tabnanny_check(file_path, err=err)
218219

220+
# TODO: RUSTPYTHON
221+
@unittest.expectedFailure
219222
def test_when_nannynag_error_verbose(self):
220223
"""A python source code file eligible for raising `tabnanny.NannyNag`.
221224
222225
Tests will assert `stdout` after activating `tabnanny.verbose` mode.
223226
"""
224227
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
225228
out = f"{file_path!r}: *** Line 3: trouble in tab city! ***\n"
226-
out += "offending line: '\\tprint(\"world\")\\n'\n"
227-
out += "indent not equal e.g. at tab size 1\n"
229+
out += "offending line: '\\tprint(\"world\")'\n"
230+
out += "inconsistent use of tabs and spaces in indentation\n"
228231

229232
tabnanny.verbose = 1
230233
self.verify_tabnanny_check(file_path, out=out)
231234

235+
# TODO: RUSTPYTHON
236+
@unittest.expectedFailure
232237
def test_when_nannynag_error(self):
233238
"""A python source code file eligible for raising `tabnanny.NannyNag`."""
234239
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
235-
out = f"{file_path} 3 '\\tprint(\"world\")\\n'\n"
240+
out = f"{file_path} 3 '\\tprint(\"world\")'\n"
236241
self.verify_tabnanny_check(file_path, out=out)
237242

238-
# TODO: RUSTPYTHON
239-
@unittest.expectedFailure
240243
def test_when_no_file(self):
241244
"""A python file which does not exist actually in system."""
242245
path = 'no_file.py'
243246
err = (f"{path!r}: I/O Error: [Errno {errno.ENOENT}] "
244247
f"{os.strerror(errno.ENOENT)}: {path!r}\n")
245-
self.verify_tabnanny_check(path, err=err)
248+
with self.assertRaises(SystemExit):
249+
self.verify_tabnanny_check(path, err=err)
246250

247-
# TODO: RUSTPYTHON
248-
@unittest.expectedFailure
249251
def test_errored_directory(self):
250252
"""Directory containing wrongly indented python source code files."""
251253
with tempfile.TemporaryDirectory() as tmp_dir:
@@ -259,7 +261,8 @@ def test_errored_directory(self):
259261
err = ('unindent does not match any outer indentation level'
260262
' (<tokenize>, line 3)\n')
261263
err = f"{e_file!r}: Indentation Error: {err}"
262-
self.verify_tabnanny_check(tmp_dir, err=err)
264+
with self.assertRaises(SystemExit):
265+
self.verify_tabnanny_check(tmp_dir, err=err)
263266

264267

265268
class TestProcessTokens(TestCase):
@@ -295,9 +298,12 @@ def test_with_errored_codes_samples(self):
295298
class TestCommandLine(TestCase):
296299
"""Tests command line interface of `tabnanny`."""
297300

298-
def validate_cmd(self, *args, stdout="", stderr="", partial=False):
301+
def validate_cmd(self, *args, stdout="", stderr="", partial=False, expect_failure=False):
299302
"""Common function to assert the behaviour of command line interface."""
300-
_, out, err = script_helper.assert_python_ok('-m', 'tabnanny', *args)
303+
if expect_failure:
304+
_, out, err = script_helper.assert_python_failure('-m', 'tabnanny', *args)
305+
else:
306+
_, out, err = script_helper.assert_python_ok('-m', 'tabnanny', *args)
301307
# Note: The `splitlines()` will solve the problem of CRLF(\r) added
302308
# by OS Windows.
303309
out = os.fsdecode(out)
@@ -319,8 +325,8 @@ def test_with_errored_file(self):
319325
with TemporaryPyFile(SOURCE_CODES["wrong_indented"]) as file_path:
320326
stderr = f"{file_path!r}: Indentation Error: "
321327
stderr += ('unindent does not match any outer indentation level'
322-
' (<tokenize>, line 3)')
323-
self.validate_cmd(file_path, stderr=stderr)
328+
' (<string>, line 3)')
329+
self.validate_cmd(file_path, stderr=stderr, expect_failure=True)
324330

325331
def test_with_error_free_file(self):
326332
"""Should not display anything if python file is correctly indented."""
@@ -331,26 +337,30 @@ def test_command_usage(self):
331337
"""Should display usage on no arguments."""
332338
path = findfile('tabnanny.py')
333339
stderr = f"Usage: {path} [-v] file_or_directory ..."
334-
self.validate_cmd(stderr=stderr)
340+
self.validate_cmd(stderr=stderr, expect_failure=True)
335341

336342
def test_quiet_flag(self):
337343
"""Should display less when quite mode is on."""
338344
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path:
339345
stdout = f"{file_path}\n"
340346
self.validate_cmd("-q", file_path, stdout=stdout)
341347

348+
# TODO: RUSTPYTHON
349+
@unittest.expectedFailure
342350
def test_verbose_mode(self):
343351
"""Should display more error information if verbose mode is on."""
344352
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path:
345353
stdout = textwrap.dedent(
346-
"offending line: '\\tprint(\"world\")\\n'"
354+
"offending line: '\\tprint(\"world\")'"
347355
).strip()
348356
self.validate_cmd("-v", path, stdout=stdout, partial=True)
349357

358+
# TODO: RUSTPYTHON
359+
@unittest.expectedFailure
350360
def test_double_verbose_mode(self):
351361
"""Should display detailed error information if double verbose is on."""
352362
with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path:
353363
stdout = textwrap.dedent(
354-
"offending line: '\\tprint(\"world\")\\n'"
364+
"offending line: '\\tprint(\"world\")'"
355365
).strip()
356366
self.validate_cmd("-vv", path, stdout=stdout, partial=True)

0 commit comments

Comments
 (0)