ยปCore Development>Code coverage>Lib/idlelib/browser.py

Python code coverage for Lib/idlelib/browser.py

#countcontent
1n/a"""Class browser.
2n/a
3n/aXXX TO DO:
4n/a
5n/a- reparse when source changed (maybe just a button would be OK?)
6n/a (or recheck on window popup)
7n/a- add popup menu with more options (e.g. doc strings, base classes, imports)
8n/a- show function argument list? (have to do pattern matching on source)
9n/a- should the classes and methods lists also be in the module's menu bar?
10n/a- add base classes to class browser tree
11n/a"""
12n/a
13n/aimport os
14n/aimport pyclbr
15n/aimport sys
16n/a
17n/afrom idlelib.config import idleConf
18n/afrom idlelib import pyshell
19n/afrom idlelib.tree import TreeNode, TreeItem, ScrolledCanvas
20n/afrom idlelib.windows import ListedToplevel
21n/a
22n/afile_open = None # Method...Item and Class...Item use this.
23n/a# Normally pyshell.flist.open, but there is no pyshell.flist for htest.
24n/a
25n/aclass ClassBrowser:
26n/a
27n/a def __init__(self, flist, name, path, _htest=False):
28n/a # XXX This API should change, if the file doesn't end in ".py"
29n/a # XXX the code here is bogus!
30n/a """
31n/a _htest - bool, change box when location running htest.
32n/a """
33n/a global file_open
34n/a if not _htest:
35n/a file_open = pyshell.flist.open
36n/a self.name = name
37n/a self.file = os.path.join(path[0], self.name + ".py")
38n/a self._htest = _htest
39n/a self.init(flist)
40n/a
41n/a def close(self, event=None):
42n/a self.top.destroy()
43n/a self.node.destroy()
44n/a
45n/a def init(self, flist):
46n/a self.flist = flist
47n/a # reset pyclbr
48n/a pyclbr._modules.clear()
49n/a # create top
50n/a self.top = top = ListedToplevel(flist.root)
51n/a top.protocol("WM_DELETE_WINDOW", self.close)
52n/a top.bind("<Escape>", self.close)
53n/a if self._htest: # place dialog below parent if running htest
54n/a top.geometry("+%d+%d" %
55n/a (flist.root.winfo_rootx(), flist.root.winfo_rooty() + 200))
56n/a self.settitle()
57n/a top.focus_set()
58n/a # create scrolled canvas
59n/a theme = idleConf.CurrentTheme()
60n/a background = idleConf.GetHighlight(theme, 'normal')['background']
61n/a sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1)
62n/a sc.frame.pack(expand=1, fill="both")
63n/a item = self.rootnode()
64n/a self.node = node = TreeNode(sc.canvas, None, item)
65n/a node.update()
66n/a node.expand()
67n/a
68n/a def settitle(self):
69n/a self.top.wm_title("Class Browser - " + self.name)
70n/a self.top.wm_iconname("Class Browser")
71n/a
72n/a def rootnode(self):
73n/a return ModuleBrowserTreeItem(self.file)
74n/a
75n/aclass ModuleBrowserTreeItem(TreeItem):
76n/a
77n/a def __init__(self, file):
78n/a self.file = file
79n/a
80n/a def GetText(self):
81n/a return os.path.basename(self.file)
82n/a
83n/a def GetIconName(self):
84n/a return "python"
85n/a
86n/a def GetSubList(self):
87n/a sublist = []
88n/a for name in self.listclasses():
89n/a item = ClassBrowserTreeItem(name, self.classes, self.file)
90n/a sublist.append(item)
91n/a return sublist
92n/a
93n/a def OnDoubleClick(self):
94n/a if os.path.normcase(self.file[-3:]) != ".py":
95n/a return
96n/a if not os.path.exists(self.file):
97n/a return
98n/a pyshell.flist.open(self.file)
99n/a
100n/a def IsExpandable(self):
101n/a return os.path.normcase(self.file[-3:]) == ".py"
102n/a
103n/a def listclasses(self):
104n/a dir, file = os.path.split(self.file)
105n/a name, ext = os.path.splitext(file)
106n/a if os.path.normcase(ext) != ".py":
107n/a return []
108n/a try:
109n/a dict = pyclbr.readmodule_ex(name, [dir] + sys.path)
110n/a except ImportError:
111n/a return []
112n/a items = []
113n/a self.classes = {}
114n/a for key, cl in dict.items():
115n/a if cl.module == name:
116n/a s = key
117n/a if hasattr(cl, 'super') and cl.super:
118n/a supers = []
119n/a for sup in cl.super:
120n/a if type(sup) is type(''):
121n/a sname = sup
122n/a else:
123n/a sname = sup.name
124n/a if sup.module != cl.module:
125n/a sname = "%s.%s" % (sup.module, sname)
126n/a supers.append(sname)
127n/a s = s + "(%s)" % ", ".join(supers)
128n/a items.append((cl.lineno, s))
129n/a self.classes[s] = cl
130n/a items.sort()
131n/a list = []
132n/a for item, s in items:
133n/a list.append(s)
134n/a return list
135n/a
136n/aclass ClassBrowserTreeItem(TreeItem):
137n/a
138n/a def __init__(self, name, classes, file):
139n/a self.name = name
140n/a self.classes = classes
141n/a self.file = file
142n/a try:
143n/a self.cl = self.classes[self.name]
144n/a except (IndexError, KeyError):
145n/a self.cl = None
146n/a self.isfunction = isinstance(self.cl, pyclbr.Function)
147n/a
148n/a def GetText(self):
149n/a if self.isfunction:
150n/a return "def " + self.name + "(...)"
151n/a else:
152n/a return "class " + self.name
153n/a
154n/a def GetIconName(self):
155n/a if self.isfunction:
156n/a return "python"
157n/a else:
158n/a return "folder"
159n/a
160n/a def IsExpandable(self):
161n/a if self.cl:
162n/a try:
163n/a return not not self.cl.methods
164n/a except AttributeError:
165n/a return False
166n/a
167n/a def GetSubList(self):
168n/a if not self.cl:
169n/a return []
170n/a sublist = []
171n/a for name in self.listmethods():
172n/a item = MethodBrowserTreeItem(name, self.cl, self.file)
173n/a sublist.append(item)
174n/a return sublist
175n/a
176n/a def OnDoubleClick(self):
177n/a if not os.path.exists(self.file):
178n/a return
179n/a edit = file_open(self.file)
180n/a if hasattr(self.cl, 'lineno'):
181n/a lineno = self.cl.lineno
182n/a edit.gotoline(lineno)
183n/a
184n/a def listmethods(self):
185n/a if not self.cl:
186n/a return []
187n/a items = []
188n/a for name, lineno in self.cl.methods.items():
189n/a items.append((lineno, name))
190n/a items.sort()
191n/a list = []
192n/a for item, name in items:
193n/a list.append(name)
194n/a return list
195n/a
196n/aclass MethodBrowserTreeItem(TreeItem):
197n/a
198n/a def __init__(self, name, cl, file):
199n/a self.name = name
200n/a self.cl = cl
201n/a self.file = file
202n/a
203n/a def GetText(self):
204n/a return "def " + self.name + "(...)"
205n/a
206n/a def GetIconName(self):
207n/a return "python" # XXX
208n/a
209n/a def IsExpandable(self):
210n/a return 0
211n/a
212n/a def OnDoubleClick(self):
213n/a if not os.path.exists(self.file):
214n/a return
215n/a edit = file_open(self.file)
216n/a edit.gotoline(self.cl.methods[self.name])
217n/a
218n/adef _class_browser(parent): #Wrapper for htest
219n/a try:
220n/a file = __file__
221n/a except NameError:
222n/a file = sys.argv[0]
223n/a if sys.argv[1:]:
224n/a file = sys.argv[1]
225n/a else:
226n/a file = sys.argv[0]
227n/a dir, file = os.path.split(file)
228n/a name = os.path.splitext(file)[0]
229n/a flist = pyshell.PyShellFileList(parent)
230n/a global file_open
231n/a file_open = flist.open
232n/a ClassBrowser(flist, name, [dir], _htest=True)
233n/a
234n/aif __name__ == "__main__":
235n/a from idlelib.idle_test.htest import run
236n/a run(_class_browser)