From 45b6e3a795778448f03e3e7a7796898842af40b7 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 23 Nov 2019 21:57:30 -0500 Subject: [PATCH 1/8] bpo-38862: IDLE Strip Trailing Whitespace fixes end newlines A non-blank non-shell window should end with exactly one newline following something other than space, tab, or newline. It should then be ready to commit to the cpython repository. --- .../NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst 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 00000000000000..e485fc28a29308 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst @@ -0,0 +1,4 @@ +Format menu Strip Trailing Whitespace adjusts ending newlines of non shell +windows so that the file is either blank or ends with one newline after +something other than space, tab, or newline. The result should be ready to +commit to the CPython repository. From db5d873f394a59215aa4d477eceb78b72f18505d Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 23 Nov 2019 21:58:47 -0500 Subject: [PATCH 2/8] Add text parameter to mock Editor so a tk Text can be passed in. --- Lib/idlelib/idle_test/mock_idle.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index f279a52fd511f0..71fa480ce4d05c 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -40,8 +40,9 @@ def __call__(self, *args, **kwds): 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): From f4dcabc3ede8ecac926698e3e72553b52e347b83 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 23 Nov 2019 22:02:01 -0500 Subject: [PATCH 3/8] Add new code and test for fixing endlines. --- Lib/idlelib/format.py | 14 +++++++ Lib/idlelib/idle_test/test_format.py | 62 ++++++++++++++++------------ 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index 2b0980565734a4..188cf2e536c1f8 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -408,6 +408,20 @@ def do_rstrip(self, event=None): if cut < raw: text.delete('%i.%i' % (cur, cut), '%i.end' % cur) + # 'Empty' file has tk guard newline at index 'end-1c' = '1.0'. + # Only adjust ending newlines for non-empty non-shell window. + if (text.index('end-1c') > '1.0' + and not hasattr(self.editwin, 'interp')): + if text.get('end-2c') != '\n': # No user endline, add one. + text.insert('end-1c', '\n') + else: # Delete extra user endlines. + while (text.index('end-1c') > '1.0' # Stop when 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/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index 20b5970f4982da..89e12ee3a00473 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -611,37 +611,33 @@ def test_change_indentwidth(self, askinteger): 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 - 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 + @classmethod + def tearDownClass(cls): + del cls.text, cls.do_rstrip, cls.editor + cls.root.update_idletasks() + cls.root.destroy() + del cls.root + + def tearDown(self): + self.text.delete('1.0', 'end') + 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 @@ def test_rstrip_multiple(self): " 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 t in ('', '\n', '\n\n\n'): + with self.subTest(t=t): + text.insert('1.0', t) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), '') + for t in ('a', 'a\n', 'a\n\n', 'a\n\n\n'): + with self.subTest(t=t): + text.delete('1.0', 'end') + text.insert('1.0', t) + self.do_rstrip() + self.assertEqual(text.get('1.0','end-1c'), 'a\n') if __name__ == '__main__': From 9a4d241f3bd66339089b571dbef6fcd137b3d03e Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 23 Nov 2019 22:02:49 -0500 Subject: [PATCH 4/8] idlelib NEWS.txt entry --- Lib/idlelib/NEWS.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index c6aa00d0d54b32..4a60b25f4ef0d9 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,11 @@ Released on 2020-10-05? ====================================== +bpo-38862: Format menu Strip Trailing Whitespace adjusts end newlines. +Non shell windows will be either blank or end with one newline after +something other than space, tab, or newline. The result should be +ready to commit to the CPython repository. + 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. From fff243b643eaa5878b5554234c9aba09b804cbba Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sat, 23 Nov 2019 22:14:53 -0500 Subject: [PATCH 5/8] Update IDLE doc and help.html. --- Doc/library/idle.rst | 4 +++- Lib/idlelib/help.html | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 0bd248c22b1820..742bc4d16cc8f5 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -199,7 +199,9 @@ 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, + adjust ending newlines so that the file is either empty or ends with a + newline following something other than space, tab, or newline. .. index:: single: Run script diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 0754f2453baf66..80541f293b0941 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 @@

Navigation

