[Python-checkins] bpo-45447: Add syntax highlighting for `.pyi` files in IDLE (GH-28950)

miss-islington webhook-mailer at python.org
Sat Feb 12 20:19:33 EST 2022


https://github.com/python/cpython/commit/1d4d44c385414042cbdd2a1e9504cd8e9d69c0ae
commit: 1d4d44c385414042cbdd2a1e9504cd8e9d69c0ae
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2022-02-12T17:19:25-08:00
summary:

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 at users.noreply.github.com>
Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu>
(cherry picked from commit 50cf4991c49e19f917305dd7b9c71085c11edddb)

Co-authored-by: Alex Waygood <Alex.Waygood at Gmail.com>
(cherry picked from commit 9fabcfbe68ff81ef5f17f86a93daf9cce9d83876)

Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu>

files:
A Lib/idlelib/idle_test/example_noext
A Lib/idlelib/idle_test/example_stub.pyi
A Lib/idlelib/idle_test/test_util.py
A Lib/idlelib/util.py
A Misc/NEWS.d/next/IDLE/2021-10-14-16-55-03.bpo-45447.FhiH5P.rst
M Lib/idlelib/NEWS.txt
M Lib/idlelib/README.txt
M Lib/idlelib/editor.py
M Lib/idlelib/idle_test/test_iomenu.py
M Lib/idlelib/iomenu.py

diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 73c8b7a32d767..5605c564f9032 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -4,6 +4,9 @@ Released on 2022-05-16
 =========================
 
 
+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 bc3d978f43f1a..8870fda315e39 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 b9cb50264ff06..3bd0a0cd39c8e 100644
--- a/Lib/idlelib/editor.py
+++ b/Lib/idlelib/editor.py
@@ -27,6 +27,7 @@
 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 @@ def ispythonsource(self, filename):
         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 0000000000000..7d2510e30bc0a
--- /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 0000000000000..a9811a78d10a6
--- /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 99f4048796712..e338893c09e6a 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 @@ def test_fixnewlines_end(self):
         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 0000000000000..20721fe980c78
--- /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 5ebf7089fb9ab..ad3109df84096 100644
--- a/Lib/idlelib/iomenu.py
+++ b/Lib/idlelib/iomenu.py
@@ -11,6 +11,9 @@
 
 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 @@ def print_window(self, event):
     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 0000000000000..5480219786bca
--- /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 0000000000000..2b5170c7631d2
--- /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.



More information about the Python-checkins mailing list