From 50cf4991c49e19f917305dd7b9c71085c11edddb Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 13 Feb 2022 00:04:48 +0000 Subject: bpo-45447: Add syntax highlighting for `.pyi` files in IDLE (GH-28950) Also add .pyi to the python extensions in the "File-open" and "File-save" dialogues. Add util.py to contain objects that are used in multiple idlelib modules and have no dependencies on any of them. Co-authored-by: E-Paine <63801254+E-Paine@users.noreply.github.com> Co-authored-by: Terry Jan Reedy --- Doc/whatsnew/3.11.rst | 6 ++++++ Lib/idlelib/NEWS.txt | 3 +++ Lib/idlelib/README.txt | 1 + Lib/idlelib/editor.py | 3 ++- Lib/idlelib/idle_test/example_noext | 4 ++++ Lib/idlelib/idle_test/example_stub.pyi | 2 ++ Lib/idlelib/idle_test/test_iomenu.py | 24 +++++++++++++++++++++- Lib/idlelib/idle_test/test_util.py | 14 +++++++++++++ Lib/idlelib/iomenu.py | 5 ++++- Lib/idlelib/util.py | 22 ++++++++++++++++++++ .../IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst | 2 ++ 11 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 Lib/idlelib/idle_test/example_noext create mode 100644 Lib/idlelib/idle_test/example_stub.pyi create mode 100644 Lib/idlelib/idle_test/test_util.py create mode 100644 Lib/idlelib/util.py create mode 100644 Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 5e7c89e..43a112a 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -228,6 +228,12 @@ fractions (Contributed by Mark Dickinson in :issue:`44547`.) +IDLE and idlelib +---------------- + +* IDLE now applies syntax highlighting to `.pyi` files. (Contributed by Alex + Waygood and Terry Jan Reedy in :issue:`45447`.) + inspect ------- * Add :func:`inspect.getmembers_static`: return all members without diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 0bfadfd..441ec41 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -4,6 +4,9 @@ Released on 2022-10-03 ========================= +bpo-28950: Apply IDLE syntax highlighting to `.pyi` files. Add util.py +for common components. Patch by Alex Waygood and Terry Jan Reedy. + bpo-46630: Make query dialogs on Windows start with a cursor in the entry box. diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index bc3d978..8870fda 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -82,6 +82,7 @@ tabbedpages.py # Define tabbed pages widget (nim). textview.py # Define read-only text widget (nim). tree.py # Define tree widget, used in browsers (nim). undo.py # Manage undo stack. +util.py # Define objects imported elsewhere with no dependencies (nim) windows.py # Manage window list and define listed top level. zoomheight.py # Zoom window to full height of screen. diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index fcc8a3f..6c52efd 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -27,6 +27,7 @@ from idlelib import query from idlelib import replace from idlelib import search from idlelib.tree import wheel_event +from idlelib.util import py_extensions from idlelib import window # The default tab setting for a Text widget, in average-width characters. @@ -757,7 +758,7 @@ class EditorWindow: if not filename or os.path.isdir(filename): return True base, ext = os.path.splitext(os.path.basename(filename)) - if os.path.normcase(ext) in (".py", ".pyw"): + if os.path.normcase(ext) in py_extensions: return True line = self.text.get('1.0', '1.0 lineend') return line.startswith('#!') and 'python' in line diff --git a/Lib/idlelib/idle_test/example_noext b/Lib/idlelib/idle_test/example_noext new file mode 100644 index 0000000..7d2510e --- /dev/null +++ b/Lib/idlelib/idle_test/example_noext @@ -0,0 +1,4 @@ +#!usr/bin/env python + +def example_function(some_argument): + pass diff --git a/Lib/idlelib/idle_test/example_stub.pyi b/Lib/idlelib/idle_test/example_stub.pyi new file mode 100644 index 0000000..a9811a7 --- /dev/null +++ b/Lib/idlelib/idle_test/example_stub.pyi @@ -0,0 +1,2 @@ +class Example: + def method(self, argument1: str, argument2: list[int]) -> None: ... diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index 99f4048..e338893 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -1,6 +1,6 @@ "Test , coverage 17%." -from idlelib import iomenu +from idlelib import iomenu, util import unittest from test.support import requires from tkinter import Tk @@ -45,5 +45,27 @@ class IOBindingTest(unittest.TestCase): eq(fix(), 'a'+io.eol_convention) +def _extension_in_filetypes(extension): + return any( + f'*{extension}' in filetype_tuple[1] + for filetype_tuple in iomenu.IOBinding.filetypes + ) + + +class FiletypesTest(unittest.TestCase): + def test_python_source_files(self): + for extension in util.py_extensions: + with self.subTest(extension=extension): + self.assertTrue( + _extension_in_filetypes(extension) + ) + + def test_text_files(self): + self.assertTrue(_extension_in_filetypes('.txt')) + + def test_all_files(self): + self.assertTrue(_extension_in_filetypes('')) + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_util.py b/Lib/idlelib/idle_test/test_util.py new file mode 100644 index 0000000..20721fe --- /dev/null +++ b/Lib/idlelib/idle_test/test_util.py @@ -0,0 +1,14 @@ +"""Test util, coverage 100%""" + +import unittest +from idlelib import util + + +class UtilTest(unittest.TestCase): + def test_extensions(self): + for extension in {'.pyi', '.py', '.pyw'}: + self.assertIn(extension, util.py_extensions) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/iomenu.py b/Lib/idlelib/iomenu.py index 5ebf708..ad3109d 100644 --- a/Lib/idlelib/iomenu.py +++ b/Lib/idlelib/iomenu.py @@ -11,6 +11,9 @@ from tkinter.simpledialog import askstring import idlelib from idlelib.config import idleConf +from idlelib.util import py_extensions + +py_extensions = ' '.join("*"+ext for ext in py_extensions) encoding = 'utf-8' if sys.platform == 'win32': @@ -348,7 +351,7 @@ class IOBinding: savedialog = None filetypes = ( - ("Python files", "*.py *.pyw", "TEXT"), + ("Python files", py_extensions, "TEXT"), ("Text files", "*.txt", "TEXT"), ("All files", "*"), ) diff --git a/Lib/idlelib/util.py b/Lib/idlelib/util.py new file mode 100644 index 0000000..5480219 --- /dev/null +++ b/Lib/idlelib/util.py @@ -0,0 +1,22 @@ +""" +Idlelib objects with no external idlelib dependencies +which are needed in more than one idlelib module. + +They are included here because + a) they don't particularly belong elsewhere; or + b) because inclusion here simplifies the idlelib dependency graph. + +TODO: + * Python versions (editor and help_about), + * tk version and patchlevel (pyshell, help_about, maxos?, editor?), + * std streams (pyshell, run), + * warning stuff (pyshell, run). +""" +from os import path + +# .pyw is for Windows; .pyi is for stub files. +py_extensions = ('.py', '.pyw', '.pyi') # Order needed for open/save dialogs. + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_util', verbosity=2) diff --git a/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst b/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst new file mode 100644 index 0000000..2b5170c --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst @@ -0,0 +1,2 @@ +Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood +and Terry Jan Reedy. -- cgit v0.12