gh-95411: IDLE - Enable using the module browser with .pyw files (#95397)

Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
This commit is contained in:
Erlend Egeberg Aasland 2022-07-30 06:42:13 +02:00 committed by GitHub
parent d92b19e1b5
commit 7e19e417b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 9 deletions

View file

@ -3,6 +3,8 @@ What's New in IDLE 3.11.0
Released on 2022-10-03 Released on 2022-10-03
========================= =========================
gh-95411: Enable using IDLE's module browser with .pyw files.
gh-89610: Add .pyi as a recognized extension for IDLE on macOS. This allows gh-89610: Add .pyi as a recognized extension for IDLE on macOS. This allows
opening stub files by double clicking on them in the Finder. opening stub files by double clicking on them in the Finder.

View file

@ -6,7 +6,6 @@ XXX TO DO:
(or recheck on window popup) (or recheck on window popup)
- add popup menu with more options (e.g. doc strings, base classes, imports) - add popup menu with more options (e.g. doc strings, base classes, imports)
- add base classes to class browser tree - add base classes to class browser tree
- finish removing limitation to x.py files (ModuleBrowserTreeItem)
""" """
import os import os
@ -16,12 +15,22 @@ import sys
from idlelib.config import idleConf from idlelib.config import idleConf
from idlelib import pyshell from idlelib import pyshell
from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
from idlelib.util import py_extensions
from idlelib.window import ListedToplevel from idlelib.window import ListedToplevel
file_open = None # Method...Item and Class...Item use this. file_open = None # Method...Item and Class...Item use this.
# Normally pyshell.flist.open, but there is no pyshell.flist for htest. # Normally pyshell.flist.open, but there is no pyshell.flist for htest.
# The browser depends on pyclbr and importlib which do not support .pyi files.
browseable_extension_blocklist = ('.pyi',)
def is_browseable_extension(path):
_, ext = os.path.splitext(path)
ext = os.path.normcase(ext)
return ext in py_extensions and ext not in browseable_extension_blocklist
def transform_children(child_dict, modname=None): def transform_children(child_dict, modname=None):
"""Transform a child dictionary to an ordered sequence of objects. """Transform a child dictionary to an ordered sequence of objects.
@ -76,8 +85,8 @@ class ModuleBrowser:
Instance variables: Instance variables:
name: Module name. name: Module name.
file: Full path and module with .py extension. Used in file: Full path and module with supported extension.
creating ModuleBrowserTreeItem as the rootnode for Used in creating ModuleBrowserTreeItem as the rootnode for
the tree and subsequently in the children. the tree and subsequently in the children.
""" """
self.master = master self.master = master
@ -161,22 +170,22 @@ class ModuleBrowserTreeItem(TreeItem):
def OnDoubleClick(self): def OnDoubleClick(self):
"Open a module in an editor window when double clicked." "Open a module in an editor window when double clicked."
if os.path.normcase(self.file[-3:]) != ".py": if not is_browseable_extension(self.file):
return return
if not os.path.exists(self.file): if not os.path.exists(self.file):
return return
file_open(self.file) file_open(self.file)
def IsExpandable(self): def IsExpandable(self):
"Return True if Python (.py) file." "Return True if Python file."
return os.path.normcase(self.file[-3:]) == ".py" return is_browseable_extension(self.file)
def listchildren(self): def listchildren(self):
"Return sequenced classes and functions in the module." "Return sequenced classes and functions in the module."
dir, base = os.path.split(self.file) if not is_browseable_extension(self.file):
name, ext = os.path.splitext(base)
if os.path.normcase(ext) != ".py":
return [] return []
dir, base = os.path.split(self.file)
name, _ = os.path.splitext(base)
try: try:
tree = pyclbr.readmodule_ex(name, [dir] + sys.path) tree = pyclbr.readmodule_ex(name, [dir] + sys.path)
except ImportError: except ImportError:

View file

@ -5,6 +5,7 @@ from test.support import requires
import unittest import unittest
from unittest import mock from unittest import mock
from idlelib.idle_test.mock_idle import Func from idlelib.idle_test.mock_idle import Func
from idlelib.util import py_extensions
from collections import deque from collections import deque
import os.path import os.path
@ -57,6 +58,15 @@ class ModuleBrowserTest(unittest.TestCase):
self.assertTrue(mb.node.destroy.called) self.assertTrue(mb.node.destroy.called)
del mb.top.destroy, mb.node.destroy del mb.top.destroy, mb.node.destroy
def test_is_browseable_extension(self):
path = "/path/to/file"
for ext in py_extensions:
with self.subTest(ext=ext):
filename = f'{path}{ext}'
actual = browser.is_browseable_extension(filename)
expected = ext not in browser.browseable_extension_blocklist
self.assertEqual(actual, expected)
# Nested tree same as in test_pyclbr.py except for supers on C0. C1. # Nested tree same as in test_pyclbr.py except for supers on C0. C1.
mb = pyclbr mb = pyclbr

View file

@ -0,0 +1 @@
Enable using IDLE's module browser with .pyw files.