[Python-checkins] gh-95411: IDLE - Enable using the module browser with .pyw files (GH-95397)

miss-islington webhook-mailer at python.org
Sat Jul 30 01:09:39 EDT 2022


https://github.com/python/cpython/commit/a459ee9543243299386f594fc10bb0b206ec5530
commit: a459ee9543243299386f594fc10bb0b206ec5530
branch: 3.11
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-07-29T22:09:32-07:00
summary:

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


Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu>
(cherry picked from commit 7e19e417b5df765dabab8d6550ec0e9d897c573e)

Co-authored-by: Erlend Egeberg Aasland <erlend.aasland at protonmail.com>

files:
A Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst
M Lib/idlelib/NEWS.txt
M Lib/idlelib/browser.py
M Lib/idlelib/idle_test/test_browser.py

diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index ffb090aa45a46..85116b5b6b931 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -3,6 +3,8 @@ What's New in IDLE 3.11.0
 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
 opening stub files by double clicking on them in the Finder.
 
diff --git a/Lib/idlelib/browser.py b/Lib/idlelib/browser.py
index 3c3a53a6599a7..10d9a7261113e 100644
--- a/Lib/idlelib/browser.py
+++ b/Lib/idlelib/browser.py
@@ -6,7 +6,6 @@
     (or recheck on window popup)
 - add popup menu with more options (e.g. doc strings, base classes, imports)
 - add base classes to class browser tree
-- finish removing limitation to x.py files (ModuleBrowserTreeItem)
 """
 
 import os
@@ -16,12 +15,22 @@
 from idlelib.config import idleConf
 from idlelib import pyshell
 from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
+from idlelib.util import py_extensions
 from idlelib.window import ListedToplevel
 
 
 file_open = None  # Method...Item and Class...Item use this.
 # 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):
     """Transform a child dictionary to an ordered sequence of objects.
@@ -76,8 +85,8 @@ def __init__(self, master, path, *, _htest=False, _utest=False):
 
         Instance variables:
             name: Module name.
-            file: Full path and module with .py extension.  Used in
-                creating ModuleBrowserTreeItem as the rootnode for
+            file: Full path and module with supported extension.
+                Used in creating ModuleBrowserTreeItem as the rootnode for
                 the tree and subsequently in the children.
         """
         self.master = master
@@ -161,22 +170,22 @@ def GetSubList(self):
 
     def OnDoubleClick(self):
         "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
         if not os.path.exists(self.file):
             return
         file_open(self.file)
 
     def IsExpandable(self):
-        "Return True if Python (.py) file."
-        return os.path.normcase(self.file[-3:]) == ".py"
+        "Return True if Python file."
+        return is_browseable_extension(self.file)
 
     def listchildren(self):
         "Return sequenced classes and functions in the module."
-        dir, base = os.path.split(self.file)
-        name, ext = os.path.splitext(base)
-        if os.path.normcase(ext) != ".py":
+        if not is_browseable_extension(self.file):
             return []
+        dir, base = os.path.split(self.file)
+        name, _ = os.path.splitext(base)
         try:
             tree = pyclbr.readmodule_ex(name, [dir] + sys.path)
         except ImportError:
diff --git a/Lib/idlelib/idle_test/test_browser.py b/Lib/idlelib/idle_test/test_browser.py
index 03a50f22ca1e8..343d50a6e37bd 100644
--- a/Lib/idlelib/idle_test/test_browser.py
+++ b/Lib/idlelib/idle_test/test_browser.py
@@ -5,6 +5,7 @@
 import unittest
 from unittest import mock
 from idlelib.idle_test.mock_idle import Func
+from idlelib.util import py_extensions
 
 from collections import deque
 import os.path
@@ -57,6 +58,15 @@ def test_close(self):
         self.assertTrue(mb.node.destroy.called)
         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.
 mb = pyclbr
diff --git a/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst b/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst
new file mode 100644
index 0000000000000..94ca8b2c2ea95
--- /dev/null
+++ b/Misc/NEWS.d/next/IDLE/2022-07-29-11-08-52.gh-issue-95411.dazlqH.rst
@@ -0,0 +1 @@
+Enable using IDLE's module browser with .pyw files.



More information about the Python-checkins mailing list