next |
  • - previous |
  • Navigation
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -240,7 +240,9 @@

    Edit menu (Shell and Editor)Table of Contents

    Previous topic

    -

    tkinter.scrolledtext — Scrolled Text Widget

    +

    tkinter.tix — Extension widgets for Tk

    Next topic

    Other Graphical User Interface Packages

    @@ -919,7 +921,7 @@

    Navigation

    next |
  • - previous |
  • Navigation
  • - 3.9.0a0 Documentation » + 3.9.0a1 Documentation »
  • @@ -959,11 +961,11 @@

    Navigation



    - Last updated on Sep 01, 2019. + Last updated on Nov 23, 2019. Found a bug?
    - Created using Sphinx 2.1.2. + Created using Sphinx 2.1.1. From 3fc2659feaeb890f4fd0e886f725ce0af2000d16 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 24 Nov 2019 13:24:08 -0500 Subject: [PATCH 6/8] Be explicit on slice bounds. --- Lib/idlelib/idle_test/test_format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index 89e12ee3a00473..bc1b09241d2ed8 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -628,7 +628,7 @@ def tearDownClass(cls): del cls.root def tearDown(self): - self.text.delete('1.0', 'end') + self.text.delete('1.0', 'end-1c') def test_rstrip_lines(self): original = ( From d13fc65b9c34ceae9ced6f8735ee9aab5db252b1 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 24 Nov 2019 14:05:19 -0500 Subject: [PATCH 7/8] Remove newline addition. --- Lib/idlelib/format.py | 22 +++++++++------------- Lib/idlelib/idle_test/test_format.py | 14 +++++++------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/Lib/idlelib/format.py b/Lib/idlelib/format.py index 188cf2e536c1f8..4b57a182c9a49d 100644 --- a/Lib/idlelib/format.py +++ b/Lib/idlelib/format.py @@ -408,19 +408,15 @@ def do_rstrip(self, event=None): if cut < raw: text.delete('%i.%i' % (cur, cut), '%i.end' % cur) - # 'Empty' file has tk guard newline at index 'end-1c' = '1.0'. - # Only adjust ending newlines for non-empty non-shell window. - if (text.index('end-1c') > '1.0' - and not hasattr(self.editwin, 'interp')): - if text.get('end-2c') != '\n': # No user endline, add one. - text.insert('end-1c', '\n') - else: # Delete extra user endlines. - while (text.index('end-1c') > '1.0' # Stop when 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. + 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/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index bc1b09241d2ed8..a79bb515089e7b 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -651,15 +651,15 @@ def test_rstrip_lines(self): def test_rstrip_end(self): text = self.text - for t in ('', '\n', '\n\n\n'): - with self.subTest(t=t): - text.insert('1.0', t) + 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 t in ('a', 'a\n', 'a\n\n', 'a\n\n\n'): - with self.subTest(t=t): - text.delete('1.0', 'end') - text.insert('1.0', t) + 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') From 636c15fbfe7a67237376ae0274c8f30a93d67455 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Sun, 24 Nov 2019 14:20:35 -0500 Subject: [PATCH 8/8] Change doc and news. --- Doc/library/idle.rst | 3 +-- Lib/idlelib/NEWS.txt | 6 ++---- Lib/idlelib/help.html | 5 ++--- .../next/IDLE/2019-11-23-21-50-57.bpo-38862.KQ9A0m.rst | 6 ++---- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 742bc4d16cc8f5..273b5830e4293e 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -200,8 +200,7 @@ 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. Except for Shell windows, - adjust ending newlines so that the file is either empty or ends with a - newline following something other than space, tab, or newline. + 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 4a60b25f4ef0d9..5eb77398d95e60 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,10 +3,8 @@ Released on 2020-10-05? ====================================== -bpo-38862: Format menu Strip Trailing Whitespace adjusts end newlines. -Non shell windows will be either blank or end with one newline after -something other than space, tab, or newline. The result should be -ready to commit to the CPython repository. +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 diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 80541f293b0941..09dc4c57bcdc0f 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -241,8 +241,7 @@

    Edit menu (Shell and Editor)Found a bug?
    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 index e485fc28a29308..14bab9e854bdce 100644 --- 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 @@ -1,4 +1,2 @@ -Format menu Strip Trailing Whitespace adjusts ending newlines of non shell -windows so that the file is either blank or ends with one newline after -something other than space, tab, or newline. The result should be ready to -commit to the CPython repository. +'Strip Trailing Whitespace' on the Format menu removes extra newlines +at the end of non-shell files.