Show More
@@ -6,7 +6,7 b' Uses syntax highlighting for presenting the various information elements.' | |||||
6 | Similar in spirit to the inspect module, but all calls take a name argument to |
|
6 | Similar in spirit to the inspect module, but all calls take a name argument to | |
7 | reference the name under which an object is being read. |
|
7 | reference the name under which an object is being read. | |
8 |
|
8 | |||
9 |
$Id: OInspect.py 24 |
|
9 | $Id: OInspect.py 2480 2007-07-06 19:33:43Z fperez $ | |
10 | """ |
|
10 | """ | |
11 |
|
11 | |||
12 | #***************************************************************************** |
|
12 | #***************************************************************************** | |
@@ -150,7 +150,7 b' def getsource(obj,is_binary=False):' | |||||
150 |
|
150 | |||
151 | - is_binary: whether the object is known to come from a binary source. |
|
151 | - is_binary: whether the object is known to come from a binary source. | |
152 | This implementation will skip returning any output for binary objects, but |
|
152 | This implementation will skip returning any output for binary objects, but | |
153 | custom extractors may know how to meaninfully process them.""" |
|
153 | custom extractors may know how to meaningfully process them.""" | |
154 |
|
154 | |||
155 | if is_binary: |
|
155 | if is_binary: | |
156 | return None |
|
156 | return None | |
@@ -234,10 +234,12 b' class Inspector:' | |||||
234 | return |
|
234 | return | |
235 |
|
235 | |||
236 | header = '' |
|
236 | header = '' | |
237 | if type(obj) is types.ClassType: |
|
237 | ||
|
238 | if inspect.isclass(obj): | |||
238 | header = self.__head('Class constructor information:\n') |
|
239 | header = self.__head('Class constructor information:\n') | |
239 | obj = obj.__init__ |
|
240 | obj = obj.__init__ | |
240 |
elif type(obj) is types.InstanceType |
|
241 | elif type(obj) is types.InstanceType or \ | |
|
242 | isinstance(obj,object): | |||
241 | obj = obj.__call__ |
|
243 | obj = obj.__call__ | |
242 |
|
244 | |||
243 | output = self.__getdef(obj,oname) |
|
245 | output = self.__getdef(obj,oname) | |
@@ -252,18 +254,19 b' class Inspector:' | |||||
252 | Optional: |
|
254 | Optional: | |
253 | -formatter: a function to run the docstring through for specially |
|
255 | -formatter: a function to run the docstring through for specially | |
254 | formatted docstrings.""" |
|
256 | formatted docstrings.""" | |
255 |
|
257 | |||
256 | head = self.__head # so that itpl can find it even if private |
|
258 | head = self.__head # so that itpl can find it even if private | |
257 | ds = getdoc(obj) |
|
259 | ds = getdoc(obj) | |
258 | if formatter: |
|
260 | if formatter: | |
259 | ds = formatter(ds) |
|
261 | ds = formatter(ds) | |
260 | if type(obj) is types.ClassType: |
|
262 | if inspect.isclass(obj): | |
261 | init_ds = getdoc(obj.__init__) |
|
263 | init_ds = getdoc(obj.__init__) | |
262 | output = itpl('$head("Class Docstring:")\n' |
|
264 | output = itpl('$head("Class Docstring:")\n' | |
263 | '$indent(ds)\n' |
|
265 | '$indent(ds)\n' | |
264 | '$head("Constructor Docstring"):\n' |
|
266 | '$head("Constructor Docstring"):\n' | |
265 | '$indent(init_ds)') |
|
267 | '$indent(init_ds)') | |
266 |
elif type(obj) is types.InstanceType |
|
268 | elif (type(obj) is types.InstanceType or isinstance(obj,object)) \ | |
|
269 | and hasattr(obj,'__call__'): | |||
267 | call_ds = getdoc(obj.__call__) |
|
270 | call_ds = getdoc(obj.__call__) | |
268 | if call_ds: |
|
271 | if call_ds: | |
269 | output = itpl('$head("Class Docstring:")\n$indent(ds)\n' |
|
272 | output = itpl('$head("Class Docstring:")\n$indent(ds)\n' | |
@@ -438,7 +441,7 b' class Inspector:' | |||||
438 | + indent(ds)) |
|
441 | + indent(ds)) | |
439 |
|
442 | |||
440 | # Constructor docstring for classes |
|
443 | # Constructor docstring for classes | |
441 | if obj_type is types.ClassType: |
|
444 | if inspect.isclass(obj): | |
442 | # reconstruct the function definition and print it: |
|
445 | # reconstruct the function definition and print it: | |
443 | try: |
|
446 | try: | |
444 | obj_init = obj.__init__ |
|
447 | obj_init = obj.__init__ | |
@@ -455,7 +458,8 b' class Inspector:' | |||||
455 | if init_ds: |
|
458 | if init_ds: | |
456 | out.writeln(header('Docstring:\n') + indent(init_ds)) |
|
459 | out.writeln(header('Docstring:\n') + indent(init_ds)) | |
457 | # and class docstring for instances: |
|
460 | # and class docstring for instances: | |
458 |
elif obj_type is types.InstanceType |
|
461 | elif obj_type is types.InstanceType or \ | |
|
462 | isinstance(obj,object): | |||
459 |
|
463 | |||
460 | # First, check whether the instance docstring is identical to the |
|
464 | # First, check whether the instance docstring is identical to the | |
461 | # class one, and print it separately if they don't coincide. In |
|
465 | # class one, and print it separately if they don't coincide. In |
@@ -60,7 +60,7 b' You can implement other color schemes easily, the syntax is fairly' | |||||
60 | self-explanatory. Please send back new schemes you develop to the author for |
|
60 | self-explanatory. Please send back new schemes you develop to the author for | |
61 | possible inclusion in future releases. |
|
61 | possible inclusion in future releases. | |
62 |
|
62 | |||
63 |
$Id: ultraTB.py 24 |
|
63 | $Id: ultraTB.py 2480 2007-07-06 19:33:43Z fperez $""" | |
64 |
|
64 | |||
65 | #***************************************************************************** |
|
65 | #***************************************************************************** | |
66 | # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu> |
|
66 | # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu> | |
@@ -81,6 +81,7 b' import keyword' | |||||
81 | import linecache |
|
81 | import linecache | |
82 | import os |
|
82 | import os | |
83 | import pydoc |
|
83 | import pydoc | |
|
84 | import re | |||
84 | import string |
|
85 | import string | |
85 | import sys |
|
86 | import sys | |
86 | import time |
|
87 | import time | |
@@ -88,6 +89,11 b' import tokenize' | |||||
88 | import traceback |
|
89 | import traceback | |
89 | import types |
|
90 | import types | |
90 |
|
91 | |||
|
92 | # For purposes of monkeypatching inspect to fix a bug in it. | |||
|
93 | from inspect import getsourcefile, getfile, getmodule,\ | |||
|
94 | ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode | |||
|
95 | ||||
|
96 | ||||
91 | # IPython's own modules |
|
97 | # IPython's own modules | |
92 | # Modified pdb which doesn't damage IPython's readline handling |
|
98 | # Modified pdb which doesn't damage IPython's readline handling | |
93 | from IPython import Debugger, PyColorize |
|
99 | from IPython import Debugger, PyColorize | |
@@ -117,6 +123,79 b' def inspect_error():' | |||||
117 | error('Internal Python error in the inspect module.\n' |
|
123 | error('Internal Python error in the inspect module.\n' | |
118 | 'Below is the traceback from this internal error.\n') |
|
124 | 'Below is the traceback from this internal error.\n') | |
119 |
|
125 | |||
|
126 | ||||
|
127 | def findsource(object): | |||
|
128 | """Return the entire source file and starting line number for an object. | |||
|
129 | ||||
|
130 | The argument may be a module, class, method, function, traceback, frame, | |||
|
131 | or code object. The source code is returned as a list of all the lines | |||
|
132 | in the file and the line number indexes a line in that list. An IOError | |||
|
133 | is raised if the source code cannot be retrieved. | |||
|
134 | ||||
|
135 | FIXED version with which we monkeypatch the stdlib to work around a bug.""" | |||
|
136 | ||||
|
137 | file = getsourcefile(object) or getfile(object) | |||
|
138 | module = getmodule(object, file) | |||
|
139 | if module: | |||
|
140 | lines = linecache.getlines(file, module.__dict__) | |||
|
141 | else: | |||
|
142 | lines = linecache.getlines(file) | |||
|
143 | if not lines: | |||
|
144 | raise IOError('could not get source code') | |||
|
145 | ||||
|
146 | if ismodule(object): | |||
|
147 | return lines, 0 | |||
|
148 | ||||
|
149 | if isclass(object): | |||
|
150 | name = object.__name__ | |||
|
151 | pat = re.compile(r'^(\s*)class\s*' + name + r'\b') | |||
|
152 | # make some effort to find the best matching class definition: | |||
|
153 | # use the one with the least indentation, which is the one | |||
|
154 | # that's most probably not inside a function definition. | |||
|
155 | candidates = [] | |||
|
156 | for i in range(len(lines)): | |||
|
157 | match = pat.match(lines[i]) | |||
|
158 | if match: | |||
|
159 | # if it's at toplevel, it's already the best one | |||
|
160 | if lines[i][0] == 'c': | |||
|
161 | return lines, i | |||
|
162 | # else add whitespace to candidate list | |||
|
163 | candidates.append((match.group(1), i)) | |||
|
164 | if candidates: | |||
|
165 | # this will sort by whitespace, and by line number, | |||
|
166 | # less whitespace first | |||
|
167 | candidates.sort() | |||
|
168 | return lines, candidates[0][1] | |||
|
169 | else: | |||
|
170 | raise IOError('could not find class definition') | |||
|
171 | ||||
|
172 | if ismethod(object): | |||
|
173 | object = object.im_func | |||
|
174 | if isfunction(object): | |||
|
175 | object = object.func_code | |||
|
176 | if istraceback(object): | |||
|
177 | object = object.tb_frame | |||
|
178 | if isframe(object): | |||
|
179 | object = object.f_code | |||
|
180 | if iscode(object): | |||
|
181 | if not hasattr(object, 'co_firstlineno'): | |||
|
182 | raise IOError('could not find function definition') | |||
|
183 | pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)') | |||
|
184 | pmatch = pat.match | |||
|
185 | # fperez - fix: sometimes, co_firstlineno can give a number larger than | |||
|
186 | # the length of lines, which causes an error. Safeguard against that. | |||
|
187 | lnum = min(object.co_firstlineno,len(lines))-1 | |||
|
188 | while lnum > 0: | |||
|
189 | if pmatch(lines[lnum]): break | |||
|
190 | lnum -= 1 | |||
|
191 | ||||
|
192 | return lines, lnum | |||
|
193 | raise IOError('could not find code object') | |||
|
194 | ||||
|
195 | # Monkeypatch inspect to apply our bugfix. This code only works with py25 | |||
|
196 | if sys.version_info[:2] >= (2,5): | |||
|
197 | inspect.findsource = findsource | |||
|
198 | ||||
120 | def _fixed_getinnerframes(etb, context=1,tb_offset=0): |
|
199 | def _fixed_getinnerframes(etb, context=1,tb_offset=0): | |
121 | import linecache |
|
200 | import linecache | |
122 | LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5 |
|
201 | LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5 |
@@ -1,3 +1,8 b'' | |||||
|
1 | 2007-07-06 Fernando Perez <Fernando.Perez@colorado.edu> | |||
|
2 | ||||
|
3 | * IPython/OInspect.py (Inspector.pinfo): Add support for new-style | |||
|
4 | classes in various inspector functions. | |||
|
5 | ||||
1 | 2007-06-28 Ville Vainio <vivainio@gmail.com> |
|
6 | 2007-06-28 Ville Vainio <vivainio@gmail.com> | |
2 |
|
7 | |||
3 | * shadowns.py, iplib.py, ipapi.py, OInspect.py: |
|
8 | * shadowns.py, iplib.py, ipapi.py, OInspect.py: | |
@@ -14,6 +19,11 b'' | |||||
14 |
|
19 | |||
15 | * New generic inspect_object, called on obj? and obj?? |
|
20 | * New generic inspect_object, called on obj? and obj?? | |
16 |
|
21 | |||
|
22 | 2007-06-15 Fernando Perez <Fernando.Perez@colorado.edu> | |||
|
23 | ||||
|
24 | * IPython/ultraTB.py (findsource): fix a problem with | |||
|
25 | inspect.getfile that can cause crashes during traceback construction. | |||
|
26 | ||||
17 | 2007-06-14 Ville Vainio <vivainio@gmail.com> |
|
27 | 2007-06-14 Ville Vainio <vivainio@gmail.com> | |
18 |
|
28 | |||
19 | * iplib.py (handle_auto): Try to use ascii for printing "--->" |
|
29 | * iplib.py (handle_auto): Try to use ascii for printing "--->" |
General Comments 0
You need to be logged in to leave comments.
Login now