2323# Normally pyshell.flist.open, but there is no pyshell.flist for htest.
2424
2525class ClassBrowser :
26+ """Browse module classes and functions in IDLE.
27+ """
2628
2729 def __init__ (self , flist , name , path , _htest = False ):
2830 # XXX This API should change, if the file doesn't end in ".py"
2931 # XXX the code here is bogus!
30- """
31- _htest - bool, change box when location running htest.
32+ """Create a window for browsing a module's structure.
33+
34+ Args:
35+ flist: filelist.FileList instance used as the root for the window.
36+ name: Python module to parse.
37+ path: Module search path.
38+ _htest - bool, change box when location running htest.
39+
40+ Global variables:
41+ file_open: Function used for opening a file.
42+
43+ Instance variables:
44+ name: Module name.
45+ file: Full path and module with .py extension. Used in
46+ creating ModuleBrowserTreeItem as the rootnode for
47+ the tree and subsequently in the children.
3248 """
3349 global file_open
3450 if not _htest :
@@ -39,10 +55,12 @@ def __init__(self, flist, name, path, _htest=False):
3955 self .init (flist )
4056
4157 def close (self , event = None ):
58+ "Dismiss the window and the tree nodes."
4259 self .top .destroy ()
4360 self .node .destroy ()
4461
4562 def init (self , flist ):
63+ "Create browser tkinter widgets, including the tree."
4664 self .flist = flist
4765 # reset pyclbr
4866 pyclbr ._modules .clear ()
@@ -66,41 +84,71 @@ def init(self, flist):
6684 node .expand ()
6785
6886 def settitle (self ):
87+ "Set the window title."
6988 self .top .wm_title ("Class Browser - " + self .name )
7089 self .top .wm_iconname ("Class Browser" )
7190
7291 def rootnode (self ):
92+ "Return a ModuleBrowserTreeItem as the root of the tree."
7393 return ModuleBrowserTreeItem (self .file )
7494
7595class ModuleBrowserTreeItem (TreeItem ):
96+ """Browser tree for Python module.
97+
98+ Uses TreeItem as the basis for the structure of the tree.
99+ """
76100
77101 def __init__ (self , file ):
102+ """Create a TreeItem for the file.
103+
104+ Args:
105+ file: Full path and module name.
106+ """
78107 self .file = file
79108
80109 def GetText (self ):
110+ "Return the module name as the text string to display."
81111 return os .path .basename (self .file )
82112
83113 def GetIconName (self ):
114+ "Return the name of the icon to display."
84115 return "python"
85116
86117 def GetSubList (self ):
118+ """Return the list of ClassBrowserTreeItem items.
119+
120+ Each item returned from listclasses is the first level of
121+ classes/functions within the module.
122+ """
87123 sublist = []
88124 for name in self .listclasses ():
89125 item = ClassBrowserTreeItem (name , self .classes , self .file )
90126 sublist .append (item )
91127 return sublist
92128
93129 def OnDoubleClick (self ):
130+ "Open a module in an editor window when double clicked."
94131 if os .path .normcase (self .file [- 3 :]) != ".py" :
95132 return
96133 if not os .path .exists (self .file ):
97134 return
98135 pyshell .flist .open (self .file )
99136
100137 def IsExpandable (self ):
138+ "Return True if Python (.py) file."
101139 return os .path .normcase (self .file [- 3 :]) == ".py"
102140
103141 def listclasses (self ):
142+ """Return list of classes and functions in the module.
143+
144+ The dictionary output from pyclbr is re-written as a
145+ list of tuples in the form (lineno, name) and
146+ then sorted so that the classes and functions are
147+ processed in line number order. The returned list only
148+ contains the name and not the line number. An instance
149+ variable self.classes contains the pyclbr dictionary values,
150+ which are instances of Class and Function.
151+ """
104152 dir , file = os .path .split (self .file )
105153 name , ext = os .path .splitext (file )
106154 if os .path .normcase (ext ) != ".py" :
@@ -134,9 +182,25 @@ def listclasses(self):
134182 return list
135183
136184class ClassBrowserTreeItem (TreeItem ):
185+ """Browser tree for classes within a module.
186+
187+ Uses TreeItem as the basis for the structure of the tree.
188+ """
137189
138190 def __init__ (self , name , classes , file ):
191+ """Create a TreeItem for the class/function.
192+
193+ Args:
194+ name: Name of the class/function.
195+ classes: Dictonary of Class/Function instances from pyclbr.
196+ file: Full path and module name.
197+
198+ Instance variables:
199+ self.cl: Class/Function instance for the class/function name.
200+ self.isfunction: True if self.cl is a Function.
201+ """
139202 self .name = name
203+ # XXX - Does classes need to be an instance variable?
140204 self .classes = classes
141205 self .file = file
142206 try :
@@ -146,25 +210,33 @@ def __init__(self, name, classes, file):
146210 self .isfunction = isinstance (self .cl , pyclbr .Function )
147211
148212 def GetText (self ):
213+ "Return the name of the function/class to display."
149214 if self .isfunction :
150215 return "def " + self .name + "(...)"
151216 else :
152217 return "class " + self .name
153218
154219 def GetIconName (self ):
220+ "Return the name of the icon to display."
155221 if self .isfunction :
156222 return "python"
157223 else :
158224 return "folder"
159225
160226 def IsExpandable (self ):
227+ "Return True if this class has methods."
161228 if self .cl :
162229 try :
163230 return not not self .cl .methods
164231 except AttributeError :
165232 return False
233+ return None
166234
167235 def GetSubList (self ):
236+ """Return Class methods as a list of MethodBrowserTreeItem items.
237+
238+ Each item is a method within the class.
239+ """
168240 if not self .cl :
169241 return []
170242 sublist = []
@@ -174,6 +246,7 @@ def GetSubList(self):
174246 return sublist
175247
176248 def OnDoubleClick (self ):
249+ "Open module with file_open and position to lineno, if it exists."
177250 if not os .path .exists (self .file ):
178251 return
179252 edit = file_open (self .file )
@@ -182,6 +255,7 @@ def OnDoubleClick(self):
182255 edit .gotoline (lineno )
183256
184257 def listmethods (self ):
258+ "Return list of methods within a class sorted by lineno."
185259 if not self .cl :
186260 return []
187261 items = []
@@ -194,22 +268,37 @@ def listmethods(self):
194268 return list
195269
196270class MethodBrowserTreeItem (TreeItem ):
271+ """Browser tree for methods within a class.
272+
273+ Uses TreeItem as the basis for the structure of the tree.
274+ """
197275
198276 def __init__ (self , name , cl , file ):
277+ """Create a TreeItem for the methods.
278+
279+ Args:
280+ name: Name of the class/function.
281+ cl: pyclbr.Class instance for name.
282+ file: Full path and module name.
283+ """
199284 self .name = name
200285 self .cl = cl
201286 self .file = file
202287
203288 def GetText (self ):
289+ "Return the method name to display."
204290 return "def " + self .name + "(...)"
205291
206292 def GetIconName (self ):
207- return "python" # XXX
293+ "Return the name of the icon to display."
294+ return "python"
208295
209296 def IsExpandable (self ):
210- return 0
297+ "Return False as there are no tree items after methods."
298+ return False
211299
212300 def OnDoubleClick (self ):
301+ "Open module with file_open and position at the method start."
213302 if not os .path .exists (self .file ):
214303 return
215304 edit = file_open (self .file )
0 commit comments