Skip to content

Commit 9fabcfb

Browse files
bpo-45447: Add syntax highlighting for .pyi files in IDLE (pythonGH-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 <[email protected]> Co-authored-by: Terry Jan Reedy <[email protected]> (cherry picked from commit 50cf499) Co-authored-by: Alex Waygood <[email protected]>
1 parent b7a65c9 commit 9fabcfb

10 files changed

+77
-3
lines changed

Lib/idlelib/NEWS.txt

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ Released on 2022-05-16
44
=========================
55

66

7+
bpo-28950: Apply IDLE syntax highlighting to `.pyi` files. Add util.py
8+
for common components. Patch by Alex Waygood and Terry Jan Reedy.
9+
710
bpo-46630: Make query dialogs on Windows start with a cursor in the
811
entry box.
912

Lib/idlelib/README.txt

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ tabbedpages.py # Define tabbed pages widget (nim).
8282
textview.py # Define read-only text widget (nim).
8383
tree.py # Define tree widget, used in browsers (nim).
8484
undo.py # Manage undo stack.
85+
util.py # Define objects imported elsewhere with no dependencies (nim)
8586
windows.py # Manage window list and define listed top level.
8687
zoomheight.py # Zoom window to full height of screen.
8788

Lib/idlelib/editor.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from idlelib import replace
2828
from idlelib import search
2929
from idlelib.tree import wheel_event
30+
from idlelib.util import py_extensions
3031
from idlelib import window
3132

3233
# The default tab setting for a Text widget, in average-width characters.
@@ -757,7 +758,7 @@ def ispythonsource(self, filename):
757758
if not filename or os.path.isdir(filename):
758759
return True
759760
base, ext = os.path.splitext(os.path.basename(filename))
760-
if os.path.normcase(ext) in (".py", ".pyw"):
761+
if os.path.normcase(ext) in py_extensions:
761762
return True
762763
line = self.text.get('1.0', '1.0 lineend')
763764
return line.startswith('#!') and 'python' in line

Lib/idlelib/idle_test/example_noext

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!usr/bin/env python
2+
3+
def example_function(some_argument):
4+
pass
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class Example:
2+
def method(self, argument1: str, argument2: list[int]) -> None: ...

Lib/idlelib/idle_test/test_iomenu.py

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"Test , coverage 17%."
22

3-
from idlelib import iomenu
3+
from idlelib import iomenu, util
44
import unittest
55
from test.support import requires
66
from tkinter import Tk
@@ -45,5 +45,27 @@ def test_fixnewlines_end(self):
4545
eq(fix(), 'a'+io.eol_convention)
4646

4747

48+
def _extension_in_filetypes(extension):
49+
return any(
50+
f'*{extension}' in filetype_tuple[1]
51+
for filetype_tuple in iomenu.IOBinding.filetypes
52+
)
53+
54+
55+
class FiletypesTest(unittest.TestCase):
56+
def test_python_source_files(self):
57+
for extension in util.py_extensions:
58+
with self.subTest(extension=extension):
59+
self.assertTrue(
60+
_extension_in_filetypes(extension)
61+
)
62+
63+
def test_text_files(self):
64+
self.assertTrue(_extension_in_filetypes('.txt'))
65+
66+
def test_all_files(self):
67+
self.assertTrue(_extension_in_filetypes(''))
68+
69+
4870
if __name__ == '__main__':
4971
unittest.main(verbosity=2)

Lib/idlelib/idle_test/test_util.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"""Test util, coverage 100%"""
2+
3+
import unittest
4+
from idlelib import util
5+
6+
7+
class UtilTest(unittest.TestCase):
8+
def test_extensions(self):
9+
for extension in {'.pyi', '.py', '.pyw'}:
10+
self.assertIn(extension, util.py_extensions)
11+
12+
13+
if __name__ == '__main__':
14+
unittest.main(verbosity=2)

Lib/idlelib/iomenu.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111

1212
import idlelib
1313
from idlelib.config import idleConf
14+
from idlelib.util import py_extensions
15+
16+
py_extensions = ' '.join("*"+ext for ext in py_extensions)
1417

1518
encoding = 'utf-8'
1619
if sys.platform == 'win32':
@@ -348,7 +351,7 @@ def print_window(self, event):
348351
savedialog = None
349352

350353
filetypes = (
351-
("Python files", "*.py *.pyw", "TEXT"),
354+
("Python files", py_extensions, "TEXT"),
352355
("Text files", "*.txt", "TEXT"),
353356
("All files", "*"),
354357
)

Lib/idlelib/util.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
Idlelib objects with no external idlelib dependencies
3+
which are needed in more than one idlelib module.
4+
5+
They are included here because
6+
a) they don't particularly belong elsewhere; or
7+
b) because inclusion here simplifies the idlelib dependency graph.
8+
9+
TODO:
10+
* Python versions (editor and help_about),
11+
* tk version and patchlevel (pyshell, help_about, maxos?, editor?),
12+
* std streams (pyshell, run),
13+
* warning stuff (pyshell, run).
14+
"""
15+
from os import path
16+
17+
# .pyw is for Windows; .pyi is for stub files.
18+
py_extensions = ('.py', '.pyw', '.pyi') # Order needed for open/save dialogs.
19+
20+
if __name__ == '__main__':
21+
from unittest import main
22+
main('idlelib.idle_test.test_util', verbosity=2)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood
2+
and Terry Jan Reedy.

0 commit comments

Comments
 (0)