##// END OF EJS Templates
revert fakemodule and oinspect mods, they broke unittest. monkeypatch is back
vivainio -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,52 +1,51 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Class which mimics a module.
3 Class which mimics a module.
4
4
5 Needed to allow pickle to correctly resolve namespaces during IPython
5 Needed to allow pickle to correctly resolve namespaces during IPython
6 sessions.
6 sessions.
7
7
8 $Id: FakeModule.py 1602 2006-08-11 09:19:33Z vivainio $"""
8 $Id: FakeModule.py 1625 2006-08-12 10:34:44Z vivainio $"""
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu>
11 # Copyright (C) 2002-2004 Fernando Perez. <fperez@colorado.edu>
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
15 #*****************************************************************************
16
16
17 import types
17 class FakeModule:
18
19 class FakeModule(types.ModuleType):
20 """Simple class with attribute access to fake a module.
18 """Simple class with attribute access to fake a module.
21
19
22 This is not meant to replace a module, but to allow inserting a fake
20 This is not meant to replace a module, but to allow inserting a fake
23 module in sys.modules so that systems which rely on run-time module
21 module in sys.modules so that systems which rely on run-time module
24 importing (like shelve and pickle) work correctly in interactive IPython
22 importing (like shelve and pickle) work correctly in interactive IPython
25 sessions.
23 sessions.
26
24
27 Do NOT use this code for anything other than this IPython private hack."""
25 Do NOT use this code for anything other than this IPython private hack."""
28
26
29 def __init__(self,adict):
27 def __init__(self,adict):
30 types.ModuleType.__init__(self,adict['__name__'])
28
31 # It seems pydoc (and perhaps others) needs any module instance to
29 # It seems pydoc (and perhaps others) needs any module instance to
32 # implement a __nonzero__ method, so we add it if missing:
30 # implement a __nonzero__ method, so we add it if missing:
33 if '__nonzero__' not in adict:
31 if '__nonzero__' not in adict:
34 def __nonzero__():
32 def __nonzero__():
35 return 1
33 return 1
36 adict['__nonzero__'] = __nonzero__
34 adict['__nonzero__'] = __nonzero__
37
35
36 self.__dict__ = adict
37
38 # modules should have a __file__ attribute
38 # modules should have a __file__ attribute
39 adict['__file__'] = __file__
39 adict['__file__'] = __file__
40 self.__origdict = adict
41
40
42 def __getattr__(self,key):
41 def __getattr__(self,key):
43 try:
42 try:
44 return self.__origdict[key]
43 return self.__dict__[key]
45 except KeyError, e:
44 except KeyError, e:
46 raise AttributeError("FakeModule object has no attribute %s" % e)
45 raise AttributeError("FakeModule object has no attribute %s" % e)
47
46
48 def __str__(self):
47 def __str__(self):
49 return "<IPython.FakeModule instance>"
48 return "<IPython.FakeModule instance>"
50
49
51 def __repr__(self):
50 def __repr__(self):
52 return str(self)
51 return str(self)
@@ -1,486 +1,526 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
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 1602 2006-08-11 09:19:33Z vivainio $
9 $Id: OInspect.py 1625 2006-08-12 10:34:44Z vivainio $
10 """
10 """
11
11
12 #*****************************************************************************
12 #*****************************************************************************
13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
13 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #*****************************************************************************
17 #*****************************************************************************
18
18
19 from IPython import Release
19 from IPython import Release
20 __author__ = '%s <%s>' % Release.authors['Fernando']
20 __author__ = '%s <%s>' % Release.authors['Fernando']
21 __license__ = Release.license
21 __license__ = Release.license
22
22
23 __all__ = ['Inspector','InspectColors']
23 __all__ = ['Inspector','InspectColors']
24
24
25 # stdlib modules
25 # stdlib modules
26 import __builtin__
26 import __builtin__
27 import inspect
27 import inspect
28 import linecache
28 import linecache
29 import string
29 import string
30 import StringIO
30 import StringIO
31 import types
31 import types
32 import os
32 import os
33 import sys
33 # IPython's own
34 # IPython's own
34 from IPython import PyColorize
35 from IPython import PyColorize
35 from IPython.genutils import page,indent,Term,mkdict
36 from IPython.genutils import page,indent,Term,mkdict
36 from IPython.Itpl import itpl
37 from IPython.Itpl import itpl
37 from IPython.wildcard import list_namespace
38 from IPython.wildcard import list_namespace
38 from IPython.ColorANSI import *
39 from IPython.ColorANSI import *
39
40
40 #****************************************************************************
41 #****************************************************************************
42 # HACK!!! This is a crude fix for bugs in python 2.3's inspect module. We
43 # simply monkeypatch inspect with code copied from python 2.4.
44 if sys.version_info[:2] == (2,3):
45 from inspect import ismodule, getabsfile, modulesbyfile
46 def getmodule(object):
47 """Return the module an object was defined in, or None if not found."""
48 if ismodule(object):
49 return object
50 if hasattr(object, '__module__'):
51 return sys.modules.get(object.__module__)
52 try:
53 file = getabsfile(object)
54 except TypeError:
55 return None
56 if file in modulesbyfile:
57 return sys.modules.get(modulesbyfile[file])
58 for module in sys.modules.values():
59 if hasattr(module, '__file__'):
60 modulesbyfile[
61 os.path.realpath(
62 getabsfile(module))] = module.__name__
63 if file in modulesbyfile:
64 return sys.modules.get(modulesbyfile[file])
65 main = sys.modules['__main__']
66 if not hasattr(object, '__name__'):
67 return None
68 if hasattr(main, object.__name__):
69 mainobject = getattr(main, object.__name__)
70 if mainobject is object:
71 return main
72 builtin = sys.modules['__builtin__']
73 if hasattr(builtin, object.__name__):
74 builtinobject = getattr(builtin, object.__name__)
75 if builtinobject is object:
76 return builtin
77
78 inspect.getmodule = getmodule
79
80 #****************************************************************************
41 # Builtin color schemes
81 # Builtin color schemes
42
82
43 Colors = TermColors # just a shorthand
83 Colors = TermColors # just a shorthand
44
84
45 # Build a few color schemes
85 # Build a few color schemes
46 NoColor = ColorScheme(
86 NoColor = ColorScheme(
47 'NoColor',{
87 'NoColor',{
48 'header' : Colors.NoColor,
88 'header' : Colors.NoColor,
49 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
89 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
50 } )
90 } )
51
91
52 LinuxColors = ColorScheme(
92 LinuxColors = ColorScheme(
53 'Linux',{
93 'Linux',{
54 'header' : Colors.LightRed,
94 'header' : Colors.LightRed,
55 'normal' : Colors.Normal # color off (usu. Colors.Normal)
95 'normal' : Colors.Normal # color off (usu. Colors.Normal)
56 } )
96 } )
57
97
58 LightBGColors = ColorScheme(
98 LightBGColors = ColorScheme(
59 'LightBG',{
99 'LightBG',{
60 'header' : Colors.Red,
100 'header' : Colors.Red,
61 'normal' : Colors.Normal # color off (usu. Colors.Normal)
101 'normal' : Colors.Normal # color off (usu. Colors.Normal)
62 } )
102 } )
63
103
64 # Build table of color schemes (needed by the parser)
104 # Build table of color schemes (needed by the parser)
65 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
105 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
66 'Linux')
106 'Linux')
67
107
68 #****************************************************************************
108 #****************************************************************************
69 # Auxiliary functions
109 # Auxiliary functions
70 def getdoc(obj):
110 def getdoc(obj):
71 """Stable wrapper around inspect.getdoc.
111 """Stable wrapper around inspect.getdoc.
72
112
73 This can't crash because of attribute problems.
113 This can't crash because of attribute problems.
74
114
75 It also attempts to call a getdoc() method on the given object. This
115 It also attempts to call a getdoc() method on the given object. This
76 allows objects which provide their docstrings via non-standard mechanisms
116 allows objects which provide their docstrings via non-standard mechanisms
77 (like Pyro proxies) to still be inspected by ipython's ? system."""
117 (like Pyro proxies) to still be inspected by ipython's ? system."""
78
118
79 ds = None # default return value
119 ds = None # default return value
80 try:
120 try:
81 ds = inspect.getdoc(obj)
121 ds = inspect.getdoc(obj)
82 except:
122 except:
83 # Harden against an inspect failure, which can occur with
123 # Harden against an inspect failure, which can occur with
84 # SWIG-wrapped extensions.
124 # SWIG-wrapped extensions.
85 pass
125 pass
86 # Allow objects to offer customized documentation via a getdoc method:
126 # Allow objects to offer customized documentation via a getdoc method:
87 try:
127 try:
88 ds2 = obj.getdoc()
128 ds2 = obj.getdoc()
89 except:
129 except:
90 pass
130 pass
91 else:
131 else:
92 # if we get extra info, we add it to the normal docstring.
132 # if we get extra info, we add it to the normal docstring.
93 if ds is None:
133 if ds is None:
94 ds = ds2
134 ds = ds2
95 else:
135 else:
96 ds = '%s\n%s' % (ds,ds2)
136 ds = '%s\n%s' % (ds,ds2)
97 return ds
137 return ds
98
138
99 #****************************************************************************
139 #****************************************************************************
100 # Class definitions
140 # Class definitions
101
141
102 class myStringIO(StringIO.StringIO):
142 class myStringIO(StringIO.StringIO):
103 """Adds a writeln method to normal StringIO."""
143 """Adds a writeln method to normal StringIO."""
104 def writeln(self,*arg,**kw):
144 def writeln(self,*arg,**kw):
105 """Does a write() and then a write('\n')"""
145 """Does a write() and then a write('\n')"""
106 self.write(*arg,**kw)
146 self.write(*arg,**kw)
107 self.write('\n')
147 self.write('\n')
108
148
109 class Inspector:
149 class Inspector:
110 def __init__(self,color_table,code_color_table,scheme,
150 def __init__(self,color_table,code_color_table,scheme,
111 str_detail_level=0):
151 str_detail_level=0):
112 self.color_table = color_table
152 self.color_table = color_table
113 self.parser = PyColorize.Parser(code_color_table,out='str')
153 self.parser = PyColorize.Parser(code_color_table,out='str')
114 self.format = self.parser.format
154 self.format = self.parser.format
115 self.str_detail_level = str_detail_level
155 self.str_detail_level = str_detail_level
116 self.set_active_scheme(scheme)
156 self.set_active_scheme(scheme)
117
157
118 def __getargspec(self,obj):
158 def __getargspec(self,obj):
119 """Get the names and default values of a function's arguments.
159 """Get the names and default values of a function's arguments.
120
160
121 A tuple of four things is returned: (args, varargs, varkw, defaults).
161 A tuple of four things is returned: (args, varargs, varkw, defaults).
122 'args' is a list of the argument names (it may contain nested lists).
162 'args' is a list of the argument names (it may contain nested lists).
123 'varargs' and 'varkw' are the names of the * and ** arguments or None.
163 'varargs' and 'varkw' are the names of the * and ** arguments or None.
124 'defaults' is an n-tuple of the default values of the last n arguments.
164 'defaults' is an n-tuple of the default values of the last n arguments.
125
165
126 Modified version of inspect.getargspec from the Python Standard
166 Modified version of inspect.getargspec from the Python Standard
127 Library."""
167 Library."""
128
168
129 if inspect.isfunction(obj):
169 if inspect.isfunction(obj):
130 func_obj = obj
170 func_obj = obj
131 elif inspect.ismethod(obj):
171 elif inspect.ismethod(obj):
132 func_obj = obj.im_func
172 func_obj = obj.im_func
133 else:
173 else:
134 raise TypeError, 'arg is not a Python function'
174 raise TypeError, 'arg is not a Python function'
135 args, varargs, varkw = inspect.getargs(func_obj.func_code)
175 args, varargs, varkw = inspect.getargs(func_obj.func_code)
136 return args, varargs, varkw, func_obj.func_defaults
176 return args, varargs, varkw, func_obj.func_defaults
137
177
138 def __getdef(self,obj,oname=''):
178 def __getdef(self,obj,oname=''):
139 """Return the definition header for any callable object.
179 """Return the definition header for any callable object.
140
180
141 If any exception is generated, None is returned instead and the
181 If any exception is generated, None is returned instead and the
142 exception is suppressed."""
182 exception is suppressed."""
143
183
144 try:
184 try:
145 return oname + inspect.formatargspec(*self.__getargspec(obj))
185 return oname + inspect.formatargspec(*self.__getargspec(obj))
146 except:
186 except:
147 return None
187 return None
148
188
149 def __head(self,h):
189 def __head(self,h):
150 """Return a header string with proper colors."""
190 """Return a header string with proper colors."""
151 return '%s%s%s' % (self.color_table.active_colors.header,h,
191 return '%s%s%s' % (self.color_table.active_colors.header,h,
152 self.color_table.active_colors.normal)
192 self.color_table.active_colors.normal)
153
193
154 def set_active_scheme(self,scheme):
194 def set_active_scheme(self,scheme):
155 self.color_table.set_active_scheme(scheme)
195 self.color_table.set_active_scheme(scheme)
156 self.parser.color_table.set_active_scheme(scheme)
196 self.parser.color_table.set_active_scheme(scheme)
157
197
158 def noinfo(self,msg,oname):
198 def noinfo(self,msg,oname):
159 """Generic message when no information is found."""
199 """Generic message when no information is found."""
160 print 'No %s found' % msg,
200 print 'No %s found' % msg,
161 if oname:
201 if oname:
162 print 'for %s' % oname
202 print 'for %s' % oname
163 else:
203 else:
164 print
204 print
165
205
166 def pdef(self,obj,oname=''):
206 def pdef(self,obj,oname=''):
167 """Print the definition header for any callable object.
207 """Print the definition header for any callable object.
168
208
169 If the object is a class, print the constructor information."""
209 If the object is a class, print the constructor information."""
170
210
171 if not callable(obj):
211 if not callable(obj):
172 print 'Object is not callable.'
212 print 'Object is not callable.'
173 return
213 return
174
214
175 header = ''
215 header = ''
176 if type(obj) is types.ClassType:
216 if type(obj) is types.ClassType:
177 header = self.__head('Class constructor information:\n')
217 header = self.__head('Class constructor information:\n')
178 obj = obj.__init__
218 obj = obj.__init__
179 elif type(obj) is types.InstanceType:
219 elif type(obj) is types.InstanceType:
180 obj = obj.__call__
220 obj = obj.__call__
181
221
182 output = self.__getdef(obj,oname)
222 output = self.__getdef(obj,oname)
183 if output is None:
223 if output is None:
184 self.noinfo('definition header',oname)
224 self.noinfo('definition header',oname)
185 else:
225 else:
186 print >>Term.cout, header,self.format(output),
226 print >>Term.cout, header,self.format(output),
187
227
188 def pdoc(self,obj,oname='',formatter = None):
228 def pdoc(self,obj,oname='',formatter = None):
189 """Print the docstring for any object.
229 """Print the docstring for any object.
190
230
191 Optional:
231 Optional:
192 -formatter: a function to run the docstring through for specially
232 -formatter: a function to run the docstring through for specially
193 formatted docstrings."""
233 formatted docstrings."""
194
234
195 head = self.__head # so that itpl can find it even if private
235 head = self.__head # so that itpl can find it even if private
196 ds = getdoc(obj)
236 ds = getdoc(obj)
197 if formatter:
237 if formatter:
198 ds = formatter(ds)
238 ds = formatter(ds)
199 if type(obj) is types.ClassType:
239 if type(obj) is types.ClassType:
200 init_ds = getdoc(obj.__init__)
240 init_ds = getdoc(obj.__init__)
201 output = itpl('$head("Class Docstring:")\n'
241 output = itpl('$head("Class Docstring:")\n'
202 '$indent(ds)\n'
242 '$indent(ds)\n'
203 '$head("Constructor Docstring"):\n'
243 '$head("Constructor Docstring"):\n'
204 '$indent(init_ds)')
244 '$indent(init_ds)')
205 elif type(obj) is types.InstanceType and hasattr(obj,'__call__'):
245 elif type(obj) is types.InstanceType and hasattr(obj,'__call__'):
206 call_ds = getdoc(obj.__call__)
246 call_ds = getdoc(obj.__call__)
207 if call_ds:
247 if call_ds:
208 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
248 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
209 '$head("Calling Docstring:")\n$indent(call_ds)')
249 '$head("Calling Docstring:")\n$indent(call_ds)')
210 else:
250 else:
211 output = ds
251 output = ds
212 else:
252 else:
213 output = ds
253 output = ds
214 if output is None:
254 if output is None:
215 self.noinfo('documentation',oname)
255 self.noinfo('documentation',oname)
216 return
256 return
217 page(output)
257 page(output)
218
258
219 def psource(self,obj,oname=''):
259 def psource(self,obj,oname=''):
220 """Print the source code for an object."""
260 """Print the source code for an object."""
221
261
222 # Flush the source cache because inspect can return out-of-date source
262 # Flush the source cache because inspect can return out-of-date source
223 linecache.checkcache()
263 linecache.checkcache()
224 try:
264 try:
225 src = inspect.getsource(obj)
265 src = inspect.getsource(obj)
226 except:
266 except:
227 self.noinfo('source',oname)
267 self.noinfo('source',oname)
228 else:
268 else:
229 page(self.format(src))
269 page(self.format(src))
230
270
231 def pfile(self,obj,oname=''):
271 def pfile(self,obj,oname=''):
232 """Show the whole file where an object was defined."""
272 """Show the whole file where an object was defined."""
233 try:
273 try:
234 sourcelines,lineno = inspect.getsourcelines(obj)
274 sourcelines,lineno = inspect.getsourcelines(obj)
235 except:
275 except:
236 self.noinfo('file',oname)
276 self.noinfo('file',oname)
237 else:
277 else:
238 # run contents of file through pager starting at line
278 # run contents of file through pager starting at line
239 # where the object is defined
279 # where the object is defined
240 ofile = inspect.getabsfile(obj)
280 ofile = inspect.getabsfile(obj)
241
281
242 if (ofile.endswith('.so') or ofile.endswith('.dll')):
282 if (ofile.endswith('.so') or ofile.endswith('.dll')):
243 print 'File %r is binary, not printing.' % ofile
283 print 'File %r is binary, not printing.' % ofile
244 elif not os.path.isfile(ofile):
284 elif not os.path.isfile(ofile):
245 print 'File %r does not exist, not printing.' % ofile
285 print 'File %r does not exist, not printing.' % ofile
246 else:
286 else:
247 # Print only text files, not extension binaries.
287 # Print only text files, not extension binaries.
248 page(self.format(open(ofile).read()),lineno)
288 page(self.format(open(ofile).read()),lineno)
249 #page(self.format(open(inspect.getabsfile(obj)).read()),lineno)
289 #page(self.format(open(inspect.getabsfile(obj)).read()),lineno)
250
290
251 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
291 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
252 """Show detailed information about an object.
292 """Show detailed information about an object.
253
293
254 Optional arguments:
294 Optional arguments:
255
295
256 - oname: name of the variable pointing to the object.
296 - oname: name of the variable pointing to the object.
257
297
258 - formatter: special formatter for docstrings (see pdoc)
298 - formatter: special formatter for docstrings (see pdoc)
259
299
260 - info: a structure with some information fields which may have been
300 - info: a structure with some information fields which may have been
261 precomputed already.
301 precomputed already.
262
302
263 - detail_level: if set to 1, more information is given.
303 - detail_level: if set to 1, more information is given.
264 """
304 """
265
305
266 obj_type = type(obj)
306 obj_type = type(obj)
267
307
268 header = self.__head
308 header = self.__head
269 if info is None:
309 if info is None:
270 ismagic = 0
310 ismagic = 0
271 isalias = 0
311 isalias = 0
272 ospace = ''
312 ospace = ''
273 else:
313 else:
274 ismagic = info.ismagic
314 ismagic = info.ismagic
275 isalias = info.isalias
315 isalias = info.isalias
276 ospace = info.namespace
316 ospace = info.namespace
277 # Get docstring, special-casing aliases:
317 # Get docstring, special-casing aliases:
278 if isalias:
318 if isalias:
279 ds = "Alias to the system command:\n %s" % obj[1]
319 ds = "Alias to the system command:\n %s" % obj[1]
280 else:
320 else:
281 ds = getdoc(obj)
321 ds = getdoc(obj)
282 if ds is None:
322 if ds is None:
283 ds = '<no docstring>'
323 ds = '<no docstring>'
284 if formatter is not None:
324 if formatter is not None:
285 ds = formatter(ds)
325 ds = formatter(ds)
286
326
287 # store output in a list which gets joined with \n at the end.
327 # store output in a list which gets joined with \n at the end.
288 out = myStringIO()
328 out = myStringIO()
289
329
290 string_max = 200 # max size of strings to show (snipped if longer)
330 string_max = 200 # max size of strings to show (snipped if longer)
291 shalf = int((string_max -5)/2)
331 shalf = int((string_max -5)/2)
292
332
293 if ismagic:
333 if ismagic:
294 obj_type_name = 'Magic function'
334 obj_type_name = 'Magic function'
295 elif isalias:
335 elif isalias:
296 obj_type_name = 'System alias'
336 obj_type_name = 'System alias'
297 else:
337 else:
298 obj_type_name = obj_type.__name__
338 obj_type_name = obj_type.__name__
299 out.writeln(header('Type:\t\t')+obj_type_name)
339 out.writeln(header('Type:\t\t')+obj_type_name)
300
340
301 try:
341 try:
302 bclass = obj.__class__
342 bclass = obj.__class__
303 out.writeln(header('Base Class:\t')+str(bclass))
343 out.writeln(header('Base Class:\t')+str(bclass))
304 except: pass
344 except: pass
305
345
306 # String form, but snip if too long in ? form (full in ??)
346 # String form, but snip if too long in ? form (full in ??)
307 if detail_level >= self.str_detail_level:
347 if detail_level >= self.str_detail_level:
308 try:
348 try:
309 ostr = str(obj)
349 ostr = str(obj)
310 str_head = 'String Form:'
350 str_head = 'String Form:'
311 if not detail_level and len(ostr)>string_max:
351 if not detail_level and len(ostr)>string_max:
312 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
352 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
313 ostr = ("\n" + " " * len(str_head.expandtabs())).\
353 ostr = ("\n" + " " * len(str_head.expandtabs())).\
314 join(map(string.strip,ostr.split("\n")))
354 join(map(string.strip,ostr.split("\n")))
315 if ostr.find('\n') > -1:
355 if ostr.find('\n') > -1:
316 # Print multi-line strings starting at the next line.
356 # Print multi-line strings starting at the next line.
317 str_sep = '\n'
357 str_sep = '\n'
318 else:
358 else:
319 str_sep = '\t'
359 str_sep = '\t'
320 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
360 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
321 except:
361 except:
322 pass
362 pass
323
363
324 if ospace:
364 if ospace:
325 out.writeln(header('Namespace:\t')+ospace)
365 out.writeln(header('Namespace:\t')+ospace)
326
366
327 # Length (for strings and lists)
367 # Length (for strings and lists)
328 try:
368 try:
329 length = str(len(obj))
369 length = str(len(obj))
330 out.writeln(header('Length:\t\t')+length)
370 out.writeln(header('Length:\t\t')+length)
331 except: pass
371 except: pass
332
372
333 # Filename where object was defined
373 # Filename where object was defined
334 binary_file = False
374 binary_file = False
335 try:
375 try:
336 fname = inspect.getabsfile(obj)
376 fname = inspect.getabsfile(obj)
337 if fname.endswith('<string>'):
377 if fname.endswith('<string>'):
338 fname = 'Dynamically generated function. No source code available.'
378 fname = 'Dynamically generated function. No source code available.'
339 if (fname.endswith('.so') or fname.endswith('.dll') or
379 if (fname.endswith('.so') or fname.endswith('.dll') or
340 not os.path.isfile(fname)):
380 not os.path.isfile(fname)):
341 binary_file = True
381 binary_file = True
342 out.writeln(header('File:\t\t')+fname)
382 out.writeln(header('File:\t\t')+fname)
343 except:
383 except:
344 # if anything goes wrong, we don't want to show source, so it's as
384 # if anything goes wrong, we don't want to show source, so it's as
345 # if the file was binary
385 # if the file was binary
346 binary_file = True
386 binary_file = True
347
387
348 # reconstruct the function definition and print it:
388 # reconstruct the function definition and print it:
349 defln = self.__getdef(obj,oname)
389 defln = self.__getdef(obj,oname)
350 if defln:
390 if defln:
351 out.write(header('Definition:\t')+self.format(defln))
391 out.write(header('Definition:\t')+self.format(defln))
352
392
353 # Docstrings only in detail 0 mode, since source contains them (we
393 # Docstrings only in detail 0 mode, since source contains them (we
354 # avoid repetitions). If source fails, we add them back, see below.
394 # avoid repetitions). If source fails, we add them back, see below.
355 if ds and detail_level == 0:
395 if ds and detail_level == 0:
356 out.writeln(header('Docstring:\n') + indent(ds))
396 out.writeln(header('Docstring:\n') + indent(ds))
357
397
358
398
359 # Original source code for any callable
399 # Original source code for any callable
360 if detail_level:
400 if detail_level:
361 # Flush the source cache because inspect can return out-of-date source
401 # Flush the source cache because inspect can return out-of-date source
362 linecache.checkcache()
402 linecache.checkcache()
363 source_success = False
403 source_success = False
364 try:
404 try:
365 if not binary_file:
405 if not binary_file:
366 source = self.format(inspect.getsource(obj))
406 source = self.format(inspect.getsource(obj))
367 out.write(header('Source:\n')+source.rstrip())
407 out.write(header('Source:\n')+source.rstrip())
368 source_success = True
408 source_success = True
369 except:
409 except:
370 pass
410 pass
371
411
372 if ds and not source_success:
412 if ds and not source_success:
373 out.writeln(header('Docstring [source file open failed]:\n') + indent(ds))
413 out.writeln(header('Docstring [source file open failed]:\n') + indent(ds))
374
414
375 # Constructor docstring for classes
415 # Constructor docstring for classes
376 if obj_type is types.ClassType:
416 if obj_type is types.ClassType:
377 # reconstruct the function definition and print it:
417 # reconstruct the function definition and print it:
378 try:
418 try:
379 obj_init = obj.__init__
419 obj_init = obj.__init__
380 except AttributeError:
420 except AttributeError:
381 init_def = init_ds = None
421 init_def = init_ds = None
382 else:
422 else:
383 init_def = self.__getdef(obj_init,oname)
423 init_def = self.__getdef(obj_init,oname)
384 init_ds = getdoc(obj_init)
424 init_ds = getdoc(obj_init)
385
425
386 if init_def or init_ds:
426 if init_def or init_ds:
387 out.writeln(header('\nConstructor information:'))
427 out.writeln(header('\nConstructor information:'))
388 if init_def:
428 if init_def:
389 out.write(header('Definition:\t')+ self.format(init_def))
429 out.write(header('Definition:\t')+ self.format(init_def))
390 if init_ds:
430 if init_ds:
391 out.writeln(header('Docstring:\n') + indent(init_ds))
431 out.writeln(header('Docstring:\n') + indent(init_ds))
392 # and class docstring for instances:
432 # and class docstring for instances:
393 elif obj_type is types.InstanceType:
433 elif obj_type is types.InstanceType:
394
434
395 # First, check whether the instance docstring is identical to the
435 # First, check whether the instance docstring is identical to the
396 # class one, and print it separately if they don't coincide. In
436 # class one, and print it separately if they don't coincide. In
397 # most cases they will, but it's nice to print all the info for
437 # most cases they will, but it's nice to print all the info for
398 # objects which use instance-customized docstrings.
438 # objects which use instance-customized docstrings.
399 if ds:
439 if ds:
400 class_ds = getdoc(obj.__class__)
440 class_ds = getdoc(obj.__class__)
401 if class_ds and ds != class_ds:
441 if class_ds and ds != class_ds:
402 out.writeln(header('Class Docstring:\n') +
442 out.writeln(header('Class Docstring:\n') +
403 indent(class_ds))
443 indent(class_ds))
404
444
405 # Next, try to show constructor docstrings
445 # Next, try to show constructor docstrings
406 try:
446 try:
407 init_ds = getdoc(obj.__init__)
447 init_ds = getdoc(obj.__init__)
408 except AttributeError:
448 except AttributeError:
409 init_ds = None
449 init_ds = None
410 if init_ds:
450 if init_ds:
411 out.writeln(header('Constructor Docstring:\n') +
451 out.writeln(header('Constructor Docstring:\n') +
412 indent(init_ds))
452 indent(init_ds))
413
453
414 # Call form docstring for callable instances
454 # Call form docstring for callable instances
415 if hasattr(obj,'__call__'):
455 if hasattr(obj,'__call__'):
416 out.writeln(header('Callable:\t')+'Yes')
456 out.writeln(header('Callable:\t')+'Yes')
417 call_def = self.__getdef(obj.__call__,oname)
457 call_def = self.__getdef(obj.__call__,oname)
418 if call_def is None:
458 if call_def is None:
419 out.write(header('Call def:\t')+
459 out.write(header('Call def:\t')+
420 'Calling definition not available.')
460 'Calling definition not available.')
421 else:
461 else:
422 out.write(header('Call def:\t')+self.format(call_def))
462 out.write(header('Call def:\t')+self.format(call_def))
423 call_ds = getdoc(obj.__call__)
463 call_ds = getdoc(obj.__call__)
424 if call_ds:
464 if call_ds:
425 out.writeln(header('Call docstring:\n') + indent(call_ds))
465 out.writeln(header('Call docstring:\n') + indent(call_ds))
426
466
427 # Finally send to printer/pager
467 # Finally send to printer/pager
428 output = out.getvalue()
468 output = out.getvalue()
429 if output:
469 if output:
430 page(output)
470 page(output)
431 # end pinfo
471 # end pinfo
432
472
433 def psearch(self,pattern,ns_table,ns_search=[],
473 def psearch(self,pattern,ns_table,ns_search=[],
434 ignore_case=False,show_all=False):
474 ignore_case=False,show_all=False):
435 """Search namespaces with wildcards for objects.
475 """Search namespaces with wildcards for objects.
436
476
437 Arguments:
477 Arguments:
438
478
439 - pattern: string containing shell-like wildcards to use in namespace
479 - pattern: string containing shell-like wildcards to use in namespace
440 searches and optionally a type specification to narrow the search to
480 searches and optionally a type specification to narrow the search to
441 objects of that type.
481 objects of that type.
442
482
443 - ns_table: dict of name->namespaces for search.
483 - ns_table: dict of name->namespaces for search.
444
484
445 Optional arguments:
485 Optional arguments:
446
486
447 - ns_search: list of namespace names to include in search.
487 - ns_search: list of namespace names to include in search.
448
488
449 - ignore_case(False): make the search case-insensitive.
489 - ignore_case(False): make the search case-insensitive.
450
490
451 - show_all(False): show all names, including those starting with
491 - show_all(False): show all names, including those starting with
452 underscores.
492 underscores.
453 """
493 """
454 # defaults
494 # defaults
455 type_pattern = 'all'
495 type_pattern = 'all'
456 filter = ''
496 filter = ''
457
497
458 cmds = pattern.split()
498 cmds = pattern.split()
459 len_cmds = len(cmds)
499 len_cmds = len(cmds)
460 if len_cmds == 1:
500 if len_cmds == 1:
461 # Only filter pattern given
501 # Only filter pattern given
462 filter = cmds[0]
502 filter = cmds[0]
463 elif len_cmds == 2:
503 elif len_cmds == 2:
464 # Both filter and type specified
504 # Both filter and type specified
465 filter,type_pattern = cmds
505 filter,type_pattern = cmds
466 else:
506 else:
467 raise ValueError('invalid argument string for psearch: <%s>' %
507 raise ValueError('invalid argument string for psearch: <%s>' %
468 pattern)
508 pattern)
469
509
470 # filter search namespaces
510 # filter search namespaces
471 for name in ns_search:
511 for name in ns_search:
472 if name not in ns_table:
512 if name not in ns_table:
473 raise ValueError('invalid namespace <%s>. Valid names: %s' %
513 raise ValueError('invalid namespace <%s>. Valid names: %s' %
474 (name,ns_table.keys()))
514 (name,ns_table.keys()))
475
515
476 #print 'type_pattern:',type_pattern # dbg
516 #print 'type_pattern:',type_pattern # dbg
477 search_result = []
517 search_result = []
478 for ns_name in ns_search:
518 for ns_name in ns_search:
479 ns = ns_table[ns_name]
519 ns = ns_table[ns_name]
480 tmp_res = list(list_namespace(ns,type_pattern,filter,
520 tmp_res = list(list_namespace(ns,type_pattern,filter,
481 ignore_case=ignore_case,
521 ignore_case=ignore_case,
482 show_all=show_all))
522 show_all=show_all))
483 search_result.extend(tmp_res)
523 search_result.extend(tmp_res)
484 search_result.sort()
524 search_result.sort()
485
525
486 page('\n'.join(search_result))
526 page('\n'.join(search_result))
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now