Mercurial > cpython-lru_cache-weakref
annotate Lib/idlelib/ClassBrowser.py @ 79675:c0a2294de787 2.7
Issue #16199: Backport 2to3 typo fix from 3.2.
| author | Chris Jerdonek <chris.jerdonek@gmail.com> |
|---|---|
| date | Thu, 11 Oct 2012 16:15:46 -0700 |
| parents | eab361617f6a |
| children |
| rev | line source |
|---|---|
| 13975 | 1 """Class browser. |
| 2 | |
| 3 XXX TO DO: | |
| 4 | |
| 5 - reparse when source changed (maybe just a button would be OK?) | |
| 6 (or recheck on window popup) | |
| 7 - add popup menu with more options (e.g. doc strings, base classes, imports) | |
| 8 - show function argument list? (have to do pattern matching on source) | |
| 9 - should the classes and methods lists also be in the module's menu bar? | |
| 10 - add base classes to class browser tree | |
| 11 """ | |
| 12 | |
| 13 import os | |
| 14 import sys | |
| 15 import pyclbr | |
| 16 | |
|
60144
eab361617f6a
#7092: Fix additional "-3" warnings in the idlelib package, and convert to absolute imports.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
31625
diff
changeset
|
17 from idlelib import PyShell |
|
eab361617f6a
#7092: Fix additional "-3" warnings in the idlelib package, and convert to absolute imports.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
31625
diff
changeset
|
18 from idlelib.WindowList import ListedToplevel |
|
eab361617f6a
#7092: Fix additional "-3" warnings in the idlelib package, and convert to absolute imports.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
31625
diff
changeset
|
19 from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas |
|
eab361617f6a
#7092: Fix additional "-3" warnings in the idlelib package, and convert to absolute imports.
Florent Xicluna <florent.xicluna@gmail.com>
parents:
31625
diff
changeset
|
20 from idlelib.configHandler import idleConf |
| 13975 | 21 |
| 22 class ClassBrowser: | |
| 23 | |
| 24 def __init__(self, flist, name, path): | |
| 25 # XXX This API should change, if the file doesn't end in ".py" | |
| 26 # XXX the code here is bogus! | |
| 27 self.name = name | |
| 28 self.file = os.path.join(path[0], self.name + ".py") | |
| 29 self.init(flist) | |
| 30 | |
| 31 def close(self, event=None): | |
| 32 self.top.destroy() | |
| 33 self.node.destroy() | |
| 34 | |
| 35 def init(self, flist): | |
| 36 self.flist = flist | |
| 37 # reset pyclbr | |
| 38 pyclbr._modules.clear() | |
| 39 # create top | |
| 40 self.top = top = ListedToplevel(flist.root) | |
| 41 top.protocol("WM_DELETE_WINDOW", self.close) | |
| 42 top.bind("<Escape>", self.close) | |
| 43 self.settitle() | |
| 44 top.focus_set() | |
| 45 # create scrolled canvas | |
|
31625
1b02c77cdcfe
Add a highlight theme for builtin keywords. Python Patch 805830 Nigel Rowe
Kurt B. Kaiser <kbk@shore.net>
parents:
27311
diff
changeset
|
46 theme = idleConf.GetOption('main','Theme','name') |
|
1b02c77cdcfe
Add a highlight theme for builtin keywords. Python Patch 805830 Nigel Rowe
Kurt B. Kaiser <kbk@shore.net>
parents:
27311
diff
changeset
|
47 background = idleConf.GetHighlight(theme, 'normal')['background'] |
|
1b02c77cdcfe
Add a highlight theme for builtin keywords. Python Patch 805830 Nigel Rowe
Kurt B. Kaiser <kbk@shore.net>
parents:
27311
diff
changeset
|
48 sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1) |
| 13975 | 49 sc.frame.pack(expand=1, fill="both") |
| 50 item = self.rootnode() | |
| 51 self.node = node = TreeNode(sc.canvas, None, item) | |
| 52 node.update() | |
| 53 node.expand() | |
| 54 | |
| 55 def settitle(self): | |
| 56 self.top.wm_title("Class Browser - " + self.name) | |
| 57 self.top.wm_iconname("Class Browser") | |
| 58 | |
| 59 def rootnode(self): | |
| 60 return ModuleBrowserTreeItem(self.file) | |
| 61 | |
| 62 class ModuleBrowserTreeItem(TreeItem): | |
| 63 | |
| 64 def __init__(self, file): | |
| 65 self.file = file | |
| 66 | |
| 67 def GetText(self): | |
| 68 return os.path.basename(self.file) | |
| 69 | |
| 70 def GetIconName(self): | |
| 71 return "python" | |
| 72 | |
| 73 def GetSubList(self): | |
| 74 sublist = [] | |
| 75 for name in self.listclasses(): | |
| 76 item = ClassBrowserTreeItem(name, self.classes, self.file) | |
| 77 sublist.append(item) | |
| 78 return sublist | |
| 79 | |
| 80 def OnDoubleClick(self): | |
| 81 if os.path.normcase(self.file[-3:]) != ".py": | |
| 82 return | |
| 83 if not os.path.exists(self.file): | |
| 84 return | |
| 85 PyShell.flist.open(self.file) | |
| 86 | |
| 87 def IsExpandable(self): | |
| 88 return os.path.normcase(self.file[-3:]) == ".py" | |
|
18531
ec9aa0dc8b73
py-cvs-rel2_1 (Rev 1.12) merge - whitespace normalization
Kurt B. Kaiser <kbk@shore.net>
parents:
13975
diff
changeset
|
89 |
| 13975 | 90 def listclasses(self): |
| 91 dir, file = os.path.split(self.file) | |
| 92 name, ext = os.path.splitext(file) | |
| 93 if os.path.normcase(ext) != ".py": | |
| 94 return [] | |
| 95 try: | |
| 96 dict = pyclbr.readmodule_ex(name, [dir] + sys.path) | |
| 97 except ImportError, msg: | |
| 98 return [] | |
| 99 items = [] | |
| 100 self.classes = {} | |
| 101 for key, cl in dict.items(): | |
| 102 if cl.module == name: | |
| 103 s = key | |
|
27292
d7f80028301d
SF bug #668906: class browser raises AttributeError
Raymond Hettinger <python@rcn.com>
parents:
26510
diff
changeset
|
104 if hasattr(cl, 'super') and cl.super: |
| 13975 | 105 supers = [] |
| 106 for sup in cl.super: | |
| 107 if type(sup) is type(''): | |
| 108 sname = sup | |
| 109 else: | |
| 110 sname = sup.name | |
| 111 if sup.module != cl.module: | |
| 112 sname = "%s.%s" % (sup.module, sname) | |
| 113 supers.append(sname) | |
| 25283 | 114 s = s + "(%s)" % ", ".join(supers) |
| 13975 | 115 items.append((cl.lineno, s)) |
| 116 self.classes[s] = cl | |
| 117 items.sort() | |
| 118 list = [] | |
| 119 for item, s in items: | |
| 120 list.append(s) | |
| 121 return list | |
| 122 | |
| 123 class ClassBrowserTreeItem(TreeItem): | |
| 124 | |
| 125 def __init__(self, name, classes, file): | |
| 126 self.name = name | |
| 127 self.classes = classes | |
| 128 self.file = file | |
| 129 try: | |
| 130 self.cl = self.classes[self.name] | |
| 131 except (IndexError, KeyError): | |
| 132 self.cl = None | |
| 133 self.isfunction = isinstance(self.cl, pyclbr.Function) | |
| 134 | |
| 135 def GetText(self): | |
| 136 if self.isfunction: | |
| 137 return "def " + self.name + "(...)" | |
| 138 else: | |
| 139 return "class " + self.name | |
| 140 | |
| 141 def GetIconName(self): | |
| 142 if self.isfunction: | |
| 143 return "python" | |
| 144 else: | |
| 145 return "folder" | |
| 146 | |
| 147 def IsExpandable(self): | |
| 148 if self.cl: | |
|
27311
eaa612a41dd0
...and the old pyclbr.py faked Function instances with Class instances
Kurt B. Kaiser <kbk@shore.net>
parents:
27292
diff
changeset
|
149 try: |
|
eaa612a41dd0
...and the old pyclbr.py faked Function instances with Class instances
Kurt B. Kaiser <kbk@shore.net>
parents:
27292
diff
changeset
|
150 return not not self.cl.methods |
|
eaa612a41dd0
...and the old pyclbr.py faked Function instances with Class instances
Kurt B. Kaiser <kbk@shore.net>
parents:
27292
diff
changeset
|
151 except AttributeError: |
|
eaa612a41dd0
...and the old pyclbr.py faked Function instances with Class instances
Kurt B. Kaiser <kbk@shore.net>
parents:
27292
diff
changeset
|
152 return False |
| 13975 | 153 |
| 154 def GetSubList(self): | |
| 155 if not self.cl: | |
| 156 return [] | |
| 157 sublist = [] | |
| 158 for name in self.listmethods(): | |
| 159 item = MethodBrowserTreeItem(name, self.cl, self.file) | |
| 160 sublist.append(item) | |
| 161 return sublist | |
| 162 | |
| 163 def OnDoubleClick(self): | |
| 164 if not os.path.exists(self.file): | |
| 165 return | |
| 166 edit = PyShell.flist.open(self.file) | |
| 167 if hasattr(self.cl, 'lineno'): | |
| 168 lineno = self.cl.lineno | |
| 169 edit.gotoline(lineno) | |
| 170 | |
| 171 def listmethods(self): | |
| 172 if not self.cl: | |
| 173 return [] | |
| 174 items = [] | |
| 175 for name, lineno in self.cl.methods.items(): | |
| 176 items.append((lineno, name)) | |
| 177 items.sort() | |
| 178 list = [] | |
| 179 for item, name in items: | |
| 180 list.append(name) | |
| 181 return list | |
| 182 | |
| 183 class MethodBrowserTreeItem(TreeItem): | |
| 184 | |
| 185 def __init__(self, name, cl, file): | |
| 186 self.name = name | |
| 187 self.cl = cl | |
| 188 self.file = file | |
| 189 | |
| 190 def GetText(self): | |
| 191 return "def " + self.name + "(...)" | |
| 192 | |
| 193 def GetIconName(self): | |
| 194 return "python" # XXX | |
| 195 | |
| 196 def IsExpandable(self): | |
| 197 return 0 | |
| 198 | |
| 199 def OnDoubleClick(self): | |
| 200 if not os.path.exists(self.file): | |
| 201 return | |
| 202 edit = PyShell.flist.open(self.file) | |
| 203 edit.gotoline(self.cl.methods[self.name]) | |
| 204 | |
| 205 def main(): | |
| 206 try: | |
| 207 file = __file__ | |
| 208 except NameError: | |
| 209 file = sys.argv[0] | |
| 210 if sys.argv[1:]: | |
| 211 file = sys.argv[1] | |
| 212 else: | |
| 213 file = sys.argv[0] | |
| 214 dir, file = os.path.split(file) | |
| 215 name = os.path.splitext(file)[0] | |
| 216 ClassBrowser(PyShell.flist, name, [dir]) | |
| 217 if sys.stdin is sys.__stdin__: | |
| 218 mainloop() | |
| 219 | |
| 220 if __name__ == "__main__": | |
| 221 main() |
