[Python-checkins] [3.6] bpo-31460: Simplify the API of IDLE's Module Browser. (GH-3842) (#3843)

Terry Jan Reedy webhook-mailer at python.org
Sat Sep 30 20:32:32 EDT 2017


https://github.com/python/cpython/commit/c8198c92320bc35b1e3de5ff0118bd8e20e8d68a
commit: c8198c92320bc35b1e3de5ff0118bd8e20e8d68a
branch: 3.6
author: Terry Jan Reedy <tjreedy at udel.edu>
committer: GitHub <noreply at github.com>
date: 2017年09月30日T20:32:29-04:00
summary:
[3.6] bpo-31460: Simplify the API of IDLE's Module Browser. (GH-3842) (#3843)
Passing a widget instead of an flist with a root widget opens the option of
creating a browser frame that is only part of a window. Passing a full file
name instead of pieces assumed to come from a .py file opens the possibility
of browsing python files that do not end in .py.
(cherry picked from commit d6bb65f)
files:
A Misc/NEWS.d/next/IDLE/2017-09-30-19-03-26.bpo-31460.HpveI6.rst
M Lib/idlelib/browser.py
M Lib/idlelib/editor.py
M Lib/idlelib/idle_test/test_browser.py
diff --git a/Lib/idlelib/browser.py b/Lib/idlelib/browser.py
index 010d8c34982..090eb2876ea 100644
--- a/Lib/idlelib/browser.py
+++ b/Lib/idlelib/browser.py
@@ -5,9 +5,8 @@
 - reparse when source changed (maybe just a button would be OK?)
 (or recheck on window popup)
 - add popup menu with more options (e.g. doc strings, base classes, imports)
-- show function argument list? (have to do pattern matching on source)
-- should the classes and methods lists also be in the module's menu bar?
 - add base classes to class browser tree
+- finish removing limitation to x.py files (ModuleBrowserTreeItem)
 """
 
 import os
@@ -58,19 +57,18 @@ def transform_children(child_dict, modname=None):
 class ModuleBrowser:
 """Browse module classes and functions in IDLE.
 """
- # This class is the base class for pathbrowser.PathBrowser.
+ # This class is also the base class for pathbrowser.PathBrowser.
 # Init and close are inherited, other methods are overriden.
+ # PathBrowser.__init__ does not call __init__ below.
 
- def __init__(self, flist, name, path, *, _htest=False, _utest=False):
- # XXX This API should change, if the file doesn't end in ".py"
- # XXX the code here is bogus!
+ def __init__(self, master, path, *, _htest=False, _utest=False):
 """Create a window for browsing a module's structure.
 
 Args:
- flist: filelist.FileList instance used as the root for the window.
- name: Python module to parse.
- path: Module search path.
- _htest - bool, change box when location running htest.
+ master: parent for widgets.
+ path: full path of file to browse.
+ _htest - bool; change box location when running htest.
+ -utest - bool; suppress contents when running unittest.
 
 Global variables:
 file_open: Function used for opening a file.
@@ -84,35 +82,36 @@ def __init__(self, flist, name, path, *, _htest=False, _utest=False):
 global file_open
 if not (_htest or _utest):
 file_open = pyshell.flist.open
- self.name = name
- self.file = os.path.join(path[0], self.name + ".py")
+ self.master = master
+ self.path = path
 self._htest = _htest
 self._utest = _utest
- self.init(flist)
+ self.init()
 
 def close(self, event=None):
 "Dismiss the window and the tree nodes."
 self.top.destroy()
 self.node.destroy()
 
- def init(self, flist):
+ def init(self):
 "Create browser tkinter widgets, including the tree."
- self.flist = flist
+ root = self.master
 # reset pyclbr
 pyclbr._modules.clear()
 # create top
- self.top = top = ListedToplevel(flist.root)
+ self.top = top = ListedToplevel(root)
 top.protocol("WM_DELETE_WINDOW", self.close)
 top.bind("<Escape>", self.close)
 if self._htest: # place dialog below parent if running htest
 top.geometry("+%d+%d" %
- (flist.root.winfo_rootx(), flist.root.winfo_rooty() + 200))
+ (root.winfo_rootx(), root.winfo_rooty() + 200))
 self.settitle()
 top.focus_set()
 # create scrolled canvas
 theme = idleConf.CurrentTheme()
 background = idleConf.GetHighlight(theme, 'normal')['background']
- sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1)
+ sc = ScrolledCanvas(top, bg=background, highlightthickness=0,
+ takefocus=1)
 sc.frame.pack(expand=1, fill="both")
 item = self.rootnode()
 self.node = node = TreeNode(sc.canvas, None, item)
@@ -122,18 +121,19 @@ def init(self, flist):
 
 def settitle(self):
 "Set the window title."
- self.top.wm_title("Module Browser - " + self.name)
+ self.top.wm_title("Module Browser - " + os.path.basename(self.path))
 self.top.wm_iconname("Module Browser")
 
 def rootnode(self):
 "Return a ModuleBrowserTreeItem as the root of the tree."
- return ModuleBrowserTreeItem(self.file)
+ return ModuleBrowserTreeItem(self.path)
 
 
 class ModuleBrowserTreeItem(TreeItem):
 """Browser tree for Python module.
 
 Uses TreeItem as the basis for the structure of the tree.
+ Used by both browsers.
 """
 
 def __init__(self, file):
@@ -170,8 +170,8 @@ def IsExpandable(self):
 
 def listchildren(self):
 "Return sequenced classes and functions in the module."
- dir, file = os.path.split(self.file)
- name, ext = os.path.splitext(file)
+ dir, base = os.path.split(self.file)
+ name, ext = os.path.splitext(base)
 if os.path.normcase(ext) != ".py":
 return []
 try:
@@ -227,25 +227,22 @@ def OnDoubleClick(self):
 
 
 def _module_browser(parent): # htest #
- try:
- file = sys.argv[1] # If pass file on command line
- # If this succeeds, unittest will fail.
- except IndexError:
+ if len(sys.argv) > 1: # If pass file on command line.
+ file = sys.argv[1]
+ else:
 file = __file__
- # Add objects for htest
+ # Add nested objects for htest.
 class Nested_in_func(TreeNode):
 def nested_in_class(): pass
 def closure():
 class Nested_in_closure: pass
- dir, file = os.path.split(file)
- name = os.path.splitext(file)[0]
- flist = pyshell.PyShellFileList(parent)
 global file_open
- file_open = flist.open
- ModuleBrowser(flist, name, [dir], _htest=True)
+ file_open = pyshell.PyShellFileList(parent).open
+ ModuleBrowser(parent, file, _htest=True)
 
 if __name__ == "__main__":
- from unittest import main
- main('idlelib.idle_test.test_browser', verbosity=2, exit=False)
+ if len(sys.argv) == 1: # If pass file on command line, unittest fails.
+ from unittest import main
+ main('idlelib.idle_test.test_browser', verbosity=2, exit=False)
 from idlelib.idle_test.htest import run
 run(_module_browser)
diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py
index 5b16ccee8a6..87d1eef01ec 100644
--- a/Lib/idlelib/editor.py
+++ b/Lib/idlelib/editor.py
@@ -664,10 +664,8 @@ def open_module_browser(self, event=None):
 filename = self.open_module()
 if filename is None:
 return "break"
- head, tail = os.path.split(filename)
- base, ext = os.path.splitext(tail)
 from idlelib import browser
- browser.ModuleBrowser(self.flist, base, [head])
+ browser.ModuleBrowser(self.root, filename)
 return "break"
 
 def open_path_browser(self, event=None):
diff --git a/Lib/idlelib/idle_test/test_browser.py b/Lib/idlelib/idle_test/test_browser.py
index b9ae0419f8c..c8184957821 100644
--- a/Lib/idlelib/idle_test/test_browser.py
+++ b/Lib/idlelib/idle_test/test_browser.py
@@ -24,30 +24,24 @@ def setUpClass(cls):
 requires('gui')
 cls.root = Tk()
 cls.root.withdraw()
- cls.flist = filelist.FileList(cls.root)
- cls.file = __file__
- cls.path = os.path.dirname(cls.file)
- cls.module = os.path.basename(cls.file).rstrip('.py')
- cls.mb = browser.ModuleBrowser(cls.flist, cls.module, [cls.path], _utest=True)
+ cls.mb = browser.ModuleBrowser(cls.root, __file__, _utest=True)
 
 @classmethod
 def tearDownClass(cls):
 cls.mb.close()
 cls.root.destroy()
- del cls.root, cls.flist, cls.mb
+ del cls.root, cls.mb
 
 def test_init(self):
 mb = self.mb
 eq = self.assertEqual
- eq(mb.name, self.module)
- eq(mb.file, self.file)
- eq(mb.flist, self.flist)
+ eq(mb.path, __file__)
 eq(pyclbr._modules, {})
 self.assertIsInstance(mb.node, TreeNode)
 
 def test_settitle(self):
 mb = self.mb
- self.assertIn(self.module, mb.top.title())
+ self.assertIn(os.path.basename(__file__), mb.top.title())
 self.assertEqual(mb.top.iconname(), 'Module Browser')
 
 def test_rootnode(self):
diff --git a/Misc/NEWS.d/next/IDLE/2017-09-30-19-03-26.bpo-31460.HpveI6.rst b/Misc/NEWS.d/next/IDLE/2017-09-30-19-03-26.bpo-31460.HpveI6.rst
new file mode 100644
index 00000000000..6492115260a
--- /dev/null
+++ b/Misc/NEWS.d/next/IDLE/2017-09-30-19-03-26.bpo-31460.HpveI6.rst
@@ -0,0 +1,6 @@
+Simplify the API of IDLE's Module Browser.
+
+Passing a widget instead of an flist with a root widget opens the option of
+creating a browser frame that is only part of a window. Passing a full file
+name instead of pieces assumed to come from a .py file opens the possibility
+of browsing python files that do not end in .py.


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /