##// END OF EJS Templates
remove OInspect monkeypatch...
vivainio -
Show More

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

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