Skip to content

Commit fa7904c

Browse files
gh-95411: IDLE - Enable using the module browser with .pyw files (GH-95397)
Co-authored-by: Terry Jan Reedy <[email protected]> (cherry picked from commit 7e19e41) Co-authored-by: Erlend Egeberg Aasland <[email protected]>
1 parent f14ced6 commit fa7904c

File tree

4 files changed

+31
-9
lines changed

4 files changed

+31
-9
lines changed

Lib/idlelib/NEWS.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ after 3.10.0 until 3.10.10?
33
Released 2023-04-03?
44
=========================
55

6+
gh-95411: Enable using IDLE's module browser with .pyw files.
7+
68
gh-89610: Add .pyi as a recognized extension for IDLE on macOS. This allows
79
opening stub files by double clicking on them in the Finder.
810

Lib/idlelib/browser.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
(or recheck on window popup)
77
- add popup menu with more options (e.g. doc strings, base classes, imports)
88
- add base classes to class browser tree
9-
- finish removing limitation to x.py files (ModuleBrowserTreeItem)
109
"""
1110

1211
import os
@@ -16,12 +15,22 @@
1615
from idlelib.config import idleConf
1716
from idlelib import pyshell
1817
from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
18+
from idlelib.util import py_extensions
1919
from idlelib.window import ListedToplevel
2020

2121

2222
file_open = None # Method...Item and Class...Item use this.
2323
# Normally pyshell.flist.open, but there is no pyshell.flist for htest.
2424

25+
# The browser depends on pyclbr and importlib which do not support .pyi files.
26+
browseable_extension_blocklist = ('.pyi',)
27+
28+
29+
def is_browseable_extension(path):
30+
_, ext = os.path.splitext(path)
31+
ext = os.path.normcase(ext)
32+
return ext in py_extensions and ext not in browseable_extension_blocklist
33+
2534

2635
def transform_children(child_dict, modname=None):
2736
"""Transform a child dictionary to an ordered sequence of objects.
@@ -76,8 +85,8 @@ def __init__(self, master, path, *, _htest=False, _utest=False):
7685
7786
Instance variables:
7887
name: Module name.
79-
file: Full path and module with .py extension. Used in
80-
creating ModuleBrowserTreeItem as the rootnode for
88+
file: Full path and module with supported extension.
89+
Used in creating ModuleBrowserTreeItem as the rootnode for
8190
the tree and subsequently in the children.
8291
"""
8392
self.master = master
@@ -161,22 +170,22 @@ def GetSubList(self):
161170

162171
def OnDoubleClick(self):
163172
"Open a module in an editor window when double clicked."
164-
if os.path.normcase(self.file[-3:]) != ".py":
173+
if not is_browseable_extension(self.file):
165174
return
166175
if not os.path.exists(self.file):
167176
return
168177
file_open(self.file)
169178

170179
def IsExpandable(self):
171-
"Return True if Python (.py) file."
172-
return os.path.normcase(self.file[-3:]) == ".py"
180+
"Return True if Python file."
181+
return is_browseable_extension(self.file)
173182

174183
def listchildren(self):
175184
"Return sequenced classes and functions in the module."
176-
dir, base = os.path.split(self.file)
177-
name, ext = os.path.splitext(base)
178-
if os.path.normcase(ext) != ".py":
185+
if not is_browseable_extension(self.file):
179186
return []
187+
dir, base = os.path.split(self.file)
188+
name, _ = os.path.splitext(base)
180189
try:
181190
tree = pyclbr.readmodule_ex(name, [dir] + sys.path)
182191
except ImportError:

Lib/idlelib/idle_test/test_browser.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import unittest
66
from unittest import mock
77
from idlelib.idle_test.mock_idle import Func
8+
from idlelib.util import py_extensions
89

910
from collections import deque
1011
import os.path
@@ -57,6 +58,15 @@ def test_close(self):
5758
self.assertTrue(mb.node.destroy.called)
5859
del mb.top.destroy, mb.node.destroy
5960

61+
def test_is_browseable_extension(self):
62+
path = "/path/to/file"
63+
for ext in py_extensions:
64+
with self.subTest(ext=ext):
65+
filename = f'{path}{ext}'
66+
actual = browser.is_browseable_extension(filename)
67+
expected = ext not in browser.browseable_extension_blocklist
68+
self.assertEqual(actual, expected)
69+
6070

6171
# Nested tree same as in test_pyclbr.py except for supers on C0. C1.
6272
mb = pyclbr
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Enable using IDLE's module browser with .pyw files.

0 commit comments

Comments
 (0)