From 6bf644ec82f14cceae68278dc35bafb00875efae Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 24 Nov 2019 16:29:29 -0500 Subject: bpo-38862: IDLE Strip Trailing Whitespace fixes end newlines (GH-17366) Extra newlines are removed at the end of non-shell files. If the file only has newlines after stripping other trailing whitespace, all are removed, as is done by patchcheck.py. --- Doc/library/idle.rst | 3 +- Lib/idlelib/NEWS.txt | 3 ++ Lib/idlelib/format.py | 10 ++++ Lib/idlelib/help.html | 25 ++++----- Lib/idlelib/idle_test/mock_idle.py | 5 +- Lib/idlelib/idle_test/test_format.py | 62 +++++++++++++--------- .../IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst | 2 + 7 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 0bd248c..273b583 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -199,7 +199,8 @@ Format Paragraph Strip trailing whitespace Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, - including lines within multiline strings. + including lines within multiline strings. Except for Shell windows, + remove extra newlines at the end of the file. .. index:: single: Run script diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index c6aa00d..5eb7739 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2020-10-05? ====================================== +bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra +newlines at the end of non-shell files. + bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 and 3.8.0. diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index 2b09805..4b57a18 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -408,6 +408,16 @@ class Rstrip: # 'Strip Trailing Whitespace" on "Format" menu. if cut < raw: text.delete('%i.%i' % (cur, cut), '%i.end' % cur) + if (text.get('end-2c') == '\n' # File ends with at least 1 newline; + and not hasattr(self.editwin, 'interp')): # & is not Shell. + # Delete extra user endlines. + while (text.index('end-1c') > '1.0' # Stop if file empty. + and text.get('end-3c') == '\n'): + text.delete('end-3c') + # Because tk indexes are slice indexes and never raise, + # a file with only newlines will be emptied. + # patchcheck.py does the same. + undo.undo_block_stop() diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 0754f24..09dc4c5 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -4,7 +4,7 @@ - IDLE — Python 3.9.0a0 documentation + IDLE — Python 3.9.0a1 documentation @@ -17,14 +17,14 @@ - + @@ -62,7 +62,7 @@ next |
  • - previous |
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -240,7 +240,8 @@ paragraph will be formatted to less than N columns, where N defaults to 72.

    Strip trailing whitespace

    Remove trailing space and other whitespace characters after the last non-whitespace character of a line by applying str.rstrip to each line, -including lines within multiline strings.

    +including lines within multiline strings. Except for Shell windows, +remove extra newlines at the end of the file.

    @@ -886,8 +887,8 @@ also used for testing.

    Previous topic

    -

    tkinter.scrolledtext — Scrolled Text Widget

    +

    tkinter.tix — Extension widgets for Tk

    Next topic

    Other Graphical User Interface Packages

    @@ -919,7 +920,7 @@ also used for testing.

    next |
  • - previous |
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -959,11 +960,11 @@ also used for testing.



    - Last updated on Sep 01, 2019. + Last updated on Nov 24, 2019. Found a bug?
    - Created using Sphinx 2.1.2. + Created using Sphinx 2.1.1. diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index f279a52..71fa480 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -40,8 +40,9 @@ class Func: class Editor: '''Minimally imitate editor.EditorWindow class. ''' - def __init__(self, flist=None, filename=None, key=None, root=None): - self.text = Text() + def __init__(self, flist=None, filename=None, key=None, root=None, + text=None): # Allow real Text with mock Editor. + self.text = text or Text() self.undo = UndoDelegator() def get_selection_indices(self): diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index 20b5970..a79bb51 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -611,37 +611,33 @@ class IndentsTest(unittest.TestCase): class RstripTest(unittest.TestCase): - def test_rstrip_line(self): - editor = MockEditor() - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip - eq = self.assertEqual + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.text = Text(cls.root) + cls.editor = MockEditor(text=cls.text) + cls.do_rstrip = ft.Rstrip(cls.editor).do_rstrip + + @classmethod + def tearDownClass(cls): + del cls.text, cls.do_rstrip, cls.editor + cls.root.update_idletasks() + cls.root.destroy() + del cls.root - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' ') - do_rstrip() - eq(text.get('1.0', 'insert'), '') - text.insert('1.0', ' \n') - do_rstrip() - eq(text.get('1.0', 'insert'), '\n') - - def test_rstrip_multiple(self): - editor = MockEditor() - # Comment above, uncomment 3 below to test with real Editor & Text. - #from idlelib.editor import EditorWindow as Editor - #from tkinter import Tk - #editor = Editor(root=Tk()) - text = editor.text - do_rstrip = ft.Rstrip(editor).do_rstrip + def tearDown(self): + self.text.delete('1.0', 'end-1c') + def test_rstrip_lines(self): original = ( "Line with an ending tab \n" "Line ending in 5 spaces \n" "Linewithnospaces\n" " indented line\n" " indented line with trailing space \n" - " ") + " \n") stripped = ( "Line with an ending tab\n" "Line ending in 5 spaces\n" @@ -649,9 +645,23 @@ class RstripTest(unittest.TestCase): " indented line\n" " indented line with trailing space\n") - text.insert('1.0', original) - do_rstrip() - self.assertEqual(text.get('1.0', 'insert'), stripped) + self.text.insert('1.0', original) + self.do_rstrip() + self.assertEqual(self.text.get('1.0', 'insert'), stripped) + + def test_rstrip_end(self): + text = self.text + for code in ('', '\n', '\n\n\n'): + with self.subTest(code=code): + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), '') + for code in ('a\n', 'a\n\n', 'a\n\n\n'): + with self.subTest(code=code): + text.delete('1.0', 'end-1c') + text.insert('1.0', code) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), 'a\n') if __name__ == '__main__': diff --git a/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst new file mode 100644 index 0000000..14bab9e --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst @@ -0,0 +1,2 @@ +'Strip Trailing Whitespace' on the Format menu removes extra newlines +at the end of non-shell files. -- cgit v0.12