##// END OF EJS Templates
Merge pull request #1845 from fperez/magic_inspect...
Fernando Perez -
r7433:44b81218 merge
parent child Browse files
Show More
@@ -1,700 +1,700 b''
1 """Implementation of namespace-related magic functions.
1 """Implementation of namespace-related magic functions.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
4 # Copyright (c) 2012 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 # Stdlib
15 # Stdlib
16 import gc
16 import gc
17 import re
17 import re
18 import sys
18 import sys
19
19
20 # Our own packages
20 # Our own packages
21 from IPython.core import page
21 from IPython.core import page
22 from IPython.core.error import StdinNotImplementedError
22 from IPython.core.error import StdinNotImplementedError
23 from IPython.core.magic import Magics, magics_class, line_magic
23 from IPython.core.magic import Magics, magics_class, line_magic
24 from IPython.testing.skipdoctest import skip_doctest
24 from IPython.testing.skipdoctest import skip_doctest
25 from IPython.utils.encoding import DEFAULT_ENCODING
25 from IPython.utils.encoding import DEFAULT_ENCODING
26 from IPython.utils.path import get_py_filename
26 from IPython.utils.path import get_py_filename
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Magic implementation classes
29 # Magic implementation classes
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 @magics_class
32 @magics_class
33 class NamespaceMagics(Magics):
33 class NamespaceMagics(Magics):
34 """Magics to manage various aspects of the user's namespace.
34 """Magics to manage various aspects of the user's namespace.
35
35
36 These include listing variables, introspecting into them, etc.
36 These include listing variables, introspecting into them, etc.
37 """
37 """
38
38
39 @line_magic
39 @line_magic
40 def pinfo(self, parameter_s='', namespaces=None):
40 def pinfo(self, parameter_s='', namespaces=None):
41 """Provide detailed information about an object.
41 """Provide detailed information about an object.
42
42
43 '%pinfo object' is just a synonym for object? or ?object."""
43 '%pinfo object' is just a synonym for object? or ?object."""
44
44
45 #print 'pinfo par: <%s>' % parameter_s # dbg
45 #print 'pinfo par: <%s>' % parameter_s # dbg
46 # detail_level: 0 -> obj? , 1 -> obj??
46 # detail_level: 0 -> obj? , 1 -> obj??
47 detail_level = 0
47 detail_level = 0
48 # We need to detect if we got called as 'pinfo pinfo foo', which can
48 # We need to detect if we got called as 'pinfo pinfo foo', which can
49 # happen if the user types 'pinfo foo?' at the cmd line.
49 # happen if the user types 'pinfo foo?' at the cmd line.
50 pinfo,qmark1,oname,qmark2 = \
50 pinfo,qmark1,oname,qmark2 = \
51 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
51 re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
52 if pinfo or qmark1 or qmark2:
52 if pinfo or qmark1 or qmark2:
53 detail_level = 1
53 detail_level = 1
54 if "*" in oname:
54 if "*" in oname:
55 self.psearch(oname)
55 self.psearch(oname)
56 else:
56 else:
57 self.shell._inspect('pinfo', oname, detail_level=detail_level,
57 self.shell._inspect('pinfo', oname, detail_level=detail_level,
58 namespaces=namespaces)
58 namespaces=namespaces)
59
59
60 @line_magic
60 @line_magic
61 def pinfo2(self, parameter_s='', namespaces=None):
61 def pinfo2(self, parameter_s='', namespaces=None):
62 """Provide extra detailed information about an object.
62 """Provide extra detailed information about an object.
63
63
64 '%pinfo2 object' is just a synonym for object?? or ??object."""
64 '%pinfo2 object' is just a synonym for object?? or ??object."""
65 self.shell._inspect('pinfo', parameter_s, detail_level=1,
65 self.shell._inspect('pinfo', parameter_s, detail_level=1,
66 namespaces=namespaces)
66 namespaces=namespaces)
67
67
68 @skip_doctest
68 @skip_doctest
69 @line_magic
69 @line_magic
70 def pdef(self, parameter_s='', namespaces=None):
70 def pdef(self, parameter_s='', namespaces=None):
71 """Print the definition header for any callable object.
71 """Print the definition header for any callable object.
72
72
73 If the object is a class, print the constructor information.
73 If the object is a class, print the constructor information.
74
74
75 Examples
75 Examples
76 --------
76 --------
77 ::
77 ::
78
78
79 In [3]: %pdef urllib.urlopen
79 In [3]: %pdef urllib.urlopen
80 urllib.urlopen(url, data=None, proxies=None)
80 urllib.urlopen(url, data=None, proxies=None)
81 """
81 """
82 self._inspect('pdef',parameter_s, namespaces)
82 self.shell._inspect('pdef',parameter_s, namespaces)
83
83
84 @line_magic
84 @line_magic
85 def pdoc(self, parameter_s='', namespaces=None):
85 def pdoc(self, parameter_s='', namespaces=None):
86 """Print the docstring for an object.
86 """Print the docstring for an object.
87
87
88 If the given object is a class, it will print both the class and the
88 If the given object is a class, it will print both the class and the
89 constructor docstrings."""
89 constructor docstrings."""
90 self._inspect('pdoc',parameter_s, namespaces)
90 self.shell._inspect('pdoc',parameter_s, namespaces)
91
91
92 @line_magic
92 @line_magic
93 def psource(self, parameter_s='', namespaces=None):
93 def psource(self, parameter_s='', namespaces=None):
94 """Print (or run through pager) the source code for an object."""
94 """Print (or run through pager) the source code for an object."""
95 self._inspect('psource',parameter_s, namespaces)
95 self.shell._inspect('psource',parameter_s, namespaces)
96
96
97 @line_magic
97 @line_magic
98 def pfile(self, parameter_s=''):
98 def pfile(self, parameter_s=''):
99 """Print (or run through pager) the file where an object is defined.
99 """Print (or run through pager) the file where an object is defined.
100
100
101 The file opens at the line where the object definition begins. IPython
101 The file opens at the line where the object definition begins. IPython
102 will honor the environment variable PAGER if set, and otherwise will
102 will honor the environment variable PAGER if set, and otherwise will
103 do its best to print the file in a convenient form.
103 do its best to print the file in a convenient form.
104
104
105 If the given argument is not an object currently defined, IPython will
105 If the given argument is not an object currently defined, IPython will
106 try to interpret it as a filename (automatically adding a .py extension
106 try to interpret it as a filename (automatically adding a .py extension
107 if needed). You can thus use %pfile as a syntax highlighting code
107 if needed). You can thus use %pfile as a syntax highlighting code
108 viewer."""
108 viewer."""
109
109
110 # first interpret argument as an object name
110 # first interpret argument as an object name
111 out = self._inspect('pfile',parameter_s)
111 out = self.shell._inspect('pfile',parameter_s)
112 # if not, try the input as a filename
112 # if not, try the input as a filename
113 if out == 'not found':
113 if out == 'not found':
114 try:
114 try:
115 filename = get_py_filename(parameter_s)
115 filename = get_py_filename(parameter_s)
116 except IOError,msg:
116 except IOError,msg:
117 print msg
117 print msg
118 return
118 return
119 page.page(self.shell.inspector.format(open(filename).read()))
119 page.page(self.shell.inspector.format(open(filename).read()))
120
120
121 @line_magic
121 @line_magic
122 def psearch(self, parameter_s=''):
122 def psearch(self, parameter_s=''):
123 """Search for object in namespaces by wildcard.
123 """Search for object in namespaces by wildcard.
124
124
125 %psearch [options] PATTERN [OBJECT TYPE]
125 %psearch [options] PATTERN [OBJECT TYPE]
126
126
127 Note: ? can be used as a synonym for %psearch, at the beginning or at
127 Note: ? can be used as a synonym for %psearch, at the beginning or at
128 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
128 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
129 rest of the command line must be unchanged (options come first), so
129 rest of the command line must be unchanged (options come first), so
130 for example the following forms are equivalent
130 for example the following forms are equivalent
131
131
132 %psearch -i a* function
132 %psearch -i a* function
133 -i a* function?
133 -i a* function?
134 ?-i a* function
134 ?-i a* function
135
135
136 Arguments:
136 Arguments:
137
137
138 PATTERN
138 PATTERN
139
139
140 where PATTERN is a string containing * as a wildcard similar to its
140 where PATTERN is a string containing * as a wildcard similar to its
141 use in a shell. The pattern is matched in all namespaces on the
141 use in a shell. The pattern is matched in all namespaces on the
142 search path. By default objects starting with a single _ are not
142 search path. By default objects starting with a single _ are not
143 matched, many IPython generated objects have a single
143 matched, many IPython generated objects have a single
144 underscore. The default is case insensitive matching. Matching is
144 underscore. The default is case insensitive matching. Matching is
145 also done on the attributes of objects and not only on the objects
145 also done on the attributes of objects and not only on the objects
146 in a module.
146 in a module.
147
147
148 [OBJECT TYPE]
148 [OBJECT TYPE]
149
149
150 Is the name of a python type from the types module. The name is
150 Is the name of a python type from the types module. The name is
151 given in lowercase without the ending type, ex. StringType is
151 given in lowercase without the ending type, ex. StringType is
152 written string. By adding a type here only objects matching the
152 written string. By adding a type here only objects matching the
153 given type are matched. Using all here makes the pattern match all
153 given type are matched. Using all here makes the pattern match all
154 types (this is the default).
154 types (this is the default).
155
155
156 Options:
156 Options:
157
157
158 -a: makes the pattern match even objects whose names start with a
158 -a: makes the pattern match even objects whose names start with a
159 single underscore. These names are normally omitted from the
159 single underscore. These names are normally omitted from the
160 search.
160 search.
161
161
162 -i/-c: make the pattern case insensitive/sensitive. If neither of
162 -i/-c: make the pattern case insensitive/sensitive. If neither of
163 these options are given, the default is read from your configuration
163 these options are given, the default is read from your configuration
164 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
164 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
165 If this option is not specified in your configuration file, IPython's
165 If this option is not specified in your configuration file, IPython's
166 internal default is to do a case sensitive search.
166 internal default is to do a case sensitive search.
167
167
168 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
168 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
169 specify can be searched in any of the following namespaces:
169 specify can be searched in any of the following namespaces:
170 'builtin', 'user', 'user_global','internal', 'alias', where
170 'builtin', 'user', 'user_global','internal', 'alias', where
171 'builtin' and 'user' are the search defaults. Note that you should
171 'builtin' and 'user' are the search defaults. Note that you should
172 not use quotes when specifying namespaces.
172 not use quotes when specifying namespaces.
173
173
174 'Builtin' contains the python module builtin, 'user' contains all
174 'Builtin' contains the python module builtin, 'user' contains all
175 user data, 'alias' only contain the shell aliases and no python
175 user data, 'alias' only contain the shell aliases and no python
176 objects, 'internal' contains objects used by IPython. The
176 objects, 'internal' contains objects used by IPython. The
177 'user_global' namespace is only used by embedded IPython instances,
177 'user_global' namespace is only used by embedded IPython instances,
178 and it contains module-level globals. You can add namespaces to the
178 and it contains module-level globals. You can add namespaces to the
179 search with -s or exclude them with -e (these options can be given
179 search with -s or exclude them with -e (these options can be given
180 more than once).
180 more than once).
181
181
182 Examples
182 Examples
183 --------
183 --------
184 ::
184 ::
185
185
186 %psearch a* -> objects beginning with an a
186 %psearch a* -> objects beginning with an a
187 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
187 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
188 %psearch a* function -> all functions beginning with an a
188 %psearch a* function -> all functions beginning with an a
189 %psearch re.e* -> objects beginning with an e in module re
189 %psearch re.e* -> objects beginning with an e in module re
190 %psearch r*.e* -> objects that start with e in modules starting in r
190 %psearch r*.e* -> objects that start with e in modules starting in r
191 %psearch r*.* string -> all strings in modules beginning with r
191 %psearch r*.* string -> all strings in modules beginning with r
192
192
193 Case sensitive search::
193 Case sensitive search::
194
194
195 %psearch -c a* list all object beginning with lower case a
195 %psearch -c a* list all object beginning with lower case a
196
196
197 Show objects beginning with a single _::
197 Show objects beginning with a single _::
198
198
199 %psearch -a _* list objects beginning with a single underscore
199 %psearch -a _* list objects beginning with a single underscore
200 """
200 """
201 try:
201 try:
202 parameter_s.encode('ascii')
202 parameter_s.encode('ascii')
203 except UnicodeEncodeError:
203 except UnicodeEncodeError:
204 print 'Python identifiers can only contain ascii characters.'
204 print 'Python identifiers can only contain ascii characters.'
205 return
205 return
206
206
207 # default namespaces to be searched
207 # default namespaces to be searched
208 def_search = ['user_local', 'user_global', 'builtin']
208 def_search = ['user_local', 'user_global', 'builtin']
209
209
210 # Process options/args
210 # Process options/args
211 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
211 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
212 opt = opts.get
212 opt = opts.get
213 shell = self.shell
213 shell = self.shell
214 psearch = shell.inspector.psearch
214 psearch = shell.inspector.psearch
215
215
216 # select case options
216 # select case options
217 if opts.has_key('i'):
217 if opts.has_key('i'):
218 ignore_case = True
218 ignore_case = True
219 elif opts.has_key('c'):
219 elif opts.has_key('c'):
220 ignore_case = False
220 ignore_case = False
221 else:
221 else:
222 ignore_case = not shell.wildcards_case_sensitive
222 ignore_case = not shell.wildcards_case_sensitive
223
223
224 # Build list of namespaces to search from user options
224 # Build list of namespaces to search from user options
225 def_search.extend(opt('s',[]))
225 def_search.extend(opt('s',[]))
226 ns_exclude = ns_exclude=opt('e',[])
226 ns_exclude = ns_exclude=opt('e',[])
227 ns_search = [nm for nm in def_search if nm not in ns_exclude]
227 ns_search = [nm for nm in def_search if nm not in ns_exclude]
228
228
229 # Call the actual search
229 # Call the actual search
230 try:
230 try:
231 psearch(args,shell.ns_table,ns_search,
231 psearch(args,shell.ns_table,ns_search,
232 show_all=opt('a'),ignore_case=ignore_case)
232 show_all=opt('a'),ignore_case=ignore_case)
233 except:
233 except:
234 shell.showtraceback()
234 shell.showtraceback()
235
235
236 @skip_doctest
236 @skip_doctest
237 @line_magic
237 @line_magic
238 def who_ls(self, parameter_s=''):
238 def who_ls(self, parameter_s=''):
239 """Return a sorted list of all interactive variables.
239 """Return a sorted list of all interactive variables.
240
240
241 If arguments are given, only variables of types matching these
241 If arguments are given, only variables of types matching these
242 arguments are returned.
242 arguments are returned.
243
243
244 Examples
244 Examples
245 --------
245 --------
246
246
247 Define two variables and list them with who_ls::
247 Define two variables and list them with who_ls::
248
248
249 In [1]: alpha = 123
249 In [1]: alpha = 123
250
250
251 In [2]: beta = 'test'
251 In [2]: beta = 'test'
252
252
253 In [3]: %who_ls
253 In [3]: %who_ls
254 Out[3]: ['alpha', 'beta']
254 Out[3]: ['alpha', 'beta']
255
255
256 In [4]: %who_ls int
256 In [4]: %who_ls int
257 Out[4]: ['alpha']
257 Out[4]: ['alpha']
258
258
259 In [5]: %who_ls str
259 In [5]: %who_ls str
260 Out[5]: ['beta']
260 Out[5]: ['beta']
261 """
261 """
262
262
263 user_ns = self.shell.user_ns
263 user_ns = self.shell.user_ns
264 user_ns_hidden = self.shell.user_ns_hidden
264 user_ns_hidden = self.shell.user_ns_hidden
265 out = [ i for i in user_ns
265 out = [ i for i in user_ns
266 if not i.startswith('_') \
266 if not i.startswith('_') \
267 and not i in user_ns_hidden ]
267 and not i in user_ns_hidden ]
268
268
269 typelist = parameter_s.split()
269 typelist = parameter_s.split()
270 if typelist:
270 if typelist:
271 typeset = set(typelist)
271 typeset = set(typelist)
272 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
272 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
273
273
274 out.sort()
274 out.sort()
275 return out
275 return out
276
276
277 @skip_doctest
277 @skip_doctest
278 @line_magic
278 @line_magic
279 def who(self, parameter_s=''):
279 def who(self, parameter_s=''):
280 """Print all interactive variables, with some minimal formatting.
280 """Print all interactive variables, with some minimal formatting.
281
281
282 If any arguments are given, only variables whose type matches one of
282 If any arguments are given, only variables whose type matches one of
283 these are printed. For example::
283 these are printed. For example::
284
284
285 %who function str
285 %who function str
286
286
287 will only list functions and strings, excluding all other types of
287 will only list functions and strings, excluding all other types of
288 variables. To find the proper type names, simply use type(var) at a
288 variables. To find the proper type names, simply use type(var) at a
289 command line to see how python prints type names. For example:
289 command line to see how python prints type names. For example:
290
290
291 ::
291 ::
292
292
293 In [1]: type('hello')\\
293 In [1]: type('hello')\\
294 Out[1]: <type 'str'>
294 Out[1]: <type 'str'>
295
295
296 indicates that the type name for strings is 'str'.
296 indicates that the type name for strings is 'str'.
297
297
298 ``%who`` always excludes executed names loaded through your configuration
298 ``%who`` always excludes executed names loaded through your configuration
299 file and things which are internal to IPython.
299 file and things which are internal to IPython.
300
300
301 This is deliberate, as typically you may load many modules and the
301 This is deliberate, as typically you may load many modules and the
302 purpose of %who is to show you only what you've manually defined.
302 purpose of %who is to show you only what you've manually defined.
303
303
304 Examples
304 Examples
305 --------
305 --------
306
306
307 Define two variables and list them with who::
307 Define two variables and list them with who::
308
308
309 In [1]: alpha = 123
309 In [1]: alpha = 123
310
310
311 In [2]: beta = 'test'
311 In [2]: beta = 'test'
312
312
313 In [3]: %who
313 In [3]: %who
314 alpha beta
314 alpha beta
315
315
316 In [4]: %who int
316 In [4]: %who int
317 alpha
317 alpha
318
318
319 In [5]: %who str
319 In [5]: %who str
320 beta
320 beta
321 """
321 """
322
322
323 varlist = self.who_ls(parameter_s)
323 varlist = self.who_ls(parameter_s)
324 if not varlist:
324 if not varlist:
325 if parameter_s:
325 if parameter_s:
326 print 'No variables match your requested type.'
326 print 'No variables match your requested type.'
327 else:
327 else:
328 print 'Interactive namespace is empty.'
328 print 'Interactive namespace is empty.'
329 return
329 return
330
330
331 # if we have variables, move on...
331 # if we have variables, move on...
332 count = 0
332 count = 0
333 for i in varlist:
333 for i in varlist:
334 print i+'\t',
334 print i+'\t',
335 count += 1
335 count += 1
336 if count > 8:
336 if count > 8:
337 count = 0
337 count = 0
338 print
338 print
339 print
339 print
340
340
341 @skip_doctest
341 @skip_doctest
342 @line_magic
342 @line_magic
343 def whos(self, parameter_s=''):
343 def whos(self, parameter_s=''):
344 """Like %who, but gives some extra information about each variable.
344 """Like %who, but gives some extra information about each variable.
345
345
346 The same type filtering of %who can be applied here.
346 The same type filtering of %who can be applied here.
347
347
348 For all variables, the type is printed. Additionally it prints:
348 For all variables, the type is printed. Additionally it prints:
349
349
350 - For {},[],(): their length.
350 - For {},[],(): their length.
351
351
352 - For numpy arrays, a summary with shape, number of
352 - For numpy arrays, a summary with shape, number of
353 elements, typecode and size in memory.
353 elements, typecode and size in memory.
354
354
355 - Everything else: a string representation, snipping their middle if
355 - Everything else: a string representation, snipping their middle if
356 too long.
356 too long.
357
357
358 Examples
358 Examples
359 --------
359 --------
360
360
361 Define two variables and list them with whos::
361 Define two variables and list them with whos::
362
362
363 In [1]: alpha = 123
363 In [1]: alpha = 123
364
364
365 In [2]: beta = 'test'
365 In [2]: beta = 'test'
366
366
367 In [3]: %whos
367 In [3]: %whos
368 Variable Type Data/Info
368 Variable Type Data/Info
369 --------------------------------
369 --------------------------------
370 alpha int 123
370 alpha int 123
371 beta str test
371 beta str test
372 """
372 """
373
373
374 varnames = self.who_ls(parameter_s)
374 varnames = self.who_ls(parameter_s)
375 if not varnames:
375 if not varnames:
376 if parameter_s:
376 if parameter_s:
377 print 'No variables match your requested type.'
377 print 'No variables match your requested type.'
378 else:
378 else:
379 print 'Interactive namespace is empty.'
379 print 'Interactive namespace is empty.'
380 return
380 return
381
381
382 # if we have variables, move on...
382 # if we have variables, move on...
383
383
384 # for these types, show len() instead of data:
384 # for these types, show len() instead of data:
385 seq_types = ['dict', 'list', 'tuple']
385 seq_types = ['dict', 'list', 'tuple']
386
386
387 # for numpy arrays, display summary info
387 # for numpy arrays, display summary info
388 ndarray_type = None
388 ndarray_type = None
389 if 'numpy' in sys.modules:
389 if 'numpy' in sys.modules:
390 try:
390 try:
391 from numpy import ndarray
391 from numpy import ndarray
392 except ImportError:
392 except ImportError:
393 pass
393 pass
394 else:
394 else:
395 ndarray_type = ndarray.__name__
395 ndarray_type = ndarray.__name__
396
396
397 # Find all variable names and types so we can figure out column sizes
397 # Find all variable names and types so we can figure out column sizes
398 def get_vars(i):
398 def get_vars(i):
399 return self.shell.user_ns[i]
399 return self.shell.user_ns[i]
400
400
401 # some types are well known and can be shorter
401 # some types are well known and can be shorter
402 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
402 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
403 def type_name(v):
403 def type_name(v):
404 tn = type(v).__name__
404 tn = type(v).__name__
405 return abbrevs.get(tn,tn)
405 return abbrevs.get(tn,tn)
406
406
407 varlist = map(get_vars,varnames)
407 varlist = map(get_vars,varnames)
408
408
409 typelist = []
409 typelist = []
410 for vv in varlist:
410 for vv in varlist:
411 tt = type_name(vv)
411 tt = type_name(vv)
412
412
413 if tt=='instance':
413 if tt=='instance':
414 typelist.append( abbrevs.get(str(vv.__class__),
414 typelist.append( abbrevs.get(str(vv.__class__),
415 str(vv.__class__)))
415 str(vv.__class__)))
416 else:
416 else:
417 typelist.append(tt)
417 typelist.append(tt)
418
418
419 # column labels and # of spaces as separator
419 # column labels and # of spaces as separator
420 varlabel = 'Variable'
420 varlabel = 'Variable'
421 typelabel = 'Type'
421 typelabel = 'Type'
422 datalabel = 'Data/Info'
422 datalabel = 'Data/Info'
423 colsep = 3
423 colsep = 3
424 # variable format strings
424 # variable format strings
425 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
425 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
426 aformat = "%s: %s elems, type `%s`, %s bytes"
426 aformat = "%s: %s elems, type `%s`, %s bytes"
427 # find the size of the columns to format the output nicely
427 # find the size of the columns to format the output nicely
428 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
428 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
429 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
429 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
430 # table header
430 # table header
431 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
431 print varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
432 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
432 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)
433 # and the table itself
433 # and the table itself
434 kb = 1024
434 kb = 1024
435 Mb = 1048576 # kb**2
435 Mb = 1048576 # kb**2
436 for vname,var,vtype in zip(varnames,varlist,typelist):
436 for vname,var,vtype in zip(varnames,varlist,typelist):
437 print vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth),
437 print vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth),
438 if vtype in seq_types:
438 if vtype in seq_types:
439 print "n="+str(len(var))
439 print "n="+str(len(var))
440 elif vtype == ndarray_type:
440 elif vtype == ndarray_type:
441 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
441 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
442 if vtype==ndarray_type:
442 if vtype==ndarray_type:
443 # numpy
443 # numpy
444 vsize = var.size
444 vsize = var.size
445 vbytes = vsize*var.itemsize
445 vbytes = vsize*var.itemsize
446 vdtype = var.dtype
446 vdtype = var.dtype
447
447
448 if vbytes < 100000:
448 if vbytes < 100000:
449 print aformat % (vshape, vsize, vdtype, vbytes)
449 print aformat % (vshape, vsize, vdtype, vbytes)
450 else:
450 else:
451 print aformat % (vshape, vsize, vdtype, vbytes),
451 print aformat % (vshape, vsize, vdtype, vbytes),
452 if vbytes < Mb:
452 if vbytes < Mb:
453 print '(%s kb)' % (vbytes/kb,)
453 print '(%s kb)' % (vbytes/kb,)
454 else:
454 else:
455 print '(%s Mb)' % (vbytes/Mb,)
455 print '(%s Mb)' % (vbytes/Mb,)
456 else:
456 else:
457 try:
457 try:
458 vstr = str(var)
458 vstr = str(var)
459 except UnicodeEncodeError:
459 except UnicodeEncodeError:
460 vstr = unicode(var).encode(DEFAULT_ENCODING,
460 vstr = unicode(var).encode(DEFAULT_ENCODING,
461 'backslashreplace')
461 'backslashreplace')
462 except:
462 except:
463 vstr = "<object with id %d (str() failed)>" % id(var)
463 vstr = "<object with id %d (str() failed)>" % id(var)
464 vstr = vstr.replace('\n', '\\n')
464 vstr = vstr.replace('\n', '\\n')
465 if len(vstr) < 50:
465 if len(vstr) < 50:
466 print vstr
466 print vstr
467 else:
467 else:
468 print vstr[:25] + "<...>" + vstr[-25:]
468 print vstr[:25] + "<...>" + vstr[-25:]
469
469
470 @line_magic
470 @line_magic
471 def reset(self, parameter_s=''):
471 def reset(self, parameter_s=''):
472 """Resets the namespace by removing all names defined by the user, if
472 """Resets the namespace by removing all names defined by the user, if
473 called without arguments, or by removing some types of objects, such
473 called without arguments, or by removing some types of objects, such
474 as everything currently in IPython's In[] and Out[] containers (see
474 as everything currently in IPython's In[] and Out[] containers (see
475 the parameters for details).
475 the parameters for details).
476
476
477 Parameters
477 Parameters
478 ----------
478 ----------
479 -f : force reset without asking for confirmation.
479 -f : force reset without asking for confirmation.
480
480
481 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
481 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
482 References to objects may be kept. By default (without this option),
482 References to objects may be kept. By default (without this option),
483 we do a 'hard' reset, giving you a new session and removing all
483 we do a 'hard' reset, giving you a new session and removing all
484 references to objects from the current session.
484 references to objects from the current session.
485
485
486 in : reset input history
486 in : reset input history
487
487
488 out : reset output history
488 out : reset output history
489
489
490 dhist : reset directory history
490 dhist : reset directory history
491
491
492 array : reset only variables that are NumPy arrays
492 array : reset only variables that are NumPy arrays
493
493
494 See Also
494 See Also
495 --------
495 --------
496 magic_reset_selective : invoked as ``%reset_selective``
496 magic_reset_selective : invoked as ``%reset_selective``
497
497
498 Examples
498 Examples
499 --------
499 --------
500 ::
500 ::
501
501
502 In [6]: a = 1
502 In [6]: a = 1
503
503
504 In [7]: a
504 In [7]: a
505 Out[7]: 1
505 Out[7]: 1
506
506
507 In [8]: 'a' in _ip.user_ns
507 In [8]: 'a' in _ip.user_ns
508 Out[8]: True
508 Out[8]: True
509
509
510 In [9]: %reset -f
510 In [9]: %reset -f
511
511
512 In [1]: 'a' in _ip.user_ns
512 In [1]: 'a' in _ip.user_ns
513 Out[1]: False
513 Out[1]: False
514
514
515 In [2]: %reset -f in
515 In [2]: %reset -f in
516 Flushing input history
516 Flushing input history
517
517
518 In [3]: %reset -f dhist in
518 In [3]: %reset -f dhist in
519 Flushing directory history
519 Flushing directory history
520 Flushing input history
520 Flushing input history
521
521
522 Notes
522 Notes
523 -----
523 -----
524 Calling this magic from clients that do not implement standard input,
524 Calling this magic from clients that do not implement standard input,
525 such as the ipython notebook interface, will reset the namespace
525 such as the ipython notebook interface, will reset the namespace
526 without confirmation.
526 without confirmation.
527 """
527 """
528 opts, args = self.parse_options(parameter_s,'sf', mode='list')
528 opts, args = self.parse_options(parameter_s,'sf', mode='list')
529 if 'f' in opts:
529 if 'f' in opts:
530 ans = True
530 ans = True
531 else:
531 else:
532 try:
532 try:
533 ans = self.shell.ask_yes_no(
533 ans = self.shell.ask_yes_no(
534 "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
534 "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
535 default='n')
535 default='n')
536 except StdinNotImplementedError:
536 except StdinNotImplementedError:
537 ans = True
537 ans = True
538 if not ans:
538 if not ans:
539 print 'Nothing done.'
539 print 'Nothing done.'
540 return
540 return
541
541
542 if 's' in opts: # Soft reset
542 if 's' in opts: # Soft reset
543 user_ns = self.shell.user_ns
543 user_ns = self.shell.user_ns
544 for i in self.who_ls():
544 for i in self.who_ls():
545 del(user_ns[i])
545 del(user_ns[i])
546 elif len(args) == 0: # Hard reset
546 elif len(args) == 0: # Hard reset
547 self.shell.reset(new_session = False)
547 self.shell.reset(new_session = False)
548
548
549 # reset in/out/dhist/array: previously extensinions/clearcmd.py
549 # reset in/out/dhist/array: previously extensinions/clearcmd.py
550 ip = self.shell
550 ip = self.shell
551 user_ns = self.shell.user_ns # local lookup, heavily used
551 user_ns = self.shell.user_ns # local lookup, heavily used
552
552
553 for target in args:
553 for target in args:
554 target = target.lower() # make matches case insensitive
554 target = target.lower() # make matches case insensitive
555 if target == 'out':
555 if target == 'out':
556 print "Flushing output cache (%d entries)" % len(user_ns['_oh'])
556 print "Flushing output cache (%d entries)" % len(user_ns['_oh'])
557 self.shell.displayhook.flush()
557 self.shell.displayhook.flush()
558
558
559 elif target == 'in':
559 elif target == 'in':
560 print "Flushing input history"
560 print "Flushing input history"
561 pc = self.shell.displayhook.prompt_count + 1
561 pc = self.shell.displayhook.prompt_count + 1
562 for n in range(1, pc):
562 for n in range(1, pc):
563 key = '_i'+repr(n)
563 key = '_i'+repr(n)
564 user_ns.pop(key,None)
564 user_ns.pop(key,None)
565 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
565 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
566 hm = ip.history_manager
566 hm = ip.history_manager
567 # don't delete these, as %save and %macro depending on the
567 # don't delete these, as %save and %macro depending on the
568 # length of these lists to be preserved
568 # length of these lists to be preserved
569 hm.input_hist_parsed[:] = [''] * pc
569 hm.input_hist_parsed[:] = [''] * pc
570 hm.input_hist_raw[:] = [''] * pc
570 hm.input_hist_raw[:] = [''] * pc
571 # hm has internal machinery for _i,_ii,_iii, clear it out
571 # hm has internal machinery for _i,_ii,_iii, clear it out
572 hm._i = hm._ii = hm._iii = hm._i00 = u''
572 hm._i = hm._ii = hm._iii = hm._i00 = u''
573
573
574 elif target == 'array':
574 elif target == 'array':
575 # Support cleaning up numpy arrays
575 # Support cleaning up numpy arrays
576 try:
576 try:
577 from numpy import ndarray
577 from numpy import ndarray
578 # This must be done with items and not iteritems because
578 # This must be done with items and not iteritems because
579 # we're going to modify the dict in-place.
579 # we're going to modify the dict in-place.
580 for x,val in user_ns.items():
580 for x,val in user_ns.items():
581 if isinstance(val,ndarray):
581 if isinstance(val,ndarray):
582 del user_ns[x]
582 del user_ns[x]
583 except ImportError:
583 except ImportError:
584 print "reset array only works if Numpy is available."
584 print "reset array only works if Numpy is available."
585
585
586 elif target == 'dhist':
586 elif target == 'dhist':
587 print "Flushing directory history"
587 print "Flushing directory history"
588 del user_ns['_dh'][:]
588 del user_ns['_dh'][:]
589
589
590 else:
590 else:
591 print "Don't know how to reset ",
591 print "Don't know how to reset ",
592 print target + ", please run `%reset?` for details"
592 print target + ", please run `%reset?` for details"
593
593
594 gc.collect()
594 gc.collect()
595
595
596 @line_magic
596 @line_magic
597 def reset_selective(self, parameter_s=''):
597 def reset_selective(self, parameter_s=''):
598 """Resets the namespace by removing names defined by the user.
598 """Resets the namespace by removing names defined by the user.
599
599
600 Input/Output history are left around in case you need them.
600 Input/Output history are left around in case you need them.
601
601
602 %reset_selective [-f] regex
602 %reset_selective [-f] regex
603
603
604 No action is taken if regex is not included
604 No action is taken if regex is not included
605
605
606 Options
606 Options
607 -f : force reset without asking for confirmation.
607 -f : force reset without asking for confirmation.
608
608
609 See Also
609 See Also
610 --------
610 --------
611 magic_reset : invoked as ``%reset``
611 magic_reset : invoked as ``%reset``
612
612
613 Examples
613 Examples
614 --------
614 --------
615
615
616 We first fully reset the namespace so your output looks identical to
616 We first fully reset the namespace so your output looks identical to
617 this example for pedagogical reasons; in practice you do not need a
617 this example for pedagogical reasons; in practice you do not need a
618 full reset::
618 full reset::
619
619
620 In [1]: %reset -f
620 In [1]: %reset -f
621
621
622 Now, with a clean namespace we can make a few variables and use
622 Now, with a clean namespace we can make a few variables and use
623 ``%reset_selective`` to only delete names that match our regexp::
623 ``%reset_selective`` to only delete names that match our regexp::
624
624
625 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
625 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
626
626
627 In [3]: who_ls
627 In [3]: who_ls
628 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
628 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
629
629
630 In [4]: %reset_selective -f b[2-3]m
630 In [4]: %reset_selective -f b[2-3]m
631
631
632 In [5]: who_ls
632 In [5]: who_ls
633 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
633 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
634
634
635 In [6]: %reset_selective -f d
635 In [6]: %reset_selective -f d
636
636
637 In [7]: who_ls
637 In [7]: who_ls
638 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
638 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
639
639
640 In [8]: %reset_selective -f c
640 In [8]: %reset_selective -f c
641
641
642 In [9]: who_ls
642 In [9]: who_ls
643 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
643 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
644
644
645 In [10]: %reset_selective -f b
645 In [10]: %reset_selective -f b
646
646
647 In [11]: who_ls
647 In [11]: who_ls
648 Out[11]: ['a']
648 Out[11]: ['a']
649
649
650 Notes
650 Notes
651 -----
651 -----
652 Calling this magic from clients that do not implement standard input,
652 Calling this magic from clients that do not implement standard input,
653 such as the ipython notebook interface, will reset the namespace
653 such as the ipython notebook interface, will reset the namespace
654 without confirmation.
654 without confirmation.
655 """
655 """
656
656
657 opts, regex = self.parse_options(parameter_s,'f')
657 opts, regex = self.parse_options(parameter_s,'f')
658
658
659 if opts.has_key('f'):
659 if opts.has_key('f'):
660 ans = True
660 ans = True
661 else:
661 else:
662 try:
662 try:
663 ans = self.shell.ask_yes_no(
663 ans = self.shell.ask_yes_no(
664 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
664 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
665 default='n')
665 default='n')
666 except StdinNotImplementedError:
666 except StdinNotImplementedError:
667 ans = True
667 ans = True
668 if not ans:
668 if not ans:
669 print 'Nothing done.'
669 print 'Nothing done.'
670 return
670 return
671 user_ns = self.shell.user_ns
671 user_ns = self.shell.user_ns
672 if not regex:
672 if not regex:
673 print 'No regex pattern specified. Nothing done.'
673 print 'No regex pattern specified. Nothing done.'
674 return
674 return
675 else:
675 else:
676 try:
676 try:
677 m = re.compile(regex)
677 m = re.compile(regex)
678 except TypeError:
678 except TypeError:
679 raise TypeError('regex must be a string or compiled pattern')
679 raise TypeError('regex must be a string or compiled pattern')
680 for i in self.who_ls():
680 for i in self.who_ls():
681 if m.search(i):
681 if m.search(i):
682 del(user_ns[i])
682 del(user_ns[i])
683
683
684 @line_magic
684 @line_magic
685 def xdel(self, parameter_s=''):
685 def xdel(self, parameter_s=''):
686 """Delete a variable, trying to clear it from anywhere that
686 """Delete a variable, trying to clear it from anywhere that
687 IPython's machinery has references to it. By default, this uses
687 IPython's machinery has references to it. By default, this uses
688 the identity of the named object in the user namespace to remove
688 the identity of the named object in the user namespace to remove
689 references held under other names. The object is also removed
689 references held under other names. The object is also removed
690 from the output history.
690 from the output history.
691
691
692 Options
692 Options
693 -n : Delete the specified name from all namespaces, without
693 -n : Delete the specified name from all namespaces, without
694 checking their identity.
694 checking their identity.
695 """
695 """
696 opts, varname = self.parse_options(parameter_s,'n')
696 opts, varname = self.parse_options(parameter_s,'n')
697 try:
697 try:
698 self.shell.del_var(varname, ('n' in opts))
698 self.shell.del_var(varname, ('n' in opts))
699 except (NameError, ValueError) as e:
699 except (NameError, ValueError) as e:
700 print type(e).__name__ +": "+ str(e)
700 print type(e).__name__ +": "+ str(e)
@@ -1,772 +1,825 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
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 # Copyright (C) 2001-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 __all__ = ['Inspector','InspectColors']
17 __all__ = ['Inspector','InspectColors']
18
18
19 # stdlib modules
19 # stdlib modules
20 import __builtin__
20 import __builtin__
21 import inspect
21 import inspect
22 import linecache
22 import linecache
23 import os
23 import os
24 import sys
24 import sys
25 import types
25 import types
26 from collections import namedtuple
26 from collections import namedtuple
27 try:
27 try:
28 from itertools import izip_longest
28 from itertools import izip_longest
29 except ImportError:
29 except ImportError:
30 from itertools import zip_longest as izip_longest
30 from itertools import zip_longest as izip_longest
31
31
32 # IPython's own
32 # IPython's own
33 from IPython.core import page
33 from IPython.core import page
34 from IPython.testing.skipdoctest import skip_doctest_py3
34 from IPython.testing.skipdoctest import skip_doctest_py3
35 from IPython.utils import PyColorize
35 from IPython.utils import PyColorize
36 from IPython.utils import io
36 from IPython.utils import io
37 from IPython.utils import py3compat
37 from IPython.utils import py3compat
38 from IPython.utils.text import indent
38 from IPython.utils.text import indent
39 from IPython.utils.wildcard import list_namespace
39 from IPython.utils.wildcard import list_namespace
40 from IPython.utils.coloransi import *
40 from IPython.utils.coloransi import *
41
41
42 #****************************************************************************
42 #****************************************************************************
43 # Builtin color schemes
43 # Builtin color schemes
44
44
45 Colors = TermColors # just a shorthand
45 Colors = TermColors # just a shorthand
46
46
47 # Build a few color schemes
47 # Build a few color schemes
48 NoColor = ColorScheme(
48 NoColor = ColorScheme(
49 'NoColor',{
49 'NoColor',{
50 'header' : Colors.NoColor,
50 'header' : Colors.NoColor,
51 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
51 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
52 } )
52 } )
53
53
54 LinuxColors = ColorScheme(
54 LinuxColors = ColorScheme(
55 'Linux',{
55 'Linux',{
56 'header' : Colors.LightRed,
56 'header' : Colors.LightRed,
57 'normal' : Colors.Normal # color off (usu. Colors.Normal)
57 'normal' : Colors.Normal # color off (usu. Colors.Normal)
58 } )
58 } )
59
59
60 LightBGColors = ColorScheme(
60 LightBGColors = ColorScheme(
61 'LightBG',{
61 'LightBG',{
62 'header' : Colors.Red,
62 'header' : Colors.Red,
63 'normal' : Colors.Normal # color off (usu. Colors.Normal)
63 'normal' : Colors.Normal # color off (usu. Colors.Normal)
64 } )
64 } )
65
65
66 # Build table of color schemes (needed by the parser)
66 # Build table of color schemes (needed by the parser)
67 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
67 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
68 'Linux')
68 'Linux')
69
69
70 #****************************************************************************
70 #****************************************************************************
71 # Auxiliary functions and objects
71 # Auxiliary functions and objects
72
72
73 # See the messaging spec for the definition of all these fields. This list
73 # See the messaging spec for the definition of all these fields. This list
74 # effectively defines the order of display
74 # effectively defines the order of display
75 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
75 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
76 'length', 'file', 'definition', 'docstring', 'source',
76 'length', 'file', 'definition', 'docstring', 'source',
77 'init_definition', 'class_docstring', 'init_docstring',
77 'init_definition', 'class_docstring', 'init_docstring',
78 'call_def', 'call_docstring',
78 'call_def', 'call_docstring',
79 # These won't be printed but will be used to determine how to
79 # These won't be printed but will be used to determine how to
80 # format the object
80 # format the object
81 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
81 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
82 ]
82 ]
83
83
84
84
85 def object_info(**kw):
85 def object_info(**kw):
86 """Make an object info dict with all fields present."""
86 """Make an object info dict with all fields present."""
87 infodict = dict(izip_longest(info_fields, [None]))
87 infodict = dict(izip_longest(info_fields, [None]))
88 infodict.update(kw)
88 infodict.update(kw)
89 return infodict
89 return infodict
90
90
91
91
92 def getdoc(obj):
92 def getdoc(obj):
93 """Stable wrapper around inspect.getdoc.
93 """Stable wrapper around inspect.getdoc.
94
94
95 This can't crash because of attribute problems.
95 This can't crash because of attribute problems.
96
96
97 It also attempts to call a getdoc() method on the given object. This
97 It also attempts to call a getdoc() method on the given object. This
98 allows objects which provide their docstrings via non-standard mechanisms
98 allows objects which provide their docstrings via non-standard mechanisms
99 (like Pyro proxies) to still be inspected by ipython's ? system."""
99 (like Pyro proxies) to still be inspected by ipython's ? system."""
100 # Allow objects to offer customized documentation via a getdoc method:
100 # Allow objects to offer customized documentation via a getdoc method:
101 try:
101 try:
102 ds = obj.getdoc()
102 ds = obj.getdoc()
103 except Exception:
103 except Exception:
104 pass
104 pass
105 else:
105 else:
106 # if we get extra info, we add it to the normal docstring.
106 # if we get extra info, we add it to the normal docstring.
107 if isinstance(ds, basestring):
107 if isinstance(ds, basestring):
108 return inspect.cleandoc(ds)
108 return inspect.cleandoc(ds)
109
109
110 try:
110 try:
111 return inspect.getdoc(obj)
111 return inspect.getdoc(obj)
112 except Exception:
112 except Exception:
113 # Harden against an inspect failure, which can occur with
113 # Harden against an inspect failure, which can occur with
114 # SWIG-wrapped extensions.
114 # SWIG-wrapped extensions.
115 return None
115 return None
116
116
117
117
118 def getsource(obj,is_binary=False):
118 def getsource(obj,is_binary=False):
119 """Wrapper around inspect.getsource.
119 """Wrapper around inspect.getsource.
120
120
121 This can be modified by other projects to provide customized source
121 This can be modified by other projects to provide customized source
122 extraction.
122 extraction.
123
123
124 Inputs:
124 Inputs:
125
125
126 - obj: an object whose source code we will attempt to extract.
126 - obj: an object whose source code we will attempt to extract.
127
127
128 Optional inputs:
128 Optional inputs:
129
129
130 - is_binary: whether the object is known to come from a binary source.
130 - is_binary: whether the object is known to come from a binary source.
131 This implementation will skip returning any output for binary objects, but
131 This implementation will skip returning any output for binary objects, but
132 custom extractors may know how to meaningfully process them."""
132 custom extractors may know how to meaningfully process them."""
133
133
134 if is_binary:
134 if is_binary:
135 return None
135 return None
136 else:
136 else:
137 # get source if obj was decorated with @decorator
137 # get source if obj was decorated with @decorator
138 if hasattr(obj,"__wrapped__"):
138 if hasattr(obj,"__wrapped__"):
139 obj = obj.__wrapped__
139 obj = obj.__wrapped__
140 try:
140 try:
141 src = inspect.getsource(obj)
141 src = inspect.getsource(obj)
142 except TypeError:
142 except TypeError:
143 if hasattr(obj,'__class__'):
143 if hasattr(obj,'__class__'):
144 src = inspect.getsource(obj.__class__)
144 src = inspect.getsource(obj.__class__)
145 return src
145 return src
146
146
147 def getargspec(obj):
147 def getargspec(obj):
148 """Get the names and default values of a function's arguments.
148 """Get the names and default values of a function's arguments.
149
149
150 A tuple of four things is returned: (args, varargs, varkw, defaults).
150 A tuple of four things is returned: (args, varargs, varkw, defaults).
151 'args' is a list of the argument names (it may contain nested lists).
151 'args' is a list of the argument names (it may contain nested lists).
152 'varargs' and 'varkw' are the names of the * and ** arguments or None.
152 'varargs' and 'varkw' are the names of the * and ** arguments or None.
153 'defaults' is an n-tuple of the default values of the last n arguments.
153 'defaults' is an n-tuple of the default values of the last n arguments.
154
154
155 Modified version of inspect.getargspec from the Python Standard
155 Modified version of inspect.getargspec from the Python Standard
156 Library."""
156 Library."""
157
157
158 if inspect.isfunction(obj):
158 if inspect.isfunction(obj):
159 func_obj = obj
159 func_obj = obj
160 elif inspect.ismethod(obj):
160 elif inspect.ismethod(obj):
161 func_obj = obj.im_func
161 func_obj = obj.im_func
162 elif hasattr(obj, '__call__'):
162 elif hasattr(obj, '__call__'):
163 func_obj = obj.__call__
163 func_obj = obj.__call__
164 else:
164 else:
165 raise TypeError('arg is not a Python function')
165 raise TypeError('arg is not a Python function')
166 args, varargs, varkw = inspect.getargs(func_obj.func_code)
166 args, varargs, varkw = inspect.getargs(func_obj.func_code)
167 return args, varargs, varkw, func_obj.func_defaults
167 return args, varargs, varkw, func_obj.func_defaults
168
168
169
169
170 def format_argspec(argspec):
170 def format_argspec(argspec):
171 """Format argspect, convenience wrapper around inspect's.
171 """Format argspect, convenience wrapper around inspect's.
172
172
173 This takes a dict instead of ordered arguments and calls
173 This takes a dict instead of ordered arguments and calls
174 inspect.format_argspec with the arguments in the necessary order.
174 inspect.format_argspec with the arguments in the necessary order.
175 """
175 """
176 return inspect.formatargspec(argspec['args'], argspec['varargs'],
176 return inspect.formatargspec(argspec['args'], argspec['varargs'],
177 argspec['varkw'], argspec['defaults'])
177 argspec['varkw'], argspec['defaults'])
178
178
179
179
180 def call_tip(oinfo, format_call=True):
180 def call_tip(oinfo, format_call=True):
181 """Extract call tip data from an oinfo dict.
181 """Extract call tip data from an oinfo dict.
182
182
183 Parameters
183 Parameters
184 ----------
184 ----------
185 oinfo : dict
185 oinfo : dict
186
186
187 format_call : bool, optional
187 format_call : bool, optional
188 If True, the call line is formatted and returned as a string. If not, a
188 If True, the call line is formatted and returned as a string. If not, a
189 tuple of (name, argspec) is returned.
189 tuple of (name, argspec) is returned.
190
190
191 Returns
191 Returns
192 -------
192 -------
193 call_info : None, str or (str, dict) tuple.
193 call_info : None, str or (str, dict) tuple.
194 When format_call is True, the whole call information is formattted as a
194 When format_call is True, the whole call information is formattted as a
195 single string. Otherwise, the object's name and its argspec dict are
195 single string. Otherwise, the object's name and its argspec dict are
196 returned. If no call information is available, None is returned.
196 returned. If no call information is available, None is returned.
197
197
198 docstring : str or None
198 docstring : str or None
199 The most relevant docstring for calling purposes is returned, if
199 The most relevant docstring for calling purposes is returned, if
200 available. The priority is: call docstring for callable instances, then
200 available. The priority is: call docstring for callable instances, then
201 constructor docstring for classes, then main object's docstring otherwise
201 constructor docstring for classes, then main object's docstring otherwise
202 (regular functions).
202 (regular functions).
203 """
203 """
204 # Get call definition
204 # Get call definition
205 argspec = oinfo.get('argspec')
205 argspec = oinfo.get('argspec')
206 if argspec is None:
206 if argspec is None:
207 call_line = None
207 call_line = None
208 else:
208 else:
209 # Callable objects will have 'self' as their first argument, prune
209 # Callable objects will have 'self' as their first argument, prune
210 # it out if it's there for clarity (since users do *not* pass an
210 # it out if it's there for clarity (since users do *not* pass an
211 # extra first argument explicitly).
211 # extra first argument explicitly).
212 try:
212 try:
213 has_self = argspec['args'][0] == 'self'
213 has_self = argspec['args'][0] == 'self'
214 except (KeyError, IndexError):
214 except (KeyError, IndexError):
215 pass
215 pass
216 else:
216 else:
217 if has_self:
217 if has_self:
218 argspec['args'] = argspec['args'][1:]
218 argspec['args'] = argspec['args'][1:]
219
219
220 call_line = oinfo['name']+format_argspec(argspec)
220 call_line = oinfo['name']+format_argspec(argspec)
221
221
222 # Now get docstring.
222 # Now get docstring.
223 # The priority is: call docstring, constructor docstring, main one.
223 # The priority is: call docstring, constructor docstring, main one.
224 doc = oinfo.get('call_docstring')
224 doc = oinfo.get('call_docstring')
225 if doc is None:
225 if doc is None:
226 doc = oinfo.get('init_docstring')
226 doc = oinfo.get('init_docstring')
227 if doc is None:
227 if doc is None:
228 doc = oinfo.get('docstring','')
228 doc = oinfo.get('docstring','')
229
229
230 return call_line, doc
230 return call_line, doc
231
231
232
232
233 def find_file(obj):
234 """Find the absolute path to the file where an object was defined.
235
236 This is essentially a robust wrapper around `inspect.getabsfile`.
237
238 Returns None if no file can be found.
239
240 Parameters
241 ----------
242 obj : any Python object
243
244 Returns
245 -------
246 fname : str
247 The absolute path to the file where the object was defined.
248 """
249 # get source if obj was decorated with @decorator
250 if hasattr(obj, '__wrapped__'):
251 obj = obj.__wrapped__
252
253 try:
254 fname = inspect.getabsfile(obj)
255 except TypeError:
256 # For an instance, the file that matters is where its class was
257 # declared.
258 if hasattr(obj, '__class__'):
259 try:
260 fname = inspect.getabsfile(obj.__class__)
261 except TypeError:
262 # Can happen for builtins
263 fname = None
264 except:
265 fname = None
266 return fname
267
268
269 def find_source_lines(obj):
270 """Find the line number in a file where an object was defined.
271
272 This is essentially a robust wrapper around `inspect.getsourcelines`.
273
274 Returns None if no file can be found.
275
276 Parameters
277 ----------
278 obj : any Python object
279
280 Returns
281 -------
282 lineno : int
283 The line number where the object definition starts.
284 """
285 # get source if obj was decorated with @decorator
286 if hasattr(obj, '__wrapped__'):
287 obj = obj.__wrapped__
288
289 try:
290 try:
291 lineno = inspect.getsourcelines(obj)[1]
292 except TypeError:
293 # For instances, try the class object like getsource() does
294 if hasattr(obj, '__class__'):
295 lineno = inspect.getsourcelines(obj.__class__)[1]
296 except:
297 return None
298
299 return lineno
300
301
233 class Inspector:
302 class Inspector:
234 def __init__(self, color_table=InspectColors,
303 def __init__(self, color_table=InspectColors,
235 code_color_table=PyColorize.ANSICodeColors,
304 code_color_table=PyColorize.ANSICodeColors,
236 scheme='NoColor',
305 scheme='NoColor',
237 str_detail_level=0):
306 str_detail_level=0):
238 self.color_table = color_table
307 self.color_table = color_table
239 self.parser = PyColorize.Parser(code_color_table,out='str')
308 self.parser = PyColorize.Parser(code_color_table,out='str')
240 self.format = self.parser.format
309 self.format = self.parser.format
241 self.str_detail_level = str_detail_level
310 self.str_detail_level = str_detail_level
242 self.set_active_scheme(scheme)
311 self.set_active_scheme(scheme)
243
312
244 def _getdef(self,obj,oname=''):
313 def _getdef(self,obj,oname=''):
245 """Return the definition header for any callable object.
314 """Return the definition header for any callable object.
246
315
247 If any exception is generated, None is returned instead and the
316 If any exception is generated, None is returned instead and the
248 exception is suppressed."""
317 exception is suppressed."""
249
318
250 try:
319 try:
251 # We need a plain string here, NOT unicode!
320 # We need a plain string here, NOT unicode!
252 hdef = oname + inspect.formatargspec(*getargspec(obj))
321 hdef = oname + inspect.formatargspec(*getargspec(obj))
253 return py3compat.unicode_to_str(hdef, 'ascii')
322 return py3compat.unicode_to_str(hdef, 'ascii')
254 except:
323 except:
255 return None
324 return None
256
325
257 def __head(self,h):
326 def __head(self,h):
258 """Return a header string with proper colors."""
327 """Return a header string with proper colors."""
259 return '%s%s%s' % (self.color_table.active_colors.header,h,
328 return '%s%s%s' % (self.color_table.active_colors.header,h,
260 self.color_table.active_colors.normal)
329 self.color_table.active_colors.normal)
261
330
262 def set_active_scheme(self,scheme):
331 def set_active_scheme(self, scheme):
263 self.color_table.set_active_scheme(scheme)
332 self.color_table.set_active_scheme(scheme)
264 self.parser.color_table.set_active_scheme(scheme)
333 self.parser.color_table.set_active_scheme(scheme)
265
334
266 def noinfo(self,msg,oname):
335 def noinfo(self, msg, oname):
267 """Generic message when no information is found."""
336 """Generic message when no information is found."""
268 print 'No %s found' % msg,
337 print 'No %s found' % msg,
269 if oname:
338 if oname:
270 print 'for %s' % oname
339 print 'for %s' % oname
271 else:
340 else:
272 print
341 print
273
342
274 def pdef(self,obj,oname=''):
343 def pdef(self, obj, oname=''):
275 """Print the definition header for any callable object.
344 """Print the definition header for any callable object.
276
345
277 If the object is a class, print the constructor information."""
346 If the object is a class, print the constructor information."""
278
347
279 if not callable(obj):
348 if not callable(obj):
280 print 'Object is not callable.'
349 print 'Object is not callable.'
281 return
350 return
282
351
283 header = ''
352 header = ''
284
353
285 if inspect.isclass(obj):
354 if inspect.isclass(obj):
286 header = self.__head('Class constructor information:\n')
355 header = self.__head('Class constructor information:\n')
287 obj = obj.__init__
356 obj = obj.__init__
288 elif type(obj) is types.InstanceType:
357 elif type(obj) is types.InstanceType:
289 obj = obj.__call__
358 obj = obj.__call__
290
359
291 output = self._getdef(obj,oname)
360 output = self._getdef(obj,oname)
292 if output is None:
361 if output is None:
293 self.noinfo('definition header',oname)
362 self.noinfo('definition header',oname)
294 else:
363 else:
295 print >>io.stdout, header,self.format(output),
364 print >>io.stdout, header,self.format(output),
296
365
297 # In Python 3, all classes are new-style, so they all have __init__.
366 # In Python 3, all classes are new-style, so they all have __init__.
298 @skip_doctest_py3
367 @skip_doctest_py3
299 def pdoc(self,obj,oname='',formatter = None):
368 def pdoc(self,obj,oname='',formatter = None):
300 """Print the docstring for any object.
369 """Print the docstring for any object.
301
370
302 Optional:
371 Optional:
303 -formatter: a function to run the docstring through for specially
372 -formatter: a function to run the docstring through for specially
304 formatted docstrings.
373 formatted docstrings.
305
374
306 Examples
375 Examples
307 --------
376 --------
308
377
309 In [1]: class NoInit:
378 In [1]: class NoInit:
310 ...: pass
379 ...: pass
311
380
312 In [2]: class NoDoc:
381 In [2]: class NoDoc:
313 ...: def __init__(self):
382 ...: def __init__(self):
314 ...: pass
383 ...: pass
315
384
316 In [3]: %pdoc NoDoc
385 In [3]: %pdoc NoDoc
317 No documentation found for NoDoc
386 No documentation found for NoDoc
318
387
319 In [4]: %pdoc NoInit
388 In [4]: %pdoc NoInit
320 No documentation found for NoInit
389 No documentation found for NoInit
321
390
322 In [5]: obj = NoInit()
391 In [5]: obj = NoInit()
323
392
324 In [6]: %pdoc obj
393 In [6]: %pdoc obj
325 No documentation found for obj
394 No documentation found for obj
326
395
327 In [5]: obj2 = NoDoc()
396 In [5]: obj2 = NoDoc()
328
397
329 In [6]: %pdoc obj2
398 In [6]: %pdoc obj2
330 No documentation found for obj2
399 No documentation found for obj2
331 """
400 """
332
401
333 head = self.__head # For convenience
402 head = self.__head # For convenience
334 lines = []
403 lines = []
335 ds = getdoc(obj)
404 ds = getdoc(obj)
336 if formatter:
405 if formatter:
337 ds = formatter(ds)
406 ds = formatter(ds)
338 if ds:
407 if ds:
339 lines.append(head("Class Docstring:"))
408 lines.append(head("Class Docstring:"))
340 lines.append(indent(ds))
409 lines.append(indent(ds))
341 if inspect.isclass(obj) and hasattr(obj, '__init__'):
410 if inspect.isclass(obj) and hasattr(obj, '__init__'):
342 init_ds = getdoc(obj.__init__)
411 init_ds = getdoc(obj.__init__)
343 if init_ds is not None:
412 if init_ds is not None:
344 lines.append(head("Constructor Docstring:"))
413 lines.append(head("Constructor Docstring:"))
345 lines.append(indent(init_ds))
414 lines.append(indent(init_ds))
346 elif hasattr(obj,'__call__'):
415 elif hasattr(obj,'__call__'):
347 call_ds = getdoc(obj.__call__)
416 call_ds = getdoc(obj.__call__)
348 if call_ds:
417 if call_ds:
349 lines.append(head("Calling Docstring:"))
418 lines.append(head("Calling Docstring:"))
350 lines.append(indent(call_ds))
419 lines.append(indent(call_ds))
351
420
352 if not lines:
421 if not lines:
353 self.noinfo('documentation',oname)
422 self.noinfo('documentation',oname)
354 else:
423 else:
355 page.page('\n'.join(lines))
424 page.page('\n'.join(lines))
356
425
357 def psource(self,obj,oname=''):
426 def psource(self,obj,oname=''):
358 """Print the source code for an object."""
427 """Print the source code for an object."""
359
428
360 # Flush the source cache because inspect can return out-of-date source
429 # Flush the source cache because inspect can return out-of-date source
361 linecache.checkcache()
430 linecache.checkcache()
362 try:
431 try:
363 src = getsource(obj)
432 src = getsource(obj)
364 except:
433 except:
365 self.noinfo('source',oname)
434 self.noinfo('source',oname)
366 else:
435 else:
367 page.page(self.format(py3compat.unicode_to_str(src)))
436 page.page(self.format(py3compat.unicode_to_str(src)))
368
437
369 def pfile(self,obj,oname=''):
438 def pfile(self, obj, oname=''):
370 """Show the whole file where an object was defined."""
439 """Show the whole file where an object was defined."""
371
440
372 try:
441 lineno = find_source_lines(obj)
373 try:
442 if lineno is None:
374 lineno = inspect.getsourcelines(obj)[1]
443 self.noinfo('file', oname)
375 except TypeError:
376 # For instances, try the class object like getsource() does
377 if hasattr(obj,'__class__'):
378 lineno = inspect.getsourcelines(obj.__class__)[1]
379 # Adjust the inspected object so getabsfile() below works
380 obj = obj.__class__
381 except:
382 self.noinfo('file',oname)
383 return
444 return
384
445
385 # We only reach this point if object was successfully queried
446 ofile = find_file(obj)
386
447 # run contents of file through pager starting at line where the object
387 # run contents of file through pager starting at line
448 # is defined, as long as the file isn't binary and is actually on the
388 # where the object is defined
449 # filesystem.
389 ofile = inspect.getabsfile(obj)
390
391 if ofile.endswith(('.so', '.dll', '.pyd')):
450 if ofile.endswith(('.so', '.dll', '.pyd')):
392 print 'File %r is binary, not printing.' % ofile
451 print 'File %r is binary, not printing.' % ofile
393 elif not os.path.isfile(ofile):
452 elif not os.path.isfile(ofile):
394 print 'File %r does not exist, not printing.' % ofile
453 print 'File %r does not exist, not printing.' % ofile
395 else:
454 else:
396 # Print only text files, not extension binaries. Note that
455 # Print only text files, not extension binaries. Note that
397 # getsourcelines returns lineno with 1-offset and page() uses
456 # getsourcelines returns lineno with 1-offset and page() uses
398 # 0-offset, so we must adjust.
457 # 0-offset, so we must adjust.
399 page.page(self.format(open(ofile).read()),lineno-1)
458 page.page(self.format(open(ofile).read()), lineno-1)
400
459
401 def _format_fields(self, fields, title_width=12):
460 def _format_fields(self, fields, title_width=12):
402 """Formats a list of fields for display.
461 """Formats a list of fields for display.
403
462
404 Parameters
463 Parameters
405 ----------
464 ----------
406 fields : list
465 fields : list
407 A list of 2-tuples: (field_title, field_content)
466 A list of 2-tuples: (field_title, field_content)
408 title_width : int
467 title_width : int
409 How many characters to pad titles to. Default 12.
468 How many characters to pad titles to. Default 12.
410 """
469 """
411 out = []
470 out = []
412 header = self.__head
471 header = self.__head
413 for title, content in fields:
472 for title, content in fields:
414 if len(content.splitlines()) > 1:
473 if len(content.splitlines()) > 1:
415 title = header(title + ":") + "\n"
474 title = header(title + ":") + "\n"
416 else:
475 else:
417 title = header((title+":").ljust(title_width))
476 title = header((title+":").ljust(title_width))
418 out.append(title + content)
477 out.append(title + content)
419 return "\n".join(out)
478 return "\n".join(out)
420
479
421 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
480 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
422 pinfo_fields1 = [("Type", "type_name"),
481 pinfo_fields1 = [("Type", "type_name"),
423 ("Base Class", "base_class"),
482 ("Base Class", "base_class"),
424 ("String Form", "string_form"),
483 ("String Form", "string_form"),
425 ("Namespace", "namespace"),
484 ("Namespace", "namespace"),
426 ("Length", "length"),
485 ("Length", "length"),
427 ("File", "file"),
486 ("File", "file"),
428 ("Definition", "definition")]
487 ("Definition", "definition")]
429
488
430 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
489 pinfo_fields_obj = [("Class Docstring", "class_docstring"),
431 ("Constructor Docstring","init_docstring"),
490 ("Constructor Docstring","init_docstring"),
432 ("Call def", "call_def"),
491 ("Call def", "call_def"),
433 ("Call docstring", "call_docstring")]
492 ("Call docstring", "call_docstring")]
434
493
435 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
494 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
436 """Show detailed information about an object.
495 """Show detailed information about an object.
437
496
438 Optional arguments:
497 Optional arguments:
439
498
440 - oname: name of the variable pointing to the object.
499 - oname: name of the variable pointing to the object.
441
500
442 - formatter: special formatter for docstrings (see pdoc)
501 - formatter: special formatter for docstrings (see pdoc)
443
502
444 - info: a structure with some information fields which may have been
503 - info: a structure with some information fields which may have been
445 precomputed already.
504 precomputed already.
446
505
447 - detail_level: if set to 1, more information is given.
506 - detail_level: if set to 1, more information is given.
448 """
507 """
449 info = self.info(obj, oname=oname, formatter=formatter,
508 info = self.info(obj, oname=oname, formatter=formatter,
450 info=info, detail_level=detail_level)
509 info=info, detail_level=detail_level)
451 displayfields = []
510 displayfields = []
452 for title, key in self.pinfo_fields1:
511 for title, key in self.pinfo_fields1:
453 field = info[key]
512 field = info[key]
454 if field is not None:
513 if field is not None:
455 displayfields.append((title, field.rstrip()))
514 displayfields.append((title, field.rstrip()))
456
515
457 # Source or docstring, depending on detail level and whether
516 # Source or docstring, depending on detail level and whether
458 # source found.
517 # source found.
459 if detail_level > 0 and info['source'] is not None:
518 if detail_level > 0 and info['source'] is not None:
460 displayfields.append(("Source", self.format(py3compat.cast_bytes_py2(info['source']))))
519 displayfields.append(("Source", self.format(py3compat.cast_bytes_py2(info['source']))))
461 elif info['docstring'] is not None:
520 elif info['docstring'] is not None:
462 displayfields.append(("Docstring", info["docstring"]))
521 displayfields.append(("Docstring", info["docstring"]))
463
522
464 # Constructor info for classes
523 # Constructor info for classes
465 if info['isclass']:
524 if info['isclass']:
466 if info['init_definition'] or info['init_docstring']:
525 if info['init_definition'] or info['init_docstring']:
467 displayfields.append(("Constructor information", ""))
526 displayfields.append(("Constructor information", ""))
468 if info['init_definition'] is not None:
527 if info['init_definition'] is not None:
469 displayfields.append((" Definition",
528 displayfields.append((" Definition",
470 info['init_definition'].rstrip()))
529 info['init_definition'].rstrip()))
471 if info['init_docstring'] is not None:
530 if info['init_docstring'] is not None:
472 displayfields.append((" Docstring",
531 displayfields.append((" Docstring",
473 indent(info['init_docstring'])))
532 indent(info['init_docstring'])))
474
533
475 # Info for objects:
534 # Info for objects:
476 else:
535 else:
477 for title, key in self.pinfo_fields_obj:
536 for title, key in self.pinfo_fields_obj:
478 field = info[key]
537 field = info[key]
479 if field is not None:
538 if field is not None:
480 displayfields.append((title, field.rstrip()))
539 displayfields.append((title, field.rstrip()))
481
540
482 # Finally send to printer/pager:
541 # Finally send to printer/pager:
483 if displayfields:
542 if displayfields:
484 page.page(self._format_fields(displayfields))
543 page.page(self._format_fields(displayfields))
485
544
486 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
545 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
487 """Compute a dict with detailed information about an object.
546 """Compute a dict with detailed information about an object.
488
547
489 Optional arguments:
548 Optional arguments:
490
549
491 - oname: name of the variable pointing to the object.
550 - oname: name of the variable pointing to the object.
492
551
493 - formatter: special formatter for docstrings (see pdoc)
552 - formatter: special formatter for docstrings (see pdoc)
494
553
495 - info: a structure with some information fields which may have been
554 - info: a structure with some information fields which may have been
496 precomputed already.
555 precomputed already.
497
556
498 - detail_level: if set to 1, more information is given.
557 - detail_level: if set to 1, more information is given.
499 """
558 """
500
559
501 obj_type = type(obj)
560 obj_type = type(obj)
502
561
503 header = self.__head
562 header = self.__head
504 if info is None:
563 if info is None:
505 ismagic = 0
564 ismagic = 0
506 isalias = 0
565 isalias = 0
507 ospace = ''
566 ospace = ''
508 else:
567 else:
509 ismagic = info.ismagic
568 ismagic = info.ismagic
510 isalias = info.isalias
569 isalias = info.isalias
511 ospace = info.namespace
570 ospace = info.namespace
512
571
513 # Get docstring, special-casing aliases:
572 # Get docstring, special-casing aliases:
514 if isalias:
573 if isalias:
515 if not callable(obj):
574 if not callable(obj):
516 try:
575 try:
517 ds = "Alias to the system command:\n %s" % obj[1]
576 ds = "Alias to the system command:\n %s" % obj[1]
518 except:
577 except:
519 ds = "Alias: " + str(obj)
578 ds = "Alias: " + str(obj)
520 else:
579 else:
521 ds = "Alias to " + str(obj)
580 ds = "Alias to " + str(obj)
522 if obj.__doc__:
581 if obj.__doc__:
523 ds += "\nDocstring:\n" + obj.__doc__
582 ds += "\nDocstring:\n" + obj.__doc__
524 else:
583 else:
525 ds = getdoc(obj)
584 ds = getdoc(obj)
526 if ds is None:
585 if ds is None:
527 ds = '<no docstring>'
586 ds = '<no docstring>'
528 if formatter is not None:
587 if formatter is not None:
529 ds = formatter(ds)
588 ds = formatter(ds)
530
589
531 # store output in a dict, we initialize it here and fill it as we go
590 # store output in a dict, we initialize it here and fill it as we go
532 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
591 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
533
592
534 string_max = 200 # max size of strings to show (snipped if longer)
593 string_max = 200 # max size of strings to show (snipped if longer)
535 shalf = int((string_max -5)/2)
594 shalf = int((string_max -5)/2)
536
595
537 if ismagic:
596 if ismagic:
538 obj_type_name = 'Magic function'
597 obj_type_name = 'Magic function'
539 elif isalias:
598 elif isalias:
540 obj_type_name = 'System alias'
599 obj_type_name = 'System alias'
541 else:
600 else:
542 obj_type_name = obj_type.__name__
601 obj_type_name = obj_type.__name__
543 out['type_name'] = obj_type_name
602 out['type_name'] = obj_type_name
544
603
545 try:
604 try:
546 bclass = obj.__class__
605 bclass = obj.__class__
547 out['base_class'] = str(bclass)
606 out['base_class'] = str(bclass)
548 except: pass
607 except: pass
549
608
550 # String form, but snip if too long in ? form (full in ??)
609 # String form, but snip if too long in ? form (full in ??)
551 if detail_level >= self.str_detail_level:
610 if detail_level >= self.str_detail_level:
552 try:
611 try:
553 ostr = str(obj)
612 ostr = str(obj)
554 str_head = 'string_form'
613 str_head = 'string_form'
555 if not detail_level and len(ostr)>string_max:
614 if not detail_level and len(ostr)>string_max:
556 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
615 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
557 ostr = ("\n" + " " * len(str_head.expandtabs())).\
616 ostr = ("\n" + " " * len(str_head.expandtabs())).\
558 join(q.strip() for q in ostr.split("\n"))
617 join(q.strip() for q in ostr.split("\n"))
559 out[str_head] = ostr
618 out[str_head] = ostr
560 except:
619 except:
561 pass
620 pass
562
621
563 if ospace:
622 if ospace:
564 out['namespace'] = ospace
623 out['namespace'] = ospace
565
624
566 # Length (for strings and lists)
625 # Length (for strings and lists)
567 try:
626 try:
568 out['length'] = str(len(obj))
627 out['length'] = str(len(obj))
569 except: pass
628 except: pass
570
629
571 # Filename where object was defined
630 # Filename where object was defined
572 binary_file = False
631 binary_file = False
573 try:
632 fname = find_file(obj)
574 try:
633 if fname is None:
575 fname = inspect.getabsfile(obj)
576 except TypeError:
577 # For an instance, the file that matters is where its class was
578 # declared.
579 if hasattr(obj,'__class__'):
580 fname = inspect.getabsfile(obj.__class__)
581 if fname.endswith('<string>'):
582 fname = 'Dynamically generated function. No source code available.'
583 if fname.endswith(('.so', '.dll', '.pyd')):
584 binary_file = True
585 out['file'] = fname
586 except:
587 # if anything goes wrong, we don't want to show source, so it's as
634 # if anything goes wrong, we don't want to show source, so it's as
588 # if the file was binary
635 # if the file was binary
589 binary_file = True
636 binary_file = True
590
637 else:
638 if fname.endswith(('.so', '.dll', '.pyd')):
639 binary_file = True
640 elif fname.endswith('<string>'):
641 fname = 'Dynamically generated function. No source code available.'
642 out['file'] = fname
643
591 # reconstruct the function definition and print it:
644 # reconstruct the function definition and print it:
592 defln = self._getdef(obj, oname)
645 defln = self._getdef(obj, oname)
593 if defln:
646 if defln:
594 out['definition'] = self.format(defln)
647 out['definition'] = self.format(defln)
595
648
596 # Docstrings only in detail 0 mode, since source contains them (we
649 # Docstrings only in detail 0 mode, since source contains them (we
597 # avoid repetitions). If source fails, we add them back, see below.
650 # avoid repetitions). If source fails, we add them back, see below.
598 if ds and detail_level == 0:
651 if ds and detail_level == 0:
599 out['docstring'] = ds
652 out['docstring'] = ds
600
653
601 # Original source code for any callable
654 # Original source code for any callable
602 if detail_level:
655 if detail_level:
603 # Flush the source cache because inspect can return out-of-date
656 # Flush the source cache because inspect can return out-of-date
604 # source
657 # source
605 linecache.checkcache()
658 linecache.checkcache()
606 source = None
659 source = None
607 try:
660 try:
608 try:
661 try:
609 source = getsource(obj,binary_file)
662 source = getsource(obj, binary_file)
610 except TypeError:
663 except TypeError:
611 if hasattr(obj,'__class__'):
664 if hasattr(obj, '__class__'):
612 source = getsource(obj.__class__,binary_file)
665 source = getsource(obj.__class__, binary_file)
613 if source is not None:
666 if source is not None:
614 out['source'] = source.rstrip()
667 out['source'] = source.rstrip()
615 except Exception:
668 except Exception:
616 pass
669 pass
617
670
618 if ds and source is None:
671 if ds and source is None:
619 out['docstring'] = ds
672 out['docstring'] = ds
620
673
621
674
622 # Constructor docstring for classes
675 # Constructor docstring for classes
623 if inspect.isclass(obj):
676 if inspect.isclass(obj):
624 out['isclass'] = True
677 out['isclass'] = True
625 # reconstruct the function definition and print it:
678 # reconstruct the function definition and print it:
626 try:
679 try:
627 obj_init = obj.__init__
680 obj_init = obj.__init__
628 except AttributeError:
681 except AttributeError:
629 init_def = init_ds = None
682 init_def = init_ds = None
630 else:
683 else:
631 init_def = self._getdef(obj_init,oname)
684 init_def = self._getdef(obj_init,oname)
632 init_ds = getdoc(obj_init)
685 init_ds = getdoc(obj_init)
633 # Skip Python's auto-generated docstrings
686 # Skip Python's auto-generated docstrings
634 if init_ds and \
687 if init_ds and \
635 init_ds.startswith('x.__init__(...) initializes'):
688 init_ds.startswith('x.__init__(...) initializes'):
636 init_ds = None
689 init_ds = None
637
690
638 if init_def or init_ds:
691 if init_def or init_ds:
639 if init_def:
692 if init_def:
640 out['init_definition'] = self.format(init_def)
693 out['init_definition'] = self.format(init_def)
641 if init_ds:
694 if init_ds:
642 out['init_docstring'] = init_ds
695 out['init_docstring'] = init_ds
643
696
644 # and class docstring for instances:
697 # and class docstring for instances:
645 else:
698 else:
646 # First, check whether the instance docstring is identical to the
699 # First, check whether the instance docstring is identical to the
647 # class one, and print it separately if they don't coincide. In
700 # class one, and print it separately if they don't coincide. In
648 # most cases they will, but it's nice to print all the info for
701 # most cases they will, but it's nice to print all the info for
649 # objects which use instance-customized docstrings.
702 # objects which use instance-customized docstrings.
650 if ds:
703 if ds:
651 try:
704 try:
652 cls = getattr(obj,'__class__')
705 cls = getattr(obj,'__class__')
653 except:
706 except:
654 class_ds = None
707 class_ds = None
655 else:
708 else:
656 class_ds = getdoc(cls)
709 class_ds = getdoc(cls)
657 # Skip Python's auto-generated docstrings
710 # Skip Python's auto-generated docstrings
658 if class_ds and \
711 if class_ds and \
659 (class_ds.startswith('function(code, globals[,') or \
712 (class_ds.startswith('function(code, globals[,') or \
660 class_ds.startswith('instancemethod(function, instance,') or \
713 class_ds.startswith('instancemethod(function, instance,') or \
661 class_ds.startswith('module(name[,') ):
714 class_ds.startswith('module(name[,') ):
662 class_ds = None
715 class_ds = None
663 if class_ds and ds != class_ds:
716 if class_ds and ds != class_ds:
664 out['class_docstring'] = class_ds
717 out['class_docstring'] = class_ds
665
718
666 # Next, try to show constructor docstrings
719 # Next, try to show constructor docstrings
667 try:
720 try:
668 init_ds = getdoc(obj.__init__)
721 init_ds = getdoc(obj.__init__)
669 # Skip Python's auto-generated docstrings
722 # Skip Python's auto-generated docstrings
670 if init_ds and \
723 if init_ds and \
671 init_ds.startswith('x.__init__(...) initializes'):
724 init_ds.startswith('x.__init__(...) initializes'):
672 init_ds = None
725 init_ds = None
673 except AttributeError:
726 except AttributeError:
674 init_ds = None
727 init_ds = None
675 if init_ds:
728 if init_ds:
676 out['init_docstring'] = init_ds
729 out['init_docstring'] = init_ds
677
730
678 # Call form docstring for callable instances
731 # Call form docstring for callable instances
679 if hasattr(obj, '__call__'):
732 if hasattr(obj, '__call__'):
680 call_def = self._getdef(obj.__call__, oname)
733 call_def = self._getdef(obj.__call__, oname)
681 if call_def is not None:
734 if call_def is not None:
682 out['call_def'] = self.format(call_def)
735 out['call_def'] = self.format(call_def)
683 call_ds = getdoc(obj.__call__)
736 call_ds = getdoc(obj.__call__)
684 # Skip Python's auto-generated docstrings
737 # Skip Python's auto-generated docstrings
685 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
738 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
686 call_ds = None
739 call_ds = None
687 if call_ds:
740 if call_ds:
688 out['call_docstring'] = call_ds
741 out['call_docstring'] = call_ds
689
742
690 # Compute the object's argspec as a callable. The key is to decide
743 # Compute the object's argspec as a callable. The key is to decide
691 # whether to pull it from the object itself, from its __init__ or
744 # whether to pull it from the object itself, from its __init__ or
692 # from its __call__ method.
745 # from its __call__ method.
693
746
694 if inspect.isclass(obj):
747 if inspect.isclass(obj):
695 # Old-style classes need not have an __init__
748 # Old-style classes need not have an __init__
696 callable_obj = getattr(obj, "__init__", None)
749 callable_obj = getattr(obj, "__init__", None)
697 elif callable(obj):
750 elif callable(obj):
698 callable_obj = obj
751 callable_obj = obj
699 else:
752 else:
700 callable_obj = None
753 callable_obj = None
701
754
702 if callable_obj:
755 if callable_obj:
703 try:
756 try:
704 args, varargs, varkw, defaults = getargspec(callable_obj)
757 args, varargs, varkw, defaults = getargspec(callable_obj)
705 except (TypeError, AttributeError):
758 except (TypeError, AttributeError):
706 # For extensions/builtins we can't retrieve the argspec
759 # For extensions/builtins we can't retrieve the argspec
707 pass
760 pass
708 else:
761 else:
709 out['argspec'] = dict(args=args, varargs=varargs,
762 out['argspec'] = dict(args=args, varargs=varargs,
710 varkw=varkw, defaults=defaults)
763 varkw=varkw, defaults=defaults)
711
764
712 return object_info(**out)
765 return object_info(**out)
713
766
714
767
715 def psearch(self,pattern,ns_table,ns_search=[],
768 def psearch(self,pattern,ns_table,ns_search=[],
716 ignore_case=False,show_all=False):
769 ignore_case=False,show_all=False):
717 """Search namespaces with wildcards for objects.
770 """Search namespaces with wildcards for objects.
718
771
719 Arguments:
772 Arguments:
720
773
721 - pattern: string containing shell-like wildcards to use in namespace
774 - pattern: string containing shell-like wildcards to use in namespace
722 searches and optionally a type specification to narrow the search to
775 searches and optionally a type specification to narrow the search to
723 objects of that type.
776 objects of that type.
724
777
725 - ns_table: dict of name->namespaces for search.
778 - ns_table: dict of name->namespaces for search.
726
779
727 Optional arguments:
780 Optional arguments:
728
781
729 - ns_search: list of namespace names to include in search.
782 - ns_search: list of namespace names to include in search.
730
783
731 - ignore_case(False): make the search case-insensitive.
784 - ignore_case(False): make the search case-insensitive.
732
785
733 - show_all(False): show all names, including those starting with
786 - show_all(False): show all names, including those starting with
734 underscores.
787 underscores.
735 """
788 """
736 #print 'ps pattern:<%r>' % pattern # dbg
789 #print 'ps pattern:<%r>' % pattern # dbg
737
790
738 # defaults
791 # defaults
739 type_pattern = 'all'
792 type_pattern = 'all'
740 filter = ''
793 filter = ''
741
794
742 cmds = pattern.split()
795 cmds = pattern.split()
743 len_cmds = len(cmds)
796 len_cmds = len(cmds)
744 if len_cmds == 1:
797 if len_cmds == 1:
745 # Only filter pattern given
798 # Only filter pattern given
746 filter = cmds[0]
799 filter = cmds[0]
747 elif len_cmds == 2:
800 elif len_cmds == 2:
748 # Both filter and type specified
801 # Both filter and type specified
749 filter,type_pattern = cmds
802 filter,type_pattern = cmds
750 else:
803 else:
751 raise ValueError('invalid argument string for psearch: <%s>' %
804 raise ValueError('invalid argument string for psearch: <%s>' %
752 pattern)
805 pattern)
753
806
754 # filter search namespaces
807 # filter search namespaces
755 for name in ns_search:
808 for name in ns_search:
756 if name not in ns_table:
809 if name not in ns_table:
757 raise ValueError('invalid namespace <%s>. Valid names: %s' %
810 raise ValueError('invalid namespace <%s>. Valid names: %s' %
758 (name,ns_table.keys()))
811 (name,ns_table.keys()))
759
812
760 #print 'type_pattern:',type_pattern # dbg
813 #print 'type_pattern:',type_pattern # dbg
761 search_result, namespaces_seen = set(), set()
814 search_result, namespaces_seen = set(), set()
762 for ns_name in ns_search:
815 for ns_name in ns_search:
763 ns = ns_table[ns_name]
816 ns = ns_table[ns_name]
764 # Normally, locals and globals are the same, so we just check one.
817 # Normally, locals and globals are the same, so we just check one.
765 if id(ns) in namespaces_seen:
818 if id(ns) in namespaces_seen:
766 continue
819 continue
767 namespaces_seen.add(id(ns))
820 namespaces_seen.add(id(ns))
768 tmp_res = list_namespace(ns, type_pattern, filter,
821 tmp_res = list_namespace(ns, type_pattern, filter,
769 ignore_case=ignore_case, show_all=show_all)
822 ignore_case=ignore_case, show_all=show_all)
770 search_result.update(tmp_res)
823 search_result.update(tmp_res)
771
824
772 page.page('\n'.join(sorted(search_result)))
825 page.page('\n'.join(sorted(search_result)))
@@ -1,222 +1,277 b''
1 """Tests for the object inspection functionality.
1 """Tests for the object inspection functionality.
2 """
2 """
3 #-----------------------------------------------------------------------------
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2010-2011 The IPython Development Team.
4 # Copyright (C) 2010-2011 The IPython Development Team.
5 #
5 #
6 # Distributed under the terms of the BSD License.
6 # Distributed under the terms of the BSD License.
7 #
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
14 from __future__ import print_function
15
15
16 # Stdlib imports
16 # Stdlib imports
17 import os
17
18
18 # Third-party imports
19 # Third-party imports
19 import nose.tools as nt
20 import nose.tools as nt
20
21
21 # Our own imports
22 # Our own imports
22 from .. import oinspect
23 from .. import oinspect
23 from IPython.core.magic import (Magics, magics_class, line_magic,
24 from IPython.core.magic import (Magics, magics_class, line_magic,
24 cell_magic, line_cell_magic,
25 cell_magic, line_cell_magic,
25 register_line_magic, register_cell_magic,
26 register_line_magic, register_cell_magic,
26 register_line_cell_magic)
27 register_line_cell_magic)
28 from IPython.external.decorator import decorator
27 from IPython.utils import py3compat
29 from IPython.utils import py3compat
28
30
31
29 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
30 # Globals and constants
33 # Globals and constants
31 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
32
35
33 inspector = oinspect.Inspector()
36 inspector = oinspect.Inspector()
34 ip = get_ipython()
37 ip = get_ipython()
35
38
36 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
37 # Local utilities
40 # Local utilities
38 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
39
42
43 # WARNING: since this test checks the line number where a function is
44 # defined, if any code is inserted above, the following line will need to be
45 # updated. Do NOT insert any whitespace between the next line and the function
46 # definition below.
47 THIS_LINE_NUMBER = 47 # Put here the actual number of this line
48 def test_find_source_lines():
49 nt.assert_equal(oinspect.find_source_lines(test_find_source_lines),
50 THIS_LINE_NUMBER+1)
51
52
53 def test_find_file():
54 nt.assert_equal(oinspect.find_file(test_find_file),
55 os.path.abspath(__file__))
56
57
58 def test_find_file_decorated1():
59
60 @decorator
61 def noop1(f):
62 def wrapper():
63 return f(*a, **kw)
64 return wrapper
65
66 @noop1
67 def f(x):
68 "My docstring"
69
70 nt.assert_equal(oinspect.find_file(f),
71 os.path.abspath(__file__))
72 nt.assert_equal(f.__doc__, "My docstring")
73
74
75 def test_find_file_decorated2():
76
77 @decorator
78 def noop2(f, *a, **kw):
79 return f(*a, **kw)
80
81 @noop2
82 def f(x):
83 "My docstring 2"
84
85 nt.assert_equal(oinspect.find_file(f),
86 os.path.abspath(__file__))
87 nt.assert_equal(f.__doc__, "My docstring 2")
88
89
90 def test_find_file_magic():
91 run = ip.find_line_magic('run')
92 nt.assert_not_equal(oinspect.find_file(run), None)
93
94
40 # A few generic objects we can then inspect in the tests below
95 # A few generic objects we can then inspect in the tests below
41
96
42 class Call(object):
97 class Call(object):
43 """This is the class docstring."""
98 """This is the class docstring."""
44
99
45 def __init__(self, x, y=1):
100 def __init__(self, x, y=1):
46 """This is the constructor docstring."""
101 """This is the constructor docstring."""
47
102
48 def __call__(self, *a, **kw):
103 def __call__(self, *a, **kw):
49 """This is the call docstring."""
104 """This is the call docstring."""
50
105
51 def method(self, x, z=2):
106 def method(self, x, z=2):
52 """Some method's docstring"""
107 """Some method's docstring"""
53
108
54
109
55 class OldStyle:
110 class OldStyle:
56 """An old-style class for testing."""
111 """An old-style class for testing."""
57 pass
112 pass
58
113
59
114
60 def f(x, y=2, *a, **kw):
115 def f(x, y=2, *a, **kw):
61 """A simple function."""
116 """A simple function."""
62
117
63
118
64 def g(y, z=3, *a, **kw):
119 def g(y, z=3, *a, **kw):
65 pass # no docstring
120 pass # no docstring
66
121
67
122
68 @register_line_magic
123 @register_line_magic
69 def lmagic(line):
124 def lmagic(line):
70 "A line magic"
125 "A line magic"
71
126
72
127
73 @register_cell_magic
128 @register_cell_magic
74 def cmagic(line, cell):
129 def cmagic(line, cell):
75 "A cell magic"
130 "A cell magic"
76
131
77
132
78 @register_line_cell_magic
133 @register_line_cell_magic
79 def lcmagic(line, cell=None):
134 def lcmagic(line, cell=None):
80 "A line/cell magic"
135 "A line/cell magic"
81
136
82
137
83 @magics_class
138 @magics_class
84 class SimpleMagics(Magics):
139 class SimpleMagics(Magics):
85 @line_magic
140 @line_magic
86 def Clmagic(self, cline):
141 def Clmagic(self, cline):
87 "A class-based line magic"
142 "A class-based line magic"
88
143
89 @cell_magic
144 @cell_magic
90 def Ccmagic(self, cline, ccell):
145 def Ccmagic(self, cline, ccell):
91 "A class-based cell magic"
146 "A class-based cell magic"
92
147
93 @line_cell_magic
148 @line_cell_magic
94 def Clcmagic(self, cline, ccell=None):
149 def Clcmagic(self, cline, ccell=None):
95 "A class-based line/cell magic"
150 "A class-based line/cell magic"
96
151
97
152
98 def check_calltip(obj, name, call, docstring):
153 def check_calltip(obj, name, call, docstring):
99 """Generic check pattern all calltip tests will use"""
154 """Generic check pattern all calltip tests will use"""
100 info = inspector.info(obj, name)
155 info = inspector.info(obj, name)
101 call_line, ds = oinspect.call_tip(info)
156 call_line, ds = oinspect.call_tip(info)
102 nt.assert_equal(call_line, call)
157 nt.assert_equal(call_line, call)
103 nt.assert_equal(ds, docstring)
158 nt.assert_equal(ds, docstring)
104
159
105 #-----------------------------------------------------------------------------
160 #-----------------------------------------------------------------------------
106 # Tests
161 # Tests
107 #-----------------------------------------------------------------------------
162 #-----------------------------------------------------------------------------
108
163
109 def test_calltip_class():
164 def test_calltip_class():
110 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
165 check_calltip(Call, 'Call', 'Call(x, y=1)', Call.__init__.__doc__)
111
166
112
167
113 def test_calltip_instance():
168 def test_calltip_instance():
114 c = Call(1)
169 c = Call(1)
115 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
170 check_calltip(c, 'c', 'c(*a, **kw)', c.__call__.__doc__)
116
171
117
172
118 def test_calltip_method():
173 def test_calltip_method():
119 c = Call(1)
174 c = Call(1)
120 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
175 check_calltip(c.method, 'c.method', 'c.method(x, z=2)', c.method.__doc__)
121
176
122
177
123 def test_calltip_function():
178 def test_calltip_function():
124 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
179 check_calltip(f, 'f', 'f(x, y=2, *a, **kw)', f.__doc__)
125
180
126
181
127 def test_calltip_function2():
182 def test_calltip_function2():
128 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
183 check_calltip(g, 'g', 'g(y, z=3, *a, **kw)', '<no docstring>')
129
184
130
185
131 def test_calltip_builtin():
186 def test_calltip_builtin():
132 check_calltip(sum, 'sum', None, sum.__doc__)
187 check_calltip(sum, 'sum', None, sum.__doc__)
133
188
134
189
135 def test_calltip_line_magic():
190 def test_calltip_line_magic():
136 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
191 check_calltip(lmagic, 'lmagic', 'lmagic(line)', "A line magic")
137
192
138
193
139 def test_calltip_cell_magic():
194 def test_calltip_cell_magic():
140 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
195 check_calltip(cmagic, 'cmagic', 'cmagic(line, cell)', "A cell magic")
141
196
142
197
143 def test_calltip_line_magic():
198 def test_calltip_line_magic():
144 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
199 check_calltip(lcmagic, 'lcmagic', 'lcmagic(line, cell=None)',
145 "A line/cell magic")
200 "A line/cell magic")
146
201
147
202
148 def test_class_magics():
203 def test_class_magics():
149 cm = SimpleMagics(ip)
204 cm = SimpleMagics(ip)
150 ip.register_magics(cm)
205 ip.register_magics(cm)
151 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
206 check_calltip(cm.Clmagic, 'Clmagic', 'Clmagic(cline)',
152 "A class-based line magic")
207 "A class-based line magic")
153 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
208 check_calltip(cm.Ccmagic, 'Ccmagic', 'Ccmagic(cline, ccell)',
154 "A class-based cell magic")
209 "A class-based cell magic")
155 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
210 check_calltip(cm.Clcmagic, 'Clcmagic', 'Clcmagic(cline, ccell=None)',
156 "A class-based line/cell magic")
211 "A class-based line/cell magic")
157
212
158
213
159 def test_info():
214 def test_info():
160 "Check that Inspector.info fills out various fields as expected."
215 "Check that Inspector.info fills out various fields as expected."
161 i = inspector.info(Call, oname='Call')
216 i = inspector.info(Call, oname='Call')
162 nt.assert_equal(i['type_name'], 'type')
217 nt.assert_equal(i['type_name'], 'type')
163 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
218 expted_class = str(type(type)) # <class 'type'> (Python 3) or <type 'type'>
164 nt.assert_equal(i['base_class'], expted_class)
219 nt.assert_equal(i['base_class'], expted_class)
165 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
220 nt.assert_equal(i['string_form'], "<class 'IPython.core.tests.test_oinspect.Call'>")
166 fname = __file__
221 fname = __file__
167 if fname.endswith(".pyc"):
222 if fname.endswith(".pyc"):
168 fname = fname[:-1]
223 fname = fname[:-1]
169 # case-insensitive comparison needed on some filesystems
224 # case-insensitive comparison needed on some filesystems
170 # e.g. Windows:
225 # e.g. Windows:
171 nt.assert_equal(i['file'].lower(), fname.lower())
226 nt.assert_equal(i['file'].lower(), fname.lower())
172 nt.assert_equal(i['definition'], 'Call(self, *a, **kw)\n')
227 nt.assert_equal(i['definition'], 'Call(self, *a, **kw)\n')
173 nt.assert_equal(i['docstring'], Call.__doc__)
228 nt.assert_equal(i['docstring'], Call.__doc__)
174 nt.assert_equal(i['source'], None)
229 nt.assert_equal(i['source'], None)
175 nt.assert_true(i['isclass'])
230 nt.assert_true(i['isclass'])
176 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
231 nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n")
177 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
232 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
178
233
179 i = inspector.info(Call, detail_level=1)
234 i = inspector.info(Call, detail_level=1)
180 nt.assert_not_equal(i['source'], None)
235 nt.assert_not_equal(i['source'], None)
181 nt.assert_equal(i['docstring'], None)
236 nt.assert_equal(i['docstring'], None)
182
237
183 c = Call(1)
238 c = Call(1)
184 c.__doc__ = "Modified instance docstring"
239 c.__doc__ = "Modified instance docstring"
185 i = inspector.info(c)
240 i = inspector.info(c)
186 nt.assert_equal(i['type_name'], 'Call')
241 nt.assert_equal(i['type_name'], 'Call')
187 nt.assert_equal(i['docstring'], "Modified instance docstring")
242 nt.assert_equal(i['docstring'], "Modified instance docstring")
188 nt.assert_equal(i['class_docstring'], Call.__doc__)
243 nt.assert_equal(i['class_docstring'], Call.__doc__)
189 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
244 nt.assert_equal(i['init_docstring'], Call.__init__.__doc__)
190 nt.assert_equal(i['call_docstring'], c.__call__.__doc__)
245 nt.assert_equal(i['call_docstring'], c.__call__.__doc__)
191
246
192 # Test old-style classes, which for example may not have an __init__ method.
247 # Test old-style classes, which for example may not have an __init__ method.
193 if not py3compat.PY3:
248 if not py3compat.PY3:
194 i = inspector.info(OldStyle)
249 i = inspector.info(OldStyle)
195 nt.assert_equal(i['type_name'], 'classobj')
250 nt.assert_equal(i['type_name'], 'classobj')
196
251
197 i = inspector.info(OldStyle())
252 i = inspector.info(OldStyle())
198 nt.assert_equal(i['type_name'], 'instance')
253 nt.assert_equal(i['type_name'], 'instance')
199 nt.assert_equal(i['docstring'], OldStyle.__doc__)
254 nt.assert_equal(i['docstring'], OldStyle.__doc__)
200
255
201 def test_getdoc():
256 def test_getdoc():
202 class A(object):
257 class A(object):
203 """standard docstring"""
258 """standard docstring"""
204 pass
259 pass
205
260
206 class B(object):
261 class B(object):
207 """standard docstring"""
262 """standard docstring"""
208 def getdoc(self):
263 def getdoc(self):
209 return "custom docstring"
264 return "custom docstring"
210
265
211 class C(object):
266 class C(object):
212 """standard docstring"""
267 """standard docstring"""
213 def getdoc(self):
268 def getdoc(self):
214 return None
269 return None
215
270
216 a = A()
271 a = A()
217 b = B()
272 b = B()
218 c = C()
273 c = C()
219
274
220 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
275 nt.assert_equal(oinspect.getdoc(a), "standard docstring")
221 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
276 nt.assert_equal(oinspect.getdoc(b), "custom docstring")
222 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
277 nt.assert_equal(oinspect.getdoc(c), "standard docstring")
General Comments 0
You need to be logged in to leave comments. Login now