##// END OF EJS Templates
Added support to list available object types, to use on object type matching in magic function %psearch.
Andreas -
Show More
@@ -1,702 +1,714 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, UsageError
22 from IPython.core.error import StdinNotImplementedError, UsageError
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.openpy import read_py_file
26 from IPython.utils.openpy import read_py_file
27 from IPython.utils.path import get_py_filename
27 from IPython.utils.path import get_py_filename
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Magic implementation classes
30 # Magic implementation classes
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 @magics_class
33 @magics_class
34 class NamespaceMagics(Magics):
34 class NamespaceMagics(Magics):
35 """Magics to manage various aspects of the user's namespace.
35 """Magics to manage various aspects of the user's namespace.
36
36
37 These include listing variables, introspecting into them, etc.
37 These include listing variables, introspecting into them, etc.
38 """
38 """
39
39
40 @line_magic
40 @line_magic
41 def pinfo(self, parameter_s='', namespaces=None):
41 def pinfo(self, parameter_s='', namespaces=None):
42 """Provide detailed information about an object.
42 """Provide detailed information about an object.
43
43
44 '%pinfo object' is just a synonym for object? or ?object."""
44 '%pinfo object' is just a synonym for object? or ?object."""
45
45
46 #print 'pinfo par: <%s>' % parameter_s # dbg
46 #print 'pinfo par: <%s>' % parameter_s # dbg
47 # detail_level: 0 -> obj? , 1 -> obj??
47 # detail_level: 0 -> obj? , 1 -> obj??
48 detail_level = 0
48 detail_level = 0
49 # We need to detect if we got called as 'pinfo pinfo foo', which can
49 # We need to detect if we got called as 'pinfo pinfo foo', which can
50 # happen if the user types 'pinfo foo?' at the cmd line.
50 # happen if the user types 'pinfo foo?' at the cmd line.
51 pinfo,qmark1,oname,qmark2 = \
51 pinfo,qmark1,oname,qmark2 = \
52 re.match(r'(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
52 re.match(r'(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
53 if pinfo or qmark1 or qmark2:
53 if pinfo or qmark1 or qmark2:
54 detail_level = 1
54 detail_level = 1
55 if "*" in oname:
55 if "*" in oname:
56 self.psearch(oname)
56 self.psearch(oname)
57 else:
57 else:
58 self.shell._inspect('pinfo', oname, detail_level=detail_level,
58 self.shell._inspect('pinfo', oname, detail_level=detail_level,
59 namespaces=namespaces)
59 namespaces=namespaces)
60
60
61 @line_magic
61 @line_magic
62 def pinfo2(self, parameter_s='', namespaces=None):
62 def pinfo2(self, parameter_s='', namespaces=None):
63 """Provide extra detailed information about an object.
63 """Provide extra detailed information about an object.
64
64
65 '%pinfo2 object' is just a synonym for object?? or ??object."""
65 '%pinfo2 object' is just a synonym for object?? or ??object."""
66 self.shell._inspect('pinfo', parameter_s, detail_level=1,
66 self.shell._inspect('pinfo', parameter_s, detail_level=1,
67 namespaces=namespaces)
67 namespaces=namespaces)
68
68
69 @skip_doctest
69 @skip_doctest
70 @line_magic
70 @line_magic
71 def pdef(self, parameter_s='', namespaces=None):
71 def pdef(self, parameter_s='', namespaces=None):
72 """Print the call signature for any callable object.
72 """Print the call signature for any callable object.
73
73
74 If the object is a class, print the constructor information.
74 If the object is a class, print the constructor information.
75
75
76 Examples
76 Examples
77 --------
77 --------
78 ::
78 ::
79
79
80 In [3]: %pdef urllib.urlopen
80 In [3]: %pdef urllib.urlopen
81 urllib.urlopen(url, data=None, proxies=None)
81 urllib.urlopen(url, data=None, proxies=None)
82 """
82 """
83 self.shell._inspect('pdef',parameter_s, namespaces)
83 self.shell._inspect('pdef',parameter_s, namespaces)
84
84
85 @line_magic
85 @line_magic
86 def pdoc(self, parameter_s='', namespaces=None):
86 def pdoc(self, parameter_s='', namespaces=None):
87 """Print the docstring for an object.
87 """Print the docstring for an object.
88
88
89 If the given object is a class, it will print both the class and the
89 If the given object is a class, it will print both the class and the
90 constructor docstrings."""
90 constructor docstrings."""
91 self.shell._inspect('pdoc',parameter_s, namespaces)
91 self.shell._inspect('pdoc',parameter_s, namespaces)
92
92
93 @line_magic
93 @line_magic
94 def psource(self, parameter_s='', namespaces=None):
94 def psource(self, parameter_s='', namespaces=None):
95 """Print (or run through pager) the source code for an object."""
95 """Print (or run through pager) the source code for an object."""
96 if not parameter_s:
96 if not parameter_s:
97 raise UsageError('Missing object name.')
97 raise UsageError('Missing object name.')
98 self.shell._inspect('psource',parameter_s, namespaces)
98 self.shell._inspect('psource',parameter_s, namespaces)
99
99
100 @line_magic
100 @line_magic
101 def pfile(self, parameter_s='', namespaces=None):
101 def pfile(self, parameter_s='', namespaces=None):
102 """Print (or run through pager) the file where an object is defined.
102 """Print (or run through pager) the file where an object is defined.
103
103
104 The file opens at the line where the object definition begins. IPython
104 The file opens at the line where the object definition begins. IPython
105 will honor the environment variable PAGER if set, and otherwise will
105 will honor the environment variable PAGER if set, and otherwise will
106 do its best to print the file in a convenient form.
106 do its best to print the file in a convenient form.
107
107
108 If the given argument is not an object currently defined, IPython will
108 If the given argument is not an object currently defined, IPython will
109 try to interpret it as a filename (automatically adding a .py extension
109 try to interpret it as a filename (automatically adding a .py extension
110 if needed). You can thus use %pfile as a syntax highlighting code
110 if needed). You can thus use %pfile as a syntax highlighting code
111 viewer."""
111 viewer."""
112
112
113 # first interpret argument as an object name
113 # first interpret argument as an object name
114 out = self.shell._inspect('pfile',parameter_s, namespaces)
114 out = self.shell._inspect('pfile',parameter_s, namespaces)
115 # if not, try the input as a filename
115 # if not, try the input as a filename
116 if out == 'not found':
116 if out == 'not found':
117 try:
117 try:
118 filename = get_py_filename(parameter_s)
118 filename = get_py_filename(parameter_s)
119 except IOError as msg:
119 except IOError as msg:
120 print(msg)
120 print(msg)
121 return
121 return
122 page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False)))
122 page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False)))
123
123
124 @line_magic
124 @line_magic
125 def psearch(self, parameter_s=''):
125 def psearch(self, parameter_s=''):
126 """Search for object in namespaces by wildcard.
126 """Search for object in namespaces by wildcard.
127
127
128 %psearch [options] PATTERN [OBJECT TYPE]
128 %psearch [options] PATTERN [OBJECT TYPE]
129
129
130 Note: ? can be used as a synonym for %psearch, at the beginning or at
130 Note: ? can be used as a synonym for %psearch, at the beginning or at
131 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
131 the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
132 rest of the command line must be unchanged (options come first), so
132 rest of the command line must be unchanged (options come first), so
133 for example the following forms are equivalent
133 for example the following forms are equivalent
134
134
135 %psearch -i a* function
135 %psearch -i a* function
136 -i a* function?
136 -i a* function?
137 ?-i a* function
137 ?-i a* function
138
138
139 Arguments:
139 Arguments:
140
140
141 PATTERN
141 PATTERN
142
142
143 where PATTERN is a string containing * as a wildcard similar to its
143 where PATTERN is a string containing * as a wildcard similar to its
144 use in a shell. The pattern is matched in all namespaces on the
144 use in a shell. The pattern is matched in all namespaces on the
145 search path. By default objects starting with a single _ are not
145 search path. By default objects starting with a single _ are not
146 matched, many IPython generated objects have a single
146 matched, many IPython generated objects have a single
147 underscore. The default is case insensitive matching. Matching is
147 underscore. The default is case insensitive matching. Matching is
148 also done on the attributes of objects and not only on the objects
148 also done on the attributes of objects and not only on the objects
149 in a module.
149 in a module.
150
150
151 [OBJECT TYPE]
151 [OBJECT TYPE]
152
152
153 Is the name of a python type from the types module. The name is
153 Is the name of a python type from the types module. The name is
154 given in lowercase without the ending type, ex. StringType is
154 given in lowercase without the ending type, ex. StringType is
155 written string. By adding a type here only objects matching the
155 written string. By adding a type here only objects matching the
156 given type are matched. Using all here makes the pattern match all
156 given type are matched. Using all here makes the pattern match all
157 types (this is the default).
157 types (this is the default).
158
158
159 Options:
159 Options:
160
160
161 -a: makes the pattern match even objects whose names start with a
161 -a: makes the pattern match even objects whose names start with a
162 single underscore. These names are normally omitted from the
162 single underscore. These names are normally omitted from the
163 search.
163 search.
164
164
165 -i/-c: make the pattern case insensitive/sensitive. If neither of
165 -i/-c: make the pattern case insensitive/sensitive. If neither of
166 these options are given, the default is read from your configuration
166 these options are given, the default is read from your configuration
167 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
167 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
168 If this option is not specified in your configuration file, IPython's
168 If this option is not specified in your configuration file, IPython's
169 internal default is to do a case sensitive search.
169 internal default is to do a case sensitive search.
170
170
171 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
171 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
172 specify can be searched in any of the following namespaces:
172 specify can be searched in any of the following namespaces:
173 'builtin', 'user', 'user_global','internal', 'alias', where
173 'builtin', 'user', 'user_global','internal', 'alias', where
174 'builtin' and 'user' are the search defaults. Note that you should
174 'builtin' and 'user' are the search defaults. Note that you should
175 not use quotes when specifying namespaces.
175 not use quotes when specifying namespaces.
176
177 -l: List all available object types for object matching. This function
178 can be used without arguments.
176
179
177 'Builtin' contains the python module builtin, 'user' contains all
180 'Builtin' contains the python module builtin, 'user' contains all
178 user data, 'alias' only contain the shell aliases and no python
181 user data, 'alias' only contain the shell aliases and no python
179 objects, 'internal' contains objects used by IPython. The
182 objects, 'internal' contains objects used by IPython. The
180 'user_global' namespace is only used by embedded IPython instances,
183 'user_global' namespace is only used by embedded IPython instances,
181 and it contains module-level globals. You can add namespaces to the
184 and it contains module-level globals. You can add namespaces to the
182 search with -s or exclude them with -e (these options can be given
185 search with -s or exclude them with -e (these options can be given
183 more than once).
186 more than once).
184
187
185 Examples
188 Examples
186 --------
189 --------
187 ::
190 ::
188
191
189 %psearch a* -> objects beginning with an a
192 %psearch a* -> objects beginning with an a
190 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
193 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
191 %psearch a* function -> all functions beginning with an a
194 %psearch a* function -> all functions beginning with an a
192 %psearch re.e* -> objects beginning with an e in module re
195 %psearch re.e* -> objects beginning with an e in module re
193 %psearch r*.e* -> objects that start with e in modules starting in r
196 %psearch r*.e* -> objects that start with e in modules starting in r
194 %psearch r*.* string -> all strings in modules beginning with r
197 %psearch r*.* string -> all strings in modules beginning with r
195
198
196 Case sensitive search::
199 Case sensitive search::
197
200
198 %psearch -c a* list all object beginning with lower case a
201 %psearch -c a* list all object beginning with lower case a
199
202
200 Show objects beginning with a single _::
203 Show objects beginning with a single _::
201
204
202 %psearch -a _* list objects beginning with a single underscore
205 %psearch -a _* list objects beginning with a single underscore
206
207 List available objects::
208
209 %psearch -l list all available object types
203 """
210 """
204 try:
211 try:
205 parameter_s.encode('ascii')
212 parameter_s.encode('ascii')
206 except UnicodeEncodeError:
213 except UnicodeEncodeError:
207 print('Python identifiers can only contain ascii characters.')
214 print('Python identifiers can only contain ascii characters.')
208 return
215 return
209
216
210 # default namespaces to be searched
217 # default namespaces to be searched
211 def_search = ['user_local', 'user_global', 'builtin']
218 def_search = ['user_local', 'user_global', 'builtin']
212
219
213 # Process options/args
220 # Process options/args
214 opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
221 opts,args = self.parse_options(parameter_s,'cias:e:l',list_all=True)
215 opt = opts.get
222 opt = opts.get
216 shell = self.shell
223 shell = self.shell
217 psearch = shell.inspector.psearch
224 psearch = shell.inspector.psearch
225
226 # select list object types
227 list_types = False
228 if 'l' in opts:
229 list_types = True
218
230
219 # select case options
231 # select case options
220 if 'i' in opts:
232 if 'i' in opts:
221 ignore_case = True
233 ignore_case = True
222 elif 'c' in opts:
234 elif 'c' in opts:
223 ignore_case = False
235 ignore_case = False
224 else:
236 else:
225 ignore_case = not shell.wildcards_case_sensitive
237 ignore_case = not shell.wildcards_case_sensitive
226
238
227 # Build list of namespaces to search from user options
239 # Build list of namespaces to search from user options
228 def_search.extend(opt('s',[]))
240 def_search.extend(opt('s',[]))
229 ns_exclude = ns_exclude=opt('e',[])
241 ns_exclude = ns_exclude=opt('e',[])
230 ns_search = [nm for nm in def_search if nm not in ns_exclude]
242 ns_search = [nm for nm in def_search if nm not in ns_exclude]
231
243
232 # Call the actual search
244 # Call the actual search
233 try:
245 try:
234 psearch(args,shell.ns_table,ns_search,
246 psearch(args,shell.ns_table,ns_search,
235 show_all=opt('a'),ignore_case=ignore_case)
247 show_all=opt('a'),ignore_case=ignore_case, list_types=list_types)
236 except:
248 except:
237 shell.showtraceback()
249 shell.showtraceback()
238
250
239 @skip_doctest
251 @skip_doctest
240 @line_magic
252 @line_magic
241 def who_ls(self, parameter_s=''):
253 def who_ls(self, parameter_s=''):
242 """Return a sorted list of all interactive variables.
254 """Return a sorted list of all interactive variables.
243
255
244 If arguments are given, only variables of types matching these
256 If arguments are given, only variables of types matching these
245 arguments are returned.
257 arguments are returned.
246
258
247 Examples
259 Examples
248 --------
260 --------
249
261
250 Define two variables and list them with who_ls::
262 Define two variables and list them with who_ls::
251
263
252 In [1]: alpha = 123
264 In [1]: alpha = 123
253
265
254 In [2]: beta = 'test'
266 In [2]: beta = 'test'
255
267
256 In [3]: %who_ls
268 In [3]: %who_ls
257 Out[3]: ['alpha', 'beta']
269 Out[3]: ['alpha', 'beta']
258
270
259 In [4]: %who_ls int
271 In [4]: %who_ls int
260 Out[4]: ['alpha']
272 Out[4]: ['alpha']
261
273
262 In [5]: %who_ls str
274 In [5]: %who_ls str
263 Out[5]: ['beta']
275 Out[5]: ['beta']
264 """
276 """
265
277
266 user_ns = self.shell.user_ns
278 user_ns = self.shell.user_ns
267 user_ns_hidden = self.shell.user_ns_hidden
279 user_ns_hidden = self.shell.user_ns_hidden
268 nonmatching = object() # This can never be in user_ns
280 nonmatching = object() # This can never be in user_ns
269 out = [ i for i in user_ns
281 out = [ i for i in user_ns
270 if not i.startswith('_') \
282 if not i.startswith('_') \
271 and (user_ns[i] is not user_ns_hidden.get(i, nonmatching)) ]
283 and (user_ns[i] is not user_ns_hidden.get(i, nonmatching)) ]
272
284
273 typelist = parameter_s.split()
285 typelist = parameter_s.split()
274 if typelist:
286 if typelist:
275 typeset = set(typelist)
287 typeset = set(typelist)
276 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
288 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
277
289
278 out.sort()
290 out.sort()
279 return out
291 return out
280
292
281 @skip_doctest
293 @skip_doctest
282 @line_magic
294 @line_magic
283 def who(self, parameter_s=''):
295 def who(self, parameter_s=''):
284 """Print all interactive variables, with some minimal formatting.
296 """Print all interactive variables, with some minimal formatting.
285
297
286 If any arguments are given, only variables whose type matches one of
298 If any arguments are given, only variables whose type matches one of
287 these are printed. For example::
299 these are printed. For example::
288
300
289 %who function str
301 %who function str
290
302
291 will only list functions and strings, excluding all other types of
303 will only list functions and strings, excluding all other types of
292 variables. To find the proper type names, simply use type(var) at a
304 variables. To find the proper type names, simply use type(var) at a
293 command line to see how python prints type names. For example:
305 command line to see how python prints type names. For example:
294
306
295 ::
307 ::
296
308
297 In [1]: type('hello')\\
309 In [1]: type('hello')\\
298 Out[1]: <type 'str'>
310 Out[1]: <type 'str'>
299
311
300 indicates that the type name for strings is 'str'.
312 indicates that the type name for strings is 'str'.
301
313
302 ``%who`` always excludes executed names loaded through your configuration
314 ``%who`` always excludes executed names loaded through your configuration
303 file and things which are internal to IPython.
315 file and things which are internal to IPython.
304
316
305 This is deliberate, as typically you may load many modules and the
317 This is deliberate, as typically you may load many modules and the
306 purpose of %who is to show you only what you've manually defined.
318 purpose of %who is to show you only what you've manually defined.
307
319
308 Examples
320 Examples
309 --------
321 --------
310
322
311 Define two variables and list them with who::
323 Define two variables and list them with who::
312
324
313 In [1]: alpha = 123
325 In [1]: alpha = 123
314
326
315 In [2]: beta = 'test'
327 In [2]: beta = 'test'
316
328
317 In [3]: %who
329 In [3]: %who
318 alpha beta
330 alpha beta
319
331
320 In [4]: %who int
332 In [4]: %who int
321 alpha
333 alpha
322
334
323 In [5]: %who str
335 In [5]: %who str
324 beta
336 beta
325 """
337 """
326
338
327 varlist = self.who_ls(parameter_s)
339 varlist = self.who_ls(parameter_s)
328 if not varlist:
340 if not varlist:
329 if parameter_s:
341 if parameter_s:
330 print('No variables match your requested type.')
342 print('No variables match your requested type.')
331 else:
343 else:
332 print('Interactive namespace is empty.')
344 print('Interactive namespace is empty.')
333 return
345 return
334
346
335 # if we have variables, move on...
347 # if we have variables, move on...
336 count = 0
348 count = 0
337 for i in varlist:
349 for i in varlist:
338 print(i+'\t', end=' ')
350 print(i+'\t', end=' ')
339 count += 1
351 count += 1
340 if count > 8:
352 if count > 8:
341 count = 0
353 count = 0
342 print()
354 print()
343 print()
355 print()
344
356
345 @skip_doctest
357 @skip_doctest
346 @line_magic
358 @line_magic
347 def whos(self, parameter_s=''):
359 def whos(self, parameter_s=''):
348 """Like %who, but gives some extra information about each variable.
360 """Like %who, but gives some extra information about each variable.
349
361
350 The same type filtering of %who can be applied here.
362 The same type filtering of %who can be applied here.
351
363
352 For all variables, the type is printed. Additionally it prints:
364 For all variables, the type is printed. Additionally it prints:
353
365
354 - For {},[],(): their length.
366 - For {},[],(): their length.
355
367
356 - For numpy arrays, a summary with shape, number of
368 - For numpy arrays, a summary with shape, number of
357 elements, typecode and size in memory.
369 elements, typecode and size in memory.
358
370
359 - Everything else: a string representation, snipping their middle if
371 - Everything else: a string representation, snipping their middle if
360 too long.
372 too long.
361
373
362 Examples
374 Examples
363 --------
375 --------
364
376
365 Define two variables and list them with whos::
377 Define two variables and list them with whos::
366
378
367 In [1]: alpha = 123
379 In [1]: alpha = 123
368
380
369 In [2]: beta = 'test'
381 In [2]: beta = 'test'
370
382
371 In [3]: %whos
383 In [3]: %whos
372 Variable Type Data/Info
384 Variable Type Data/Info
373 --------------------------------
385 --------------------------------
374 alpha int 123
386 alpha int 123
375 beta str test
387 beta str test
376 """
388 """
377
389
378 varnames = self.who_ls(parameter_s)
390 varnames = self.who_ls(parameter_s)
379 if not varnames:
391 if not varnames:
380 if parameter_s:
392 if parameter_s:
381 print('No variables match your requested type.')
393 print('No variables match your requested type.')
382 else:
394 else:
383 print('Interactive namespace is empty.')
395 print('Interactive namespace is empty.')
384 return
396 return
385
397
386 # if we have variables, move on...
398 # if we have variables, move on...
387
399
388 # for these types, show len() instead of data:
400 # for these types, show len() instead of data:
389 seq_types = ['dict', 'list', 'tuple']
401 seq_types = ['dict', 'list', 'tuple']
390
402
391 # for numpy arrays, display summary info
403 # for numpy arrays, display summary info
392 ndarray_type = None
404 ndarray_type = None
393 if 'numpy' in sys.modules:
405 if 'numpy' in sys.modules:
394 try:
406 try:
395 from numpy import ndarray
407 from numpy import ndarray
396 except ImportError:
408 except ImportError:
397 pass
409 pass
398 else:
410 else:
399 ndarray_type = ndarray.__name__
411 ndarray_type = ndarray.__name__
400
412
401 # Find all variable names and types so we can figure out column sizes
413 # Find all variable names and types so we can figure out column sizes
402
414
403 # some types are well known and can be shorter
415 # some types are well known and can be shorter
404 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
416 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
405 def type_name(v):
417 def type_name(v):
406 tn = type(v).__name__
418 tn = type(v).__name__
407 return abbrevs.get(tn,tn)
419 return abbrevs.get(tn,tn)
408
420
409 varlist = [self.shell.user_ns[n] for n in varnames]
421 varlist = [self.shell.user_ns[n] for n in varnames]
410
422
411 typelist = []
423 typelist = []
412 for vv in varlist:
424 for vv in varlist:
413 tt = type_name(vv)
425 tt = type_name(vv)
414
426
415 if tt=='instance':
427 if tt=='instance':
416 typelist.append( abbrevs.get(str(vv.__class__),
428 typelist.append( abbrevs.get(str(vv.__class__),
417 str(vv.__class__)))
429 str(vv.__class__)))
418 else:
430 else:
419 typelist.append(tt)
431 typelist.append(tt)
420
432
421 # column labels and # of spaces as separator
433 # column labels and # of spaces as separator
422 varlabel = 'Variable'
434 varlabel = 'Variable'
423 typelabel = 'Type'
435 typelabel = 'Type'
424 datalabel = 'Data/Info'
436 datalabel = 'Data/Info'
425 colsep = 3
437 colsep = 3
426 # variable format strings
438 # variable format strings
427 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
439 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
428 aformat = "%s: %s elems, type `%s`, %s bytes"
440 aformat = "%s: %s elems, type `%s`, %s bytes"
429 # find the size of the columns to format the output nicely
441 # find the size of the columns to format the output nicely
430 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
442 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
431 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
443 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
432 # table header
444 # table header
433 print(varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
445 print(varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
434 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1))
446 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1))
435 # and the table itself
447 # and the table itself
436 kb = 1024
448 kb = 1024
437 Mb = 1048576 # kb**2
449 Mb = 1048576 # kb**2
438 for vname,var,vtype in zip(varnames,varlist,typelist):
450 for vname,var,vtype in zip(varnames,varlist,typelist):
439 print(vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth), end=' ')
451 print(vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth), end=' ')
440 if vtype in seq_types:
452 if vtype in seq_types:
441 print("n="+str(len(var)))
453 print("n="+str(len(var)))
442 elif vtype == ndarray_type:
454 elif vtype == ndarray_type:
443 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
455 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
444 if vtype==ndarray_type:
456 if vtype==ndarray_type:
445 # numpy
457 # numpy
446 vsize = var.size
458 vsize = var.size
447 vbytes = vsize*var.itemsize
459 vbytes = vsize*var.itemsize
448 vdtype = var.dtype
460 vdtype = var.dtype
449
461
450 if vbytes < 100000:
462 if vbytes < 100000:
451 print(aformat % (vshape, vsize, vdtype, vbytes))
463 print(aformat % (vshape, vsize, vdtype, vbytes))
452 else:
464 else:
453 print(aformat % (vshape, vsize, vdtype, vbytes), end=' ')
465 print(aformat % (vshape, vsize, vdtype, vbytes), end=' ')
454 if vbytes < Mb:
466 if vbytes < Mb:
455 print('(%s kb)' % (vbytes/kb,))
467 print('(%s kb)' % (vbytes/kb,))
456 else:
468 else:
457 print('(%s Mb)' % (vbytes/Mb,))
469 print('(%s Mb)' % (vbytes/Mb,))
458 else:
470 else:
459 try:
471 try:
460 vstr = str(var)
472 vstr = str(var)
461 except UnicodeEncodeError:
473 except UnicodeEncodeError:
462 vstr = var.encode(DEFAULT_ENCODING,
474 vstr = var.encode(DEFAULT_ENCODING,
463 'backslashreplace')
475 'backslashreplace')
464 except:
476 except:
465 vstr = "<object with id %d (str() failed)>" % id(var)
477 vstr = "<object with id %d (str() failed)>" % id(var)
466 vstr = vstr.replace('\n', '\\n')
478 vstr = vstr.replace('\n', '\\n')
467 if len(vstr) < 50:
479 if len(vstr) < 50:
468 print(vstr)
480 print(vstr)
469 else:
481 else:
470 print(vstr[:25] + "<...>" + vstr[-25:])
482 print(vstr[:25] + "<...>" + vstr[-25:])
471
483
472 @line_magic
484 @line_magic
473 def reset(self, parameter_s=''):
485 def reset(self, parameter_s=''):
474 """Resets the namespace by removing all names defined by the user, if
486 """Resets the namespace by removing all names defined by the user, if
475 called without arguments, or by removing some types of objects, such
487 called without arguments, or by removing some types of objects, such
476 as everything currently in IPython's In[] and Out[] containers (see
488 as everything currently in IPython's In[] and Out[] containers (see
477 the parameters for details).
489 the parameters for details).
478
490
479 Parameters
491 Parameters
480 ----------
492 ----------
481 -f : force reset without asking for confirmation.
493 -f : force reset without asking for confirmation.
482
494
483 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
495 -s : 'Soft' reset: Only clears your namespace, leaving history intact.
484 References to objects may be kept. By default (without this option),
496 References to objects may be kept. By default (without this option),
485 we do a 'hard' reset, giving you a new session and removing all
497 we do a 'hard' reset, giving you a new session and removing all
486 references to objects from the current session.
498 references to objects from the current session.
487
499
488 in : reset input history
500 in : reset input history
489
501
490 out : reset output history
502 out : reset output history
491
503
492 dhist : reset directory history
504 dhist : reset directory history
493
505
494 array : reset only variables that are NumPy arrays
506 array : reset only variables that are NumPy arrays
495
507
496 See Also
508 See Also
497 --------
509 --------
498 reset_selective : invoked as ``%reset_selective``
510 reset_selective : invoked as ``%reset_selective``
499
511
500 Examples
512 Examples
501 --------
513 --------
502 ::
514 ::
503
515
504 In [6]: a = 1
516 In [6]: a = 1
505
517
506 In [7]: a
518 In [7]: a
507 Out[7]: 1
519 Out[7]: 1
508
520
509 In [8]: 'a' in _ip.user_ns
521 In [8]: 'a' in _ip.user_ns
510 Out[8]: True
522 Out[8]: True
511
523
512 In [9]: %reset -f
524 In [9]: %reset -f
513
525
514 In [1]: 'a' in _ip.user_ns
526 In [1]: 'a' in _ip.user_ns
515 Out[1]: False
527 Out[1]: False
516
528
517 In [2]: %reset -f in
529 In [2]: %reset -f in
518 Flushing input history
530 Flushing input history
519
531
520 In [3]: %reset -f dhist in
532 In [3]: %reset -f dhist in
521 Flushing directory history
533 Flushing directory history
522 Flushing input history
534 Flushing input history
523
535
524 Notes
536 Notes
525 -----
537 -----
526 Calling this magic from clients that do not implement standard input,
538 Calling this magic from clients that do not implement standard input,
527 such as the ipython notebook interface, will reset the namespace
539 such as the ipython notebook interface, will reset the namespace
528 without confirmation.
540 without confirmation.
529 """
541 """
530 opts, args = self.parse_options(parameter_s,'sf', mode='list')
542 opts, args = self.parse_options(parameter_s,'sf', mode='list')
531 if 'f' in opts:
543 if 'f' in opts:
532 ans = True
544 ans = True
533 else:
545 else:
534 try:
546 try:
535 ans = self.shell.ask_yes_no(
547 ans = self.shell.ask_yes_no(
536 "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
548 "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
537 default='n')
549 default='n')
538 except StdinNotImplementedError:
550 except StdinNotImplementedError:
539 ans = True
551 ans = True
540 if not ans:
552 if not ans:
541 print('Nothing done.')
553 print('Nothing done.')
542 return
554 return
543
555
544 if 's' in opts: # Soft reset
556 if 's' in opts: # Soft reset
545 user_ns = self.shell.user_ns
557 user_ns = self.shell.user_ns
546 for i in self.who_ls():
558 for i in self.who_ls():
547 del(user_ns[i])
559 del(user_ns[i])
548 elif len(args) == 0: # Hard reset
560 elif len(args) == 0: # Hard reset
549 self.shell.reset(new_session = False)
561 self.shell.reset(new_session = False)
550
562
551 # reset in/out/dhist/array: previously extensinions/clearcmd.py
563 # reset in/out/dhist/array: previously extensinions/clearcmd.py
552 ip = self.shell
564 ip = self.shell
553 user_ns = self.shell.user_ns # local lookup, heavily used
565 user_ns = self.shell.user_ns # local lookup, heavily used
554
566
555 for target in args:
567 for target in args:
556 target = target.lower() # make matches case insensitive
568 target = target.lower() # make matches case insensitive
557 if target == 'out':
569 if target == 'out':
558 print("Flushing output cache (%d entries)" % len(user_ns['_oh']))
570 print("Flushing output cache (%d entries)" % len(user_ns['_oh']))
559 self.shell.displayhook.flush()
571 self.shell.displayhook.flush()
560
572
561 elif target == 'in':
573 elif target == 'in':
562 print("Flushing input history")
574 print("Flushing input history")
563 pc = self.shell.displayhook.prompt_count + 1
575 pc = self.shell.displayhook.prompt_count + 1
564 for n in range(1, pc):
576 for n in range(1, pc):
565 key = '_i'+repr(n)
577 key = '_i'+repr(n)
566 user_ns.pop(key,None)
578 user_ns.pop(key,None)
567 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
579 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
568 hm = ip.history_manager
580 hm = ip.history_manager
569 # don't delete these, as %save and %macro depending on the
581 # don't delete these, as %save and %macro depending on the
570 # length of these lists to be preserved
582 # length of these lists to be preserved
571 hm.input_hist_parsed[:] = [''] * pc
583 hm.input_hist_parsed[:] = [''] * pc
572 hm.input_hist_raw[:] = [''] * pc
584 hm.input_hist_raw[:] = [''] * pc
573 # hm has internal machinery for _i,_ii,_iii, clear it out
585 # hm has internal machinery for _i,_ii,_iii, clear it out
574 hm._i = hm._ii = hm._iii = hm._i00 = u''
586 hm._i = hm._ii = hm._iii = hm._i00 = u''
575
587
576 elif target == 'array':
588 elif target == 'array':
577 # Support cleaning up numpy arrays
589 # Support cleaning up numpy arrays
578 try:
590 try:
579 from numpy import ndarray
591 from numpy import ndarray
580 # This must be done with items and not iteritems because
592 # This must be done with items and not iteritems because
581 # we're going to modify the dict in-place.
593 # we're going to modify the dict in-place.
582 for x,val in list(user_ns.items()):
594 for x,val in list(user_ns.items()):
583 if isinstance(val,ndarray):
595 if isinstance(val,ndarray):
584 del user_ns[x]
596 del user_ns[x]
585 except ImportError:
597 except ImportError:
586 print("reset array only works if Numpy is available.")
598 print("reset array only works if Numpy is available.")
587
599
588 elif target == 'dhist':
600 elif target == 'dhist':
589 print("Flushing directory history")
601 print("Flushing directory history")
590 del user_ns['_dh'][:]
602 del user_ns['_dh'][:]
591
603
592 else:
604 else:
593 print("Don't know how to reset ", end=' ')
605 print("Don't know how to reset ", end=' ')
594 print(target + ", please run `%reset?` for details")
606 print(target + ", please run `%reset?` for details")
595
607
596 gc.collect()
608 gc.collect()
597
609
598 @line_magic
610 @line_magic
599 def reset_selective(self, parameter_s=''):
611 def reset_selective(self, parameter_s=''):
600 """Resets the namespace by removing names defined by the user.
612 """Resets the namespace by removing names defined by the user.
601
613
602 Input/Output history are left around in case you need them.
614 Input/Output history are left around in case you need them.
603
615
604 %reset_selective [-f] regex
616 %reset_selective [-f] regex
605
617
606 No action is taken if regex is not included
618 No action is taken if regex is not included
607
619
608 Options
620 Options
609 -f : force reset without asking for confirmation.
621 -f : force reset without asking for confirmation.
610
622
611 See Also
623 See Also
612 --------
624 --------
613 reset : invoked as ``%reset``
625 reset : invoked as ``%reset``
614
626
615 Examples
627 Examples
616 --------
628 --------
617
629
618 We first fully reset the namespace so your output looks identical to
630 We first fully reset the namespace so your output looks identical to
619 this example for pedagogical reasons; in practice you do not need a
631 this example for pedagogical reasons; in practice you do not need a
620 full reset::
632 full reset::
621
633
622 In [1]: %reset -f
634 In [1]: %reset -f
623
635
624 Now, with a clean namespace we can make a few variables and use
636 Now, with a clean namespace we can make a few variables and use
625 ``%reset_selective`` to only delete names that match our regexp::
637 ``%reset_selective`` to only delete names that match our regexp::
626
638
627 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
639 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
628
640
629 In [3]: who_ls
641 In [3]: who_ls
630 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
642 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
631
643
632 In [4]: %reset_selective -f b[2-3]m
644 In [4]: %reset_selective -f b[2-3]m
633
645
634 In [5]: who_ls
646 In [5]: who_ls
635 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
647 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
636
648
637 In [6]: %reset_selective -f d
649 In [6]: %reset_selective -f d
638
650
639 In [7]: who_ls
651 In [7]: who_ls
640 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
652 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
641
653
642 In [8]: %reset_selective -f c
654 In [8]: %reset_selective -f c
643
655
644 In [9]: who_ls
656 In [9]: who_ls
645 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
657 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
646
658
647 In [10]: %reset_selective -f b
659 In [10]: %reset_selective -f b
648
660
649 In [11]: who_ls
661 In [11]: who_ls
650 Out[11]: ['a']
662 Out[11]: ['a']
651
663
652 Notes
664 Notes
653 -----
665 -----
654 Calling this magic from clients that do not implement standard input,
666 Calling this magic from clients that do not implement standard input,
655 such as the ipython notebook interface, will reset the namespace
667 such as the ipython notebook interface, will reset the namespace
656 without confirmation.
668 without confirmation.
657 """
669 """
658
670
659 opts, regex = self.parse_options(parameter_s,'f')
671 opts, regex = self.parse_options(parameter_s,'f')
660
672
661 if 'f' in opts:
673 if 'f' in opts:
662 ans = True
674 ans = True
663 else:
675 else:
664 try:
676 try:
665 ans = self.shell.ask_yes_no(
677 ans = self.shell.ask_yes_no(
666 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
678 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
667 default='n')
679 default='n')
668 except StdinNotImplementedError:
680 except StdinNotImplementedError:
669 ans = True
681 ans = True
670 if not ans:
682 if not ans:
671 print('Nothing done.')
683 print('Nothing done.')
672 return
684 return
673 user_ns = self.shell.user_ns
685 user_ns = self.shell.user_ns
674 if not regex:
686 if not regex:
675 print('No regex pattern specified. Nothing done.')
687 print('No regex pattern specified. Nothing done.')
676 return
688 return
677 else:
689 else:
678 try:
690 try:
679 m = re.compile(regex)
691 m = re.compile(regex)
680 except TypeError:
692 except TypeError:
681 raise TypeError('regex must be a string or compiled pattern')
693 raise TypeError('regex must be a string or compiled pattern')
682 for i in self.who_ls():
694 for i in self.who_ls():
683 if m.search(i):
695 if m.search(i):
684 del(user_ns[i])
696 del(user_ns[i])
685
697
686 @line_magic
698 @line_magic
687 def xdel(self, parameter_s=''):
699 def xdel(self, parameter_s=''):
688 """Delete a variable, trying to clear it from anywhere that
700 """Delete a variable, trying to clear it from anywhere that
689 IPython's machinery has references to it. By default, this uses
701 IPython's machinery has references to it. By default, this uses
690 the identity of the named object in the user namespace to remove
702 the identity of the named object in the user namespace to remove
691 references held under other names. The object is also removed
703 references held under other names. The object is also removed
692 from the output history.
704 from the output history.
693
705
694 Options
706 Options
695 -n : Delete the specified name from all namespaces, without
707 -n : Delete the specified name from all namespaces, without
696 checking their identity.
708 checking their identity.
697 """
709 """
698 opts, varname = self.parse_options(parameter_s,'n')
710 opts, varname = self.parse_options(parameter_s,'n')
699 try:
711 try:
700 self.shell.del_var(varname, ('n' in opts))
712 self.shell.del_var(varname, ('n' in opts))
701 except (NameError, ValueError) as e:
713 except (NameError, ValueError) as e:
702 print(type(e).__name__ +": "+ str(e))
714 print(type(e).__name__ +": "+ str(e))
@@ -1,1064 +1,1072 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 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 __all__ = ['Inspector','InspectColors']
13 __all__ = ['Inspector','InspectColors']
14
14
15 # stdlib modules
15 # stdlib modules
16 import ast
16 import ast
17 import inspect
17 import inspect
18 from inspect import signature
18 from inspect import signature
19 import linecache
19 import linecache
20 import warnings
20 import warnings
21 import os
21 import os
22 from textwrap import dedent
22 from textwrap import dedent
23 import types
23 import types
24 import io as stdlib_io
24 import io as stdlib_io
25 from itertools import zip_longest
25 from itertools import zip_longest
26
26
27 # IPython's own
27 # IPython's own
28 from IPython.core import page
28 from IPython.core import page
29 from IPython.lib.pretty import pretty
29 from IPython.lib.pretty import pretty
30 from IPython.testing.skipdoctest import skip_doctest
30 from IPython.testing.skipdoctest import skip_doctest
31 from IPython.utils import PyColorize
31 from IPython.utils import PyColorize
32 from IPython.utils import openpy
32 from IPython.utils import openpy
33 from IPython.utils import py3compat
33 from IPython.utils import py3compat
34 from IPython.utils.dir2 import safe_hasattr
34 from IPython.utils.dir2 import safe_hasattr
35 from IPython.utils.path import compress_user
35 from IPython.utils.path import compress_user
36 from IPython.utils.text import indent
36 from IPython.utils.text import indent
37 from IPython.utils.wildcard import list_namespace
37 from IPython.utils.wildcard import list_namespace
38 from IPython.utils.wildcard import typestr2type
38 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
39 from IPython.utils.coloransi import TermColors, ColorScheme, ColorSchemeTable
39 from IPython.utils.py3compat import cast_unicode
40 from IPython.utils.py3compat import cast_unicode
40 from IPython.utils.colorable import Colorable
41 from IPython.utils.colorable import Colorable
41 from IPython.utils.decorators import undoc
42 from IPython.utils.decorators import undoc
42
43
43 from pygments import highlight
44 from pygments import highlight
44 from pygments.lexers import PythonLexer
45 from pygments.lexers import PythonLexer
45 from pygments.formatters import HtmlFormatter
46 from pygments.formatters import HtmlFormatter
46
47
47 def pylight(code):
48 def pylight(code):
48 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
49 return highlight(code, PythonLexer(), HtmlFormatter(noclasses=True))
49
50
50 # builtin docstrings to ignore
51 # builtin docstrings to ignore
51 _func_call_docstring = types.FunctionType.__call__.__doc__
52 _func_call_docstring = types.FunctionType.__call__.__doc__
52 _object_init_docstring = object.__init__.__doc__
53 _object_init_docstring = object.__init__.__doc__
53 _builtin_type_docstrings = {
54 _builtin_type_docstrings = {
54 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
55 inspect.getdoc(t) for t in (types.ModuleType, types.MethodType,
55 types.FunctionType, property)
56 types.FunctionType, property)
56 }
57 }
57
58
58 _builtin_func_type = type(all)
59 _builtin_func_type = type(all)
59 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
60 _builtin_meth_type = type(str.upper) # Bound methods have the same type as builtin functions
60 #****************************************************************************
61 #****************************************************************************
61 # Builtin color schemes
62 # Builtin color schemes
62
63
63 Colors = TermColors # just a shorthand
64 Colors = TermColors # just a shorthand
64
65
65 InspectColors = PyColorize.ANSICodeColors
66 InspectColors = PyColorize.ANSICodeColors
66
67
67 #****************************************************************************
68 #****************************************************************************
68 # Auxiliary functions and objects
69 # Auxiliary functions and objects
69
70
70 # See the messaging spec for the definition of all these fields. This list
71 # See the messaging spec for the definition of all these fields. This list
71 # effectively defines the order of display
72 # effectively defines the order of display
72 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
73 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
73 'length', 'file', 'definition', 'docstring', 'source',
74 'length', 'file', 'definition', 'docstring', 'source',
74 'init_definition', 'class_docstring', 'init_docstring',
75 'init_definition', 'class_docstring', 'init_docstring',
75 'call_def', 'call_docstring',
76 'call_def', 'call_docstring',
76 # These won't be printed but will be used to determine how to
77 # These won't be printed but will be used to determine how to
77 # format the object
78 # format the object
78 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
79 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
79 ]
80 ]
80
81
81
82
82 def object_info(**kw):
83 def object_info(**kw):
83 """Make an object info dict with all fields present."""
84 """Make an object info dict with all fields present."""
84 infodict = dict(zip_longest(info_fields, [None]))
85 infodict = dict(zip_longest(info_fields, [None]))
85 infodict.update(kw)
86 infodict.update(kw)
86 return infodict
87 return infodict
87
88
88
89
89 def get_encoding(obj):
90 def get_encoding(obj):
90 """Get encoding for python source file defining obj
91 """Get encoding for python source file defining obj
91
92
92 Returns None if obj is not defined in a sourcefile.
93 Returns None if obj is not defined in a sourcefile.
93 """
94 """
94 ofile = find_file(obj)
95 ofile = find_file(obj)
95 # run contents of file through pager starting at line where the object
96 # run contents of file through pager starting at line where the object
96 # is defined, as long as the file isn't binary and is actually on the
97 # is defined, as long as the file isn't binary and is actually on the
97 # filesystem.
98 # filesystem.
98 if ofile is None:
99 if ofile is None:
99 return None
100 return None
100 elif ofile.endswith(('.so', '.dll', '.pyd')):
101 elif ofile.endswith(('.so', '.dll', '.pyd')):
101 return None
102 return None
102 elif not os.path.isfile(ofile):
103 elif not os.path.isfile(ofile):
103 return None
104 return None
104 else:
105 else:
105 # Print only text files, not extension binaries. Note that
106 # Print only text files, not extension binaries. Note that
106 # getsourcelines returns lineno with 1-offset and page() uses
107 # getsourcelines returns lineno with 1-offset and page() uses
107 # 0-offset, so we must adjust.
108 # 0-offset, so we must adjust.
108 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
109 with stdlib_io.open(ofile, 'rb') as buffer: # Tweaked to use io.open for Python 2
109 encoding, lines = openpy.detect_encoding(buffer.readline)
110 encoding, lines = openpy.detect_encoding(buffer.readline)
110 return encoding
111 return encoding
111
112
112 def getdoc(obj):
113 def getdoc(obj):
113 """Stable wrapper around inspect.getdoc.
114 """Stable wrapper around inspect.getdoc.
114
115
115 This can't crash because of attribute problems.
116 This can't crash because of attribute problems.
116
117
117 It also attempts to call a getdoc() method on the given object. This
118 It also attempts to call a getdoc() method on the given object. This
118 allows objects which provide their docstrings via non-standard mechanisms
119 allows objects which provide their docstrings via non-standard mechanisms
119 (like Pyro proxies) to still be inspected by ipython's ? system.
120 (like Pyro proxies) to still be inspected by ipython's ? system.
120 """
121 """
121 # Allow objects to offer customized documentation via a getdoc method:
122 # Allow objects to offer customized documentation via a getdoc method:
122 try:
123 try:
123 ds = obj.getdoc()
124 ds = obj.getdoc()
124 except Exception:
125 except Exception:
125 pass
126 pass
126 else:
127 else:
127 if isinstance(ds, str):
128 if isinstance(ds, str):
128 return inspect.cleandoc(ds)
129 return inspect.cleandoc(ds)
129 docstr = inspect.getdoc(obj)
130 docstr = inspect.getdoc(obj)
130 encoding = get_encoding(obj)
131 encoding = get_encoding(obj)
131 return py3compat.cast_unicode(docstr, encoding=encoding)
132 return py3compat.cast_unicode(docstr, encoding=encoding)
132
133
133
134
134 def getsource(obj, oname=''):
135 def getsource(obj, oname=''):
135 """Wrapper around inspect.getsource.
136 """Wrapper around inspect.getsource.
136
137
137 This can be modified by other projects to provide customized source
138 This can be modified by other projects to provide customized source
138 extraction.
139 extraction.
139
140
140 Parameters
141 Parameters
141 ----------
142 ----------
142 obj : object
143 obj : object
143 an object whose source code we will attempt to extract
144 an object whose source code we will attempt to extract
144 oname : str
145 oname : str
145 (optional) a name under which the object is known
146 (optional) a name under which the object is known
146
147
147 Returns
148 Returns
148 -------
149 -------
149 src : unicode or None
150 src : unicode or None
150
151
151 """
152 """
152
153
153 if isinstance(obj, property):
154 if isinstance(obj, property):
154 sources = []
155 sources = []
155 for attrname in ['fget', 'fset', 'fdel']:
156 for attrname in ['fget', 'fset', 'fdel']:
156 fn = getattr(obj, attrname)
157 fn = getattr(obj, attrname)
157 if fn is not None:
158 if fn is not None:
158 encoding = get_encoding(fn)
159 encoding = get_encoding(fn)
159 oname_prefix = ('%s.' % oname) if oname else ''
160 oname_prefix = ('%s.' % oname) if oname else ''
160 sources.append(cast_unicode(
161 sources.append(cast_unicode(
161 ''.join(('# ', oname_prefix, attrname)),
162 ''.join(('# ', oname_prefix, attrname)),
162 encoding=encoding))
163 encoding=encoding))
163 if inspect.isfunction(fn):
164 if inspect.isfunction(fn):
164 sources.append(dedent(getsource(fn)))
165 sources.append(dedent(getsource(fn)))
165 else:
166 else:
166 # Default str/repr only prints function name,
167 # Default str/repr only prints function name,
167 # pretty.pretty prints module name too.
168 # pretty.pretty prints module name too.
168 sources.append(cast_unicode(
169 sources.append(cast_unicode(
169 '%s%s = %s\n' % (
170 '%s%s = %s\n' % (
170 oname_prefix, attrname, pretty(fn)),
171 oname_prefix, attrname, pretty(fn)),
171 encoding=encoding))
172 encoding=encoding))
172 if sources:
173 if sources:
173 return '\n'.join(sources)
174 return '\n'.join(sources)
174 else:
175 else:
175 return None
176 return None
176
177
177 else:
178 else:
178 # Get source for non-property objects.
179 # Get source for non-property objects.
179
180
180 obj = _get_wrapped(obj)
181 obj = _get_wrapped(obj)
181
182
182 try:
183 try:
183 src = inspect.getsource(obj)
184 src = inspect.getsource(obj)
184 except TypeError:
185 except TypeError:
185 # The object itself provided no meaningful source, try looking for
186 # The object itself provided no meaningful source, try looking for
186 # its class definition instead.
187 # its class definition instead.
187 if hasattr(obj, '__class__'):
188 if hasattr(obj, '__class__'):
188 try:
189 try:
189 src = inspect.getsource(obj.__class__)
190 src = inspect.getsource(obj.__class__)
190 except TypeError:
191 except TypeError:
191 return None
192 return None
192
193
193 encoding = get_encoding(obj)
194 encoding = get_encoding(obj)
194 return cast_unicode(src, encoding=encoding)
195 return cast_unicode(src, encoding=encoding)
195
196
196
197
197 def is_simple_callable(obj):
198 def is_simple_callable(obj):
198 """True if obj is a function ()"""
199 """True if obj is a function ()"""
199 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
200 return (inspect.isfunction(obj) or inspect.ismethod(obj) or \
200 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
201 isinstance(obj, _builtin_func_type) or isinstance(obj, _builtin_meth_type))
201
202
202
203
203 def getargspec(obj):
204 def getargspec(obj):
204 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
205 """Wrapper around :func:`inspect.getfullargspec` on Python 3, and
205 :func:inspect.getargspec` on Python 2.
206 :func:inspect.getargspec` on Python 2.
206
207
207 In addition to functions and methods, this can also handle objects with a
208 In addition to functions and methods, this can also handle objects with a
208 ``__call__`` attribute.
209 ``__call__`` attribute.
209 """
210 """
210 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
211 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
211 obj = obj.__call__
212 obj = obj.__call__
212
213
213 return inspect.getfullargspec(obj)
214 return inspect.getfullargspec(obj)
214
215
215
216
216 def format_argspec(argspec):
217 def format_argspec(argspec):
217 """Format argspect, convenience wrapper around inspect's.
218 """Format argspect, convenience wrapper around inspect's.
218
219
219 This takes a dict instead of ordered arguments and calls
220 This takes a dict instead of ordered arguments and calls
220 inspect.format_argspec with the arguments in the necessary order.
221 inspect.format_argspec with the arguments in the necessary order.
221 """
222 """
222 return inspect.formatargspec(argspec['args'], argspec['varargs'],
223 return inspect.formatargspec(argspec['args'], argspec['varargs'],
223 argspec['varkw'], argspec['defaults'])
224 argspec['varkw'], argspec['defaults'])
224
225
225 @undoc
226 @undoc
226 def call_tip(oinfo, format_call=True):
227 def call_tip(oinfo, format_call=True):
227 """DEPRECATED. Extract call tip data from an oinfo dict.
228 """DEPRECATED. Extract call tip data from an oinfo dict.
228 """
229 """
229 warnings.warn('`call_tip` function is deprecated as of IPython 6.0'
230 warnings.warn('`call_tip` function is deprecated as of IPython 6.0'
230 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
231 'and will be removed in future versions.', DeprecationWarning, stacklevel=2)
231 # Get call definition
232 # Get call definition
232 argspec = oinfo.get('argspec')
233 argspec = oinfo.get('argspec')
233 if argspec is None:
234 if argspec is None:
234 call_line = None
235 call_line = None
235 else:
236 else:
236 # Callable objects will have 'self' as their first argument, prune
237 # Callable objects will have 'self' as their first argument, prune
237 # it out if it's there for clarity (since users do *not* pass an
238 # it out if it's there for clarity (since users do *not* pass an
238 # extra first argument explicitly).
239 # extra first argument explicitly).
239 try:
240 try:
240 has_self = argspec['args'][0] == 'self'
241 has_self = argspec['args'][0] == 'self'
241 except (KeyError, IndexError):
242 except (KeyError, IndexError):
242 pass
243 pass
243 else:
244 else:
244 if has_self:
245 if has_self:
245 argspec['args'] = argspec['args'][1:]
246 argspec['args'] = argspec['args'][1:]
246
247
247 call_line = oinfo['name']+format_argspec(argspec)
248 call_line = oinfo['name']+format_argspec(argspec)
248
249
249 # Now get docstring.
250 # Now get docstring.
250 # The priority is: call docstring, constructor docstring, main one.
251 # The priority is: call docstring, constructor docstring, main one.
251 doc = oinfo.get('call_docstring')
252 doc = oinfo.get('call_docstring')
252 if doc is None:
253 if doc is None:
253 doc = oinfo.get('init_docstring')
254 doc = oinfo.get('init_docstring')
254 if doc is None:
255 if doc is None:
255 doc = oinfo.get('docstring','')
256 doc = oinfo.get('docstring','')
256
257
257 return call_line, doc
258 return call_line, doc
258
259
259
260
260 def _get_wrapped(obj):
261 def _get_wrapped(obj):
261 """Get the original object if wrapped in one or more @decorators
262 """Get the original object if wrapped in one or more @decorators
262
263
263 Some objects automatically construct similar objects on any unrecognised
264 Some objects automatically construct similar objects on any unrecognised
264 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
265 attribute access (e.g. unittest.mock.call). To protect against infinite loops,
265 this will arbitrarily cut off after 100 levels of obj.__wrapped__
266 this will arbitrarily cut off after 100 levels of obj.__wrapped__
266 attribute access. --TK, Jan 2016
267 attribute access. --TK, Jan 2016
267 """
268 """
268 orig_obj = obj
269 orig_obj = obj
269 i = 0
270 i = 0
270 while safe_hasattr(obj, '__wrapped__'):
271 while safe_hasattr(obj, '__wrapped__'):
271 obj = obj.__wrapped__
272 obj = obj.__wrapped__
272 i += 1
273 i += 1
273 if i > 100:
274 if i > 100:
274 # __wrapped__ is probably a lie, so return the thing we started with
275 # __wrapped__ is probably a lie, so return the thing we started with
275 return orig_obj
276 return orig_obj
276 return obj
277 return obj
277
278
278 def find_file(obj):
279 def find_file(obj):
279 """Find the absolute path to the file where an object was defined.
280 """Find the absolute path to the file where an object was defined.
280
281
281 This is essentially a robust wrapper around `inspect.getabsfile`.
282 This is essentially a robust wrapper around `inspect.getabsfile`.
282
283
283 Returns None if no file can be found.
284 Returns None if no file can be found.
284
285
285 Parameters
286 Parameters
286 ----------
287 ----------
287 obj : any Python object
288 obj : any Python object
288
289
289 Returns
290 Returns
290 -------
291 -------
291 fname : str
292 fname : str
292 The absolute path to the file where the object was defined.
293 The absolute path to the file where the object was defined.
293 """
294 """
294 obj = _get_wrapped(obj)
295 obj = _get_wrapped(obj)
295
296
296 fname = None
297 fname = None
297 try:
298 try:
298 fname = inspect.getabsfile(obj)
299 fname = inspect.getabsfile(obj)
299 except TypeError:
300 except TypeError:
300 # For an instance, the file that matters is where its class was
301 # For an instance, the file that matters is where its class was
301 # declared.
302 # declared.
302 if hasattr(obj, '__class__'):
303 if hasattr(obj, '__class__'):
303 try:
304 try:
304 fname = inspect.getabsfile(obj.__class__)
305 fname = inspect.getabsfile(obj.__class__)
305 except TypeError:
306 except TypeError:
306 # Can happen for builtins
307 # Can happen for builtins
307 pass
308 pass
308 except:
309 except:
309 pass
310 pass
310 return cast_unicode(fname)
311 return cast_unicode(fname)
311
312
312
313
313 def find_source_lines(obj):
314 def find_source_lines(obj):
314 """Find the line number in a file where an object was defined.
315 """Find the line number in a file where an object was defined.
315
316
316 This is essentially a robust wrapper around `inspect.getsourcelines`.
317 This is essentially a robust wrapper around `inspect.getsourcelines`.
317
318
318 Returns None if no file can be found.
319 Returns None if no file can be found.
319
320
320 Parameters
321 Parameters
321 ----------
322 ----------
322 obj : any Python object
323 obj : any Python object
323
324
324 Returns
325 Returns
325 -------
326 -------
326 lineno : int
327 lineno : int
327 The line number where the object definition starts.
328 The line number where the object definition starts.
328 """
329 """
329 obj = _get_wrapped(obj)
330 obj = _get_wrapped(obj)
330
331
331 try:
332 try:
332 try:
333 try:
333 lineno = inspect.getsourcelines(obj)[1]
334 lineno = inspect.getsourcelines(obj)[1]
334 except TypeError:
335 except TypeError:
335 # For instances, try the class object like getsource() does
336 # For instances, try the class object like getsource() does
336 if hasattr(obj, '__class__'):
337 if hasattr(obj, '__class__'):
337 lineno = inspect.getsourcelines(obj.__class__)[1]
338 lineno = inspect.getsourcelines(obj.__class__)[1]
338 else:
339 else:
339 lineno = None
340 lineno = None
340 except:
341 except:
341 return None
342 return None
342
343
343 return lineno
344 return lineno
344
345
345 class Inspector(Colorable):
346 class Inspector(Colorable):
346
347
347 def __init__(self, color_table=InspectColors,
348 def __init__(self, color_table=InspectColors,
348 code_color_table=PyColorize.ANSICodeColors,
349 code_color_table=PyColorize.ANSICodeColors,
349 scheme=None,
350 scheme=None,
350 str_detail_level=0,
351 str_detail_level=0,
351 parent=None, config=None):
352 parent=None, config=None):
352 super(Inspector, self).__init__(parent=parent, config=config)
353 super(Inspector, self).__init__(parent=parent, config=config)
353 self.color_table = color_table
354 self.color_table = color_table
354 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
355 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
355 self.format = self.parser.format
356 self.format = self.parser.format
356 self.str_detail_level = str_detail_level
357 self.str_detail_level = str_detail_level
357 self.set_active_scheme(scheme)
358 self.set_active_scheme(scheme)
358
359
359 def _getdef(self,obj,oname=''):
360 def _getdef(self,obj,oname=''):
360 """Return the call signature for any callable object.
361 """Return the call signature for any callable object.
361
362
362 If any exception is generated, None is returned instead and the
363 If any exception is generated, None is returned instead and the
363 exception is suppressed."""
364 exception is suppressed."""
364 try:
365 try:
365 hdef = _render_signature(signature(obj), oname)
366 hdef = _render_signature(signature(obj), oname)
366 return cast_unicode(hdef)
367 return cast_unicode(hdef)
367 except:
368 except:
368 return None
369 return None
369
370
370 def __head(self,h):
371 def __head(self,h):
371 """Return a header string with proper colors."""
372 """Return a header string with proper colors."""
372 return '%s%s%s' % (self.color_table.active_colors.header,h,
373 return '%s%s%s' % (self.color_table.active_colors.header,h,
373 self.color_table.active_colors.normal)
374 self.color_table.active_colors.normal)
374
375
375 def set_active_scheme(self, scheme):
376 def set_active_scheme(self, scheme):
376 if scheme is not None:
377 if scheme is not None:
377 self.color_table.set_active_scheme(scheme)
378 self.color_table.set_active_scheme(scheme)
378 self.parser.color_table.set_active_scheme(scheme)
379 self.parser.color_table.set_active_scheme(scheme)
379
380
380 def noinfo(self, msg, oname):
381 def noinfo(self, msg, oname):
381 """Generic message when no information is found."""
382 """Generic message when no information is found."""
382 print('No %s found' % msg, end=' ')
383 print('No %s found' % msg, end=' ')
383 if oname:
384 if oname:
384 print('for %s' % oname)
385 print('for %s' % oname)
385 else:
386 else:
386 print()
387 print()
387
388
388 def pdef(self, obj, oname=''):
389 def pdef(self, obj, oname=''):
389 """Print the call signature for any callable object.
390 """Print the call signature for any callable object.
390
391
391 If the object is a class, print the constructor information."""
392 If the object is a class, print the constructor information."""
392
393
393 if not callable(obj):
394 if not callable(obj):
394 print('Object is not callable.')
395 print('Object is not callable.')
395 return
396 return
396
397
397 header = ''
398 header = ''
398
399
399 if inspect.isclass(obj):
400 if inspect.isclass(obj):
400 header = self.__head('Class constructor information:\n')
401 header = self.__head('Class constructor information:\n')
401
402
402
403
403 output = self._getdef(obj,oname)
404 output = self._getdef(obj,oname)
404 if output is None:
405 if output is None:
405 self.noinfo('definition header',oname)
406 self.noinfo('definition header',oname)
406 else:
407 else:
407 print(header,self.format(output), end=' ')
408 print(header,self.format(output), end=' ')
408
409
409 # In Python 3, all classes are new-style, so they all have __init__.
410 # In Python 3, all classes are new-style, so they all have __init__.
410 @skip_doctest
411 @skip_doctest
411 def pdoc(self, obj, oname='', formatter=None):
412 def pdoc(self, obj, oname='', formatter=None):
412 """Print the docstring for any object.
413 """Print the docstring for any object.
413
414
414 Optional:
415 Optional:
415 -formatter: a function to run the docstring through for specially
416 -formatter: a function to run the docstring through for specially
416 formatted docstrings.
417 formatted docstrings.
417
418
418 Examples
419 Examples
419 --------
420 --------
420
421
421 In [1]: class NoInit:
422 In [1]: class NoInit:
422 ...: pass
423 ...: pass
423
424
424 In [2]: class NoDoc:
425 In [2]: class NoDoc:
425 ...: def __init__(self):
426 ...: def __init__(self):
426 ...: pass
427 ...: pass
427
428
428 In [3]: %pdoc NoDoc
429 In [3]: %pdoc NoDoc
429 No documentation found for NoDoc
430 No documentation found for NoDoc
430
431
431 In [4]: %pdoc NoInit
432 In [4]: %pdoc NoInit
432 No documentation found for NoInit
433 No documentation found for NoInit
433
434
434 In [5]: obj = NoInit()
435 In [5]: obj = NoInit()
435
436
436 In [6]: %pdoc obj
437 In [6]: %pdoc obj
437 No documentation found for obj
438 No documentation found for obj
438
439
439 In [5]: obj2 = NoDoc()
440 In [5]: obj2 = NoDoc()
440
441
441 In [6]: %pdoc obj2
442 In [6]: %pdoc obj2
442 No documentation found for obj2
443 No documentation found for obj2
443 """
444 """
444
445
445 head = self.__head # For convenience
446 head = self.__head # For convenience
446 lines = []
447 lines = []
447 ds = getdoc(obj)
448 ds = getdoc(obj)
448 if formatter:
449 if formatter:
449 ds = formatter(ds).get('plain/text', ds)
450 ds = formatter(ds).get('plain/text', ds)
450 if ds:
451 if ds:
451 lines.append(head("Class docstring:"))
452 lines.append(head("Class docstring:"))
452 lines.append(indent(ds))
453 lines.append(indent(ds))
453 if inspect.isclass(obj) and hasattr(obj, '__init__'):
454 if inspect.isclass(obj) and hasattr(obj, '__init__'):
454 init_ds = getdoc(obj.__init__)
455 init_ds = getdoc(obj.__init__)
455 if init_ds is not None:
456 if init_ds is not None:
456 lines.append(head("Init docstring:"))
457 lines.append(head("Init docstring:"))
457 lines.append(indent(init_ds))
458 lines.append(indent(init_ds))
458 elif hasattr(obj,'__call__'):
459 elif hasattr(obj,'__call__'):
459 call_ds = getdoc(obj.__call__)
460 call_ds = getdoc(obj.__call__)
460 if call_ds:
461 if call_ds:
461 lines.append(head("Call docstring:"))
462 lines.append(head("Call docstring:"))
462 lines.append(indent(call_ds))
463 lines.append(indent(call_ds))
463
464
464 if not lines:
465 if not lines:
465 self.noinfo('documentation',oname)
466 self.noinfo('documentation',oname)
466 else:
467 else:
467 page.page('\n'.join(lines))
468 page.page('\n'.join(lines))
468
469
469 def psource(self, obj, oname=''):
470 def psource(self, obj, oname=''):
470 """Print the source code for an object."""
471 """Print the source code for an object."""
471
472
472 # Flush the source cache because inspect can return out-of-date source
473 # Flush the source cache because inspect can return out-of-date source
473 linecache.checkcache()
474 linecache.checkcache()
474 try:
475 try:
475 src = getsource(obj, oname=oname)
476 src = getsource(obj, oname=oname)
476 except Exception:
477 except Exception:
477 src = None
478 src = None
478
479
479 if src is None:
480 if src is None:
480 self.noinfo('source', oname)
481 self.noinfo('source', oname)
481 else:
482 else:
482 page.page(self.format(src))
483 page.page(self.format(src))
483
484
484 def pfile(self, obj, oname=''):
485 def pfile(self, obj, oname=''):
485 """Show the whole file where an object was defined."""
486 """Show the whole file where an object was defined."""
486
487
487 lineno = find_source_lines(obj)
488 lineno = find_source_lines(obj)
488 if lineno is None:
489 if lineno is None:
489 self.noinfo('file', oname)
490 self.noinfo('file', oname)
490 return
491 return
491
492
492 ofile = find_file(obj)
493 ofile = find_file(obj)
493 # run contents of file through pager starting at line where the object
494 # run contents of file through pager starting at line where the object
494 # is defined, as long as the file isn't binary and is actually on the
495 # is defined, as long as the file isn't binary and is actually on the
495 # filesystem.
496 # filesystem.
496 if ofile.endswith(('.so', '.dll', '.pyd')):
497 if ofile.endswith(('.so', '.dll', '.pyd')):
497 print('File %r is binary, not printing.' % ofile)
498 print('File %r is binary, not printing.' % ofile)
498 elif not os.path.isfile(ofile):
499 elif not os.path.isfile(ofile):
499 print('File %r does not exist, not printing.' % ofile)
500 print('File %r does not exist, not printing.' % ofile)
500 else:
501 else:
501 # Print only text files, not extension binaries. Note that
502 # Print only text files, not extension binaries. Note that
502 # getsourcelines returns lineno with 1-offset and page() uses
503 # getsourcelines returns lineno with 1-offset and page() uses
503 # 0-offset, so we must adjust.
504 # 0-offset, so we must adjust.
504 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
505 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
505
506
506 def _format_fields(self, fields, title_width=0):
507 def _format_fields(self, fields, title_width=0):
507 """Formats a list of fields for display.
508 """Formats a list of fields for display.
508
509
509 Parameters
510 Parameters
510 ----------
511 ----------
511 fields : list
512 fields : list
512 A list of 2-tuples: (field_title, field_content)
513 A list of 2-tuples: (field_title, field_content)
513 title_width : int
514 title_width : int
514 How many characters to pad titles to. Default to longest title.
515 How many characters to pad titles to. Default to longest title.
515 """
516 """
516 out = []
517 out = []
517 header = self.__head
518 header = self.__head
518 if title_width == 0:
519 if title_width == 0:
519 title_width = max(len(title) + 2 for title, _ in fields)
520 title_width = max(len(title) + 2 for title, _ in fields)
520 for title, content in fields:
521 for title, content in fields:
521 if len(content.splitlines()) > 1:
522 if len(content.splitlines()) > 1:
522 title = header(title + ':') + '\n'
523 title = header(title + ':') + '\n'
523 else:
524 else:
524 title = header((title + ':').ljust(title_width))
525 title = header((title + ':').ljust(title_width))
525 out.append(cast_unicode(title) + cast_unicode(content))
526 out.append(cast_unicode(title) + cast_unicode(content))
526 return "\n".join(out)
527 return "\n".join(out)
527
528
528 def _mime_format(self, text, formatter=None):
529 def _mime_format(self, text, formatter=None):
529 """Return a mime bundle representation of the input text.
530 """Return a mime bundle representation of the input text.
530
531
531 - if `formatter` is None, the returned mime bundle has
532 - if `formatter` is None, the returned mime bundle has
532 a `text/plain` field, with the input text.
533 a `text/plain` field, with the input text.
533 a `text/html` field with a `<pre>` tag containing the input text.
534 a `text/html` field with a `<pre>` tag containing the input text.
534
535
535 - if `formatter` is not None, it must be a callable transforming the
536 - if `formatter` is not None, it must be a callable transforming the
536 input text into a mime bundle. Default values for `text/plain` and
537 input text into a mime bundle. Default values for `text/plain` and
537 `text/html` representations are the ones described above.
538 `text/html` representations are the ones described above.
538
539
539 Note:
540 Note:
540
541
541 Formatters returning strings are supported but this behavior is deprecated.
542 Formatters returning strings are supported but this behavior is deprecated.
542
543
543 """
544 """
544 text = cast_unicode(text)
545 text = cast_unicode(text)
545 defaults = {
546 defaults = {
546 'text/plain': text,
547 'text/plain': text,
547 'text/html': '<pre>' + text + '</pre>'
548 'text/html': '<pre>' + text + '</pre>'
548 }
549 }
549
550
550 if formatter is None:
551 if formatter is None:
551 return defaults
552 return defaults
552 else:
553 else:
553 formatted = formatter(text)
554 formatted = formatter(text)
554
555
555 if not isinstance(formatted, dict):
556 if not isinstance(formatted, dict):
556 # Handle the deprecated behavior of a formatter returning
557 # Handle the deprecated behavior of a formatter returning
557 # a string instead of a mime bundle.
558 # a string instead of a mime bundle.
558 return {
559 return {
559 'text/plain': formatted,
560 'text/plain': formatted,
560 'text/html': '<pre>' + formatted + '</pre>'
561 'text/html': '<pre>' + formatted + '</pre>'
561 }
562 }
562
563
563 else:
564 else:
564 return dict(defaults, **formatted)
565 return dict(defaults, **formatted)
565
566
566
567
567 def format_mime(self, bundle):
568 def format_mime(self, bundle):
568
569
569 text_plain = bundle['text/plain']
570 text_plain = bundle['text/plain']
570
571
571 text = ''
572 text = ''
572 heads, bodies = list(zip(*text_plain))
573 heads, bodies = list(zip(*text_plain))
573 _len = max(len(h) for h in heads)
574 _len = max(len(h) for h in heads)
574
575
575 for head, body in zip(heads, bodies):
576 for head, body in zip(heads, bodies):
576 body = body.strip('\n')
577 body = body.strip('\n')
577 delim = '\n' if '\n' in body else ' '
578 delim = '\n' if '\n' in body else ' '
578 text += self.__head(head+':') + (_len - len(head))*' ' +delim + body +'\n'
579 text += self.__head(head+':') + (_len - len(head))*' ' +delim + body +'\n'
579
580
580 bundle['text/plain'] = text
581 bundle['text/plain'] = text
581 return bundle
582 return bundle
582
583
583 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
584 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
584 """Retrieve an info dict and format it.
585 """Retrieve an info dict and format it.
585
586
586 Parameters
587 Parameters
587 ==========
588 ==========
588
589
589 obj: any
590 obj: any
590 Object to inspect and return info from
591 Object to inspect and return info from
591 oname: str (default: ''):
592 oname: str (default: ''):
592 Name of the variable pointing to `obj`.
593 Name of the variable pointing to `obj`.
593 formatter: callable
594 formatter: callable
594 info:
595 info:
595 already computed information
596 already computed information
596 detail_level: integer
597 detail_level: integer
597 Granularity of detail level, if set to 1, give more information.
598 Granularity of detail level, if set to 1, give more information.
598 """
599 """
599
600
600 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
601 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
601
602
602 _mime = {
603 _mime = {
603 'text/plain': [],
604 'text/plain': [],
604 'text/html': '',
605 'text/html': '',
605 }
606 }
606
607
607 def append_field(bundle, title, key, formatter=None):
608 def append_field(bundle, title, key, formatter=None):
608 field = info[key]
609 field = info[key]
609 if field is not None:
610 if field is not None:
610 formatted_field = self._mime_format(field, formatter)
611 formatted_field = self._mime_format(field, formatter)
611 bundle['text/plain'].append((title, formatted_field['text/plain']))
612 bundle['text/plain'].append((title, formatted_field['text/plain']))
612 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
613 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
613
614
614 def code_formatter(text):
615 def code_formatter(text):
615 return {
616 return {
616 'text/plain': self.format(text),
617 'text/plain': self.format(text),
617 'text/html': pylight(text)
618 'text/html': pylight(text)
618 }
619 }
619
620
620 if info['isalias']:
621 if info['isalias']:
621 append_field(_mime, 'Repr', 'string_form')
622 append_field(_mime, 'Repr', 'string_form')
622
623
623 elif info['ismagic']:
624 elif info['ismagic']:
624 if detail_level > 0:
625 if detail_level > 0:
625 append_field(_mime, 'Source', 'source', code_formatter)
626 append_field(_mime, 'Source', 'source', code_formatter)
626 else:
627 else:
627 append_field(_mime, 'Docstring', 'docstring', formatter)
628 append_field(_mime, 'Docstring', 'docstring', formatter)
628 append_field(_mime, 'File', 'file')
629 append_field(_mime, 'File', 'file')
629
630
630 elif info['isclass'] or is_simple_callable(obj):
631 elif info['isclass'] or is_simple_callable(obj):
631 # Functions, methods, classes
632 # Functions, methods, classes
632 append_field(_mime, 'Signature', 'definition', code_formatter)
633 append_field(_mime, 'Signature', 'definition', code_formatter)
633 append_field(_mime, 'Init signature', 'init_definition', code_formatter)
634 append_field(_mime, 'Init signature', 'init_definition', code_formatter)
634 append_field(_mime, 'Docstring', 'docstring', formatter)
635 append_field(_mime, 'Docstring', 'docstring', formatter)
635 if detail_level > 0 and info['source']:
636 if detail_level > 0 and info['source']:
636 append_field(_mime, 'Source', 'source', code_formatter)
637 append_field(_mime, 'Source', 'source', code_formatter)
637 else:
638 else:
638 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
639 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
639
640
640 append_field(_mime, 'File', 'file')
641 append_field(_mime, 'File', 'file')
641 append_field(_mime, 'Type', 'type_name')
642 append_field(_mime, 'Type', 'type_name')
642 append_field(_mime, 'Subclasses', 'subclasses')
643 append_field(_mime, 'Subclasses', 'subclasses')
643
644
644 else:
645 else:
645 # General Python objects
646 # General Python objects
646 append_field(_mime, 'Signature', 'definition', code_formatter)
647 append_field(_mime, 'Signature', 'definition', code_formatter)
647 append_field(_mime, 'Call signature', 'call_def', code_formatter)
648 append_field(_mime, 'Call signature', 'call_def', code_formatter)
648 append_field(_mime, 'Type', 'type_name')
649 append_field(_mime, 'Type', 'type_name')
649 append_field(_mime, 'String form', 'string_form')
650 append_field(_mime, 'String form', 'string_form')
650
651
651 # Namespace
652 # Namespace
652 if info['namespace'] != 'Interactive':
653 if info['namespace'] != 'Interactive':
653 append_field(_mime, 'Namespace', 'namespace')
654 append_field(_mime, 'Namespace', 'namespace')
654
655
655 append_field(_mime, 'Length', 'length')
656 append_field(_mime, 'Length', 'length')
656 append_field(_mime, 'File', 'file')
657 append_field(_mime, 'File', 'file')
657
658
658 # Source or docstring, depending on detail level and whether
659 # Source or docstring, depending on detail level and whether
659 # source found.
660 # source found.
660 if detail_level > 0 and info['source']:
661 if detail_level > 0 and info['source']:
661 append_field(_mime, 'Source', 'source', code_formatter)
662 append_field(_mime, 'Source', 'source', code_formatter)
662 else:
663 else:
663 append_field(_mime, 'Docstring', 'docstring', formatter)
664 append_field(_mime, 'Docstring', 'docstring', formatter)
664
665
665 append_field(_mime, 'Class docstring', 'class_docstring', formatter)
666 append_field(_mime, 'Class docstring', 'class_docstring', formatter)
666 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
667 append_field(_mime, 'Init docstring', 'init_docstring', formatter)
667 append_field(_mime, 'Call docstring', 'call_docstring', formatter)
668 append_field(_mime, 'Call docstring', 'call_docstring', formatter)
668
669
669
670
670 return self.format_mime(_mime)
671 return self.format_mime(_mime)
671
672
672 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0, enable_html_pager=True):
673 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0, enable_html_pager=True):
673 """Show detailed information about an object.
674 """Show detailed information about an object.
674
675
675 Optional arguments:
676 Optional arguments:
676
677
677 - oname: name of the variable pointing to the object.
678 - oname: name of the variable pointing to the object.
678
679
679 - formatter: callable (optional)
680 - formatter: callable (optional)
680 A special formatter for docstrings.
681 A special formatter for docstrings.
681
682
682 The formatter is a callable that takes a string as an input
683 The formatter is a callable that takes a string as an input
683 and returns either a formatted string or a mime type bundle
684 and returns either a formatted string or a mime type bundle
684 in the form of a dictionary.
685 in the form of a dictionary.
685
686
686 Although the support of custom formatter returning a string
687 Although the support of custom formatter returning a string
687 instead of a mime type bundle is deprecated.
688 instead of a mime type bundle is deprecated.
688
689
689 - info: a structure with some information fields which may have been
690 - info: a structure with some information fields which may have been
690 precomputed already.
691 precomputed already.
691
692
692 - detail_level: if set to 1, more information is given.
693 - detail_level: if set to 1, more information is given.
693 """
694 """
694 info = self._get_info(obj, oname, formatter, info, detail_level)
695 info = self._get_info(obj, oname, formatter, info, detail_level)
695 if not enable_html_pager:
696 if not enable_html_pager:
696 del info['text/html']
697 del info['text/html']
697 page.page(info)
698 page.page(info)
698
699
699 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
700 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
700 """DEPRECATED. Compute a dict with detailed information about an object.
701 """DEPRECATED. Compute a dict with detailed information about an object.
701 """
702 """
702 if formatter is not None:
703 if formatter is not None:
703 warnings.warn('The `formatter` keyword argument to `Inspector.info`'
704 warnings.warn('The `formatter` keyword argument to `Inspector.info`'
704 'is deprecated as of IPython 5.0 and will have no effects.',
705 'is deprecated as of IPython 5.0 and will have no effects.',
705 DeprecationWarning, stacklevel=2)
706 DeprecationWarning, stacklevel=2)
706 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
707 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
707
708
708 def _info(self, obj, oname='', info=None, detail_level=0) -> dict:
709 def _info(self, obj, oname='', info=None, detail_level=0) -> dict:
709 """Compute a dict with detailed information about an object.
710 """Compute a dict with detailed information about an object.
710
711
711 Parameters
712 Parameters
712 ==========
713 ==========
713
714
714 obj: any
715 obj: any
715 An object to find information about
716 An object to find information about
716 oname: str (default: ''):
717 oname: str (default: ''):
717 Name of the variable pointing to `obj`.
718 Name of the variable pointing to `obj`.
718 info: (default: None)
719 info: (default: None)
719 A struct (dict like with attr access) with some information fields
720 A struct (dict like with attr access) with some information fields
720 which may have been precomputed already.
721 which may have been precomputed already.
721 detail_level: int (default:0)
722 detail_level: int (default:0)
722 If set to 1, more information is given.
723 If set to 1, more information is given.
723
724
724 Returns
725 Returns
725 =======
726 =======
726
727
727 An object info dict with known fields from `info_fields`.
728 An object info dict with known fields from `info_fields`.
728 """
729 """
729
730
730 if info is None:
731 if info is None:
731 ismagic = False
732 ismagic = False
732 isalias = False
733 isalias = False
733 ospace = ''
734 ospace = ''
734 else:
735 else:
735 ismagic = info.ismagic
736 ismagic = info.ismagic
736 isalias = info.isalias
737 isalias = info.isalias
737 ospace = info.namespace
738 ospace = info.namespace
738
739
739 # Get docstring, special-casing aliases:
740 # Get docstring, special-casing aliases:
740 if isalias:
741 if isalias:
741 if not callable(obj):
742 if not callable(obj):
742 try:
743 try:
743 ds = "Alias to the system command:\n %s" % obj[1]
744 ds = "Alias to the system command:\n %s" % obj[1]
744 except:
745 except:
745 ds = "Alias: " + str(obj)
746 ds = "Alias: " + str(obj)
746 else:
747 else:
747 ds = "Alias to " + str(obj)
748 ds = "Alias to " + str(obj)
748 if obj.__doc__:
749 if obj.__doc__:
749 ds += "\nDocstring:\n" + obj.__doc__
750 ds += "\nDocstring:\n" + obj.__doc__
750 else:
751 else:
751 ds = getdoc(obj)
752 ds = getdoc(obj)
752 if ds is None:
753 if ds is None:
753 ds = '<no docstring>'
754 ds = '<no docstring>'
754
755
755 # store output in a dict, we initialize it here and fill it as we go
756 # store output in a dict, we initialize it here and fill it as we go
756 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None)
757 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None)
757
758
758 string_max = 200 # max size of strings to show (snipped if longer)
759 string_max = 200 # max size of strings to show (snipped if longer)
759 shalf = int((string_max - 5) / 2)
760 shalf = int((string_max - 5) / 2)
760
761
761 if ismagic:
762 if ismagic:
762 out['type_name'] = 'Magic function'
763 out['type_name'] = 'Magic function'
763 elif isalias:
764 elif isalias:
764 out['type_name'] = 'System alias'
765 out['type_name'] = 'System alias'
765 else:
766 else:
766 out['type_name'] = type(obj).__name__
767 out['type_name'] = type(obj).__name__
767
768
768 try:
769 try:
769 bclass = obj.__class__
770 bclass = obj.__class__
770 out['base_class'] = str(bclass)
771 out['base_class'] = str(bclass)
771 except:
772 except:
772 pass
773 pass
773
774
774 # String form, but snip if too long in ? form (full in ??)
775 # String form, but snip if too long in ? form (full in ??)
775 if detail_level >= self.str_detail_level:
776 if detail_level >= self.str_detail_level:
776 try:
777 try:
777 ostr = str(obj)
778 ostr = str(obj)
778 str_head = 'string_form'
779 str_head = 'string_form'
779 if not detail_level and len(ostr)>string_max:
780 if not detail_level and len(ostr)>string_max:
780 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
781 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
781 ostr = ("\n" + " " * len(str_head.expandtabs())).\
782 ostr = ("\n" + " " * len(str_head.expandtabs())).\
782 join(q.strip() for q in ostr.split("\n"))
783 join(q.strip() for q in ostr.split("\n"))
783 out[str_head] = ostr
784 out[str_head] = ostr
784 except:
785 except:
785 pass
786 pass
786
787
787 if ospace:
788 if ospace:
788 out['namespace'] = ospace
789 out['namespace'] = ospace
789
790
790 # Length (for strings and lists)
791 # Length (for strings and lists)
791 try:
792 try:
792 out['length'] = str(len(obj))
793 out['length'] = str(len(obj))
793 except Exception:
794 except Exception:
794 pass
795 pass
795
796
796 # Filename where object was defined
797 # Filename where object was defined
797 binary_file = False
798 binary_file = False
798 fname = find_file(obj)
799 fname = find_file(obj)
799 if fname is None:
800 if fname is None:
800 # if anything goes wrong, we don't want to show source, so it's as
801 # if anything goes wrong, we don't want to show source, so it's as
801 # if the file was binary
802 # if the file was binary
802 binary_file = True
803 binary_file = True
803 else:
804 else:
804 if fname.endswith(('.so', '.dll', '.pyd')):
805 if fname.endswith(('.so', '.dll', '.pyd')):
805 binary_file = True
806 binary_file = True
806 elif fname.endswith('<string>'):
807 elif fname.endswith('<string>'):
807 fname = 'Dynamically generated function. No source code available.'
808 fname = 'Dynamically generated function. No source code available.'
808 out['file'] = compress_user(fname)
809 out['file'] = compress_user(fname)
809
810
810 # Original source code for a callable, class or property.
811 # Original source code for a callable, class or property.
811 if detail_level:
812 if detail_level:
812 # Flush the source cache because inspect can return out-of-date
813 # Flush the source cache because inspect can return out-of-date
813 # source
814 # source
814 linecache.checkcache()
815 linecache.checkcache()
815 try:
816 try:
816 if isinstance(obj, property) or not binary_file:
817 if isinstance(obj, property) or not binary_file:
817 src = getsource(obj, oname)
818 src = getsource(obj, oname)
818 if src is not None:
819 if src is not None:
819 src = src.rstrip()
820 src = src.rstrip()
820 out['source'] = src
821 out['source'] = src
821
822
822 except Exception:
823 except Exception:
823 pass
824 pass
824
825
825 # Add docstring only if no source is to be shown (avoid repetitions).
826 # Add docstring only if no source is to be shown (avoid repetitions).
826 if ds and not self._source_contains_docstring(out.get('source'), ds):
827 if ds and not self._source_contains_docstring(out.get('source'), ds):
827 out['docstring'] = ds
828 out['docstring'] = ds
828
829
829 # Constructor docstring for classes
830 # Constructor docstring for classes
830 if inspect.isclass(obj):
831 if inspect.isclass(obj):
831 out['isclass'] = True
832 out['isclass'] = True
832
833
833 # get the init signature:
834 # get the init signature:
834 try:
835 try:
835 init_def = self._getdef(obj, oname)
836 init_def = self._getdef(obj, oname)
836 except AttributeError:
837 except AttributeError:
837 init_def = None
838 init_def = None
838
839
839 # get the __init__ docstring
840 # get the __init__ docstring
840 try:
841 try:
841 obj_init = obj.__init__
842 obj_init = obj.__init__
842 except AttributeError:
843 except AttributeError:
843 init_ds = None
844 init_ds = None
844 else:
845 else:
845 if init_def is None:
846 if init_def is None:
846 # Get signature from init if top-level sig failed.
847 # Get signature from init if top-level sig failed.
847 # Can happen for built-in types (list, etc.).
848 # Can happen for built-in types (list, etc.).
848 try:
849 try:
849 init_def = self._getdef(obj_init, oname)
850 init_def = self._getdef(obj_init, oname)
850 except AttributeError:
851 except AttributeError:
851 pass
852 pass
852 init_ds = getdoc(obj_init)
853 init_ds = getdoc(obj_init)
853 # Skip Python's auto-generated docstrings
854 # Skip Python's auto-generated docstrings
854 if init_ds == _object_init_docstring:
855 if init_ds == _object_init_docstring:
855 init_ds = None
856 init_ds = None
856
857
857 if init_def:
858 if init_def:
858 out['init_definition'] = init_def
859 out['init_definition'] = init_def
859
860
860 if init_ds:
861 if init_ds:
861 out['init_docstring'] = init_ds
862 out['init_docstring'] = init_ds
862
863
863 names = [sub.__name__ for sub in type.__subclasses__(obj)]
864 names = [sub.__name__ for sub in type.__subclasses__(obj)]
864 if len(names) < 10:
865 if len(names) < 10:
865 all_names = ', '.join(names)
866 all_names = ', '.join(names)
866 else:
867 else:
867 all_names = ', '.join(names[:10]+['...'])
868 all_names = ', '.join(names[:10]+['...'])
868 out['subclasses'] = all_names
869 out['subclasses'] = all_names
869 # and class docstring for instances:
870 # and class docstring for instances:
870 else:
871 else:
871 # reconstruct the function definition and print it:
872 # reconstruct the function definition and print it:
872 defln = self._getdef(obj, oname)
873 defln = self._getdef(obj, oname)
873 if defln:
874 if defln:
874 out['definition'] = defln
875 out['definition'] = defln
875
876
876 # First, check whether the instance docstring is identical to the
877 # First, check whether the instance docstring is identical to the
877 # class one, and print it separately if they don't coincide. In
878 # class one, and print it separately if they don't coincide. In
878 # most cases they will, but it's nice to print all the info for
879 # most cases they will, but it's nice to print all the info for
879 # objects which use instance-customized docstrings.
880 # objects which use instance-customized docstrings.
880 if ds:
881 if ds:
881 try:
882 try:
882 cls = getattr(obj,'__class__')
883 cls = getattr(obj,'__class__')
883 except:
884 except:
884 class_ds = None
885 class_ds = None
885 else:
886 else:
886 class_ds = getdoc(cls)
887 class_ds = getdoc(cls)
887 # Skip Python's auto-generated docstrings
888 # Skip Python's auto-generated docstrings
888 if class_ds in _builtin_type_docstrings:
889 if class_ds in _builtin_type_docstrings:
889 class_ds = None
890 class_ds = None
890 if class_ds and ds != class_ds:
891 if class_ds and ds != class_ds:
891 out['class_docstring'] = class_ds
892 out['class_docstring'] = class_ds
892
893
893 # Next, try to show constructor docstrings
894 # Next, try to show constructor docstrings
894 try:
895 try:
895 init_ds = getdoc(obj.__init__)
896 init_ds = getdoc(obj.__init__)
896 # Skip Python's auto-generated docstrings
897 # Skip Python's auto-generated docstrings
897 if init_ds == _object_init_docstring:
898 if init_ds == _object_init_docstring:
898 init_ds = None
899 init_ds = None
899 except AttributeError:
900 except AttributeError:
900 init_ds = None
901 init_ds = None
901 if init_ds:
902 if init_ds:
902 out['init_docstring'] = init_ds
903 out['init_docstring'] = init_ds
903
904
904 # Call form docstring for callable instances
905 # Call form docstring for callable instances
905 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
906 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
906 call_def = self._getdef(obj.__call__, oname)
907 call_def = self._getdef(obj.__call__, oname)
907 if call_def and (call_def != out.get('definition')):
908 if call_def and (call_def != out.get('definition')):
908 # it may never be the case that call def and definition differ,
909 # it may never be the case that call def and definition differ,
909 # but don't include the same signature twice
910 # but don't include the same signature twice
910 out['call_def'] = call_def
911 out['call_def'] = call_def
911 call_ds = getdoc(obj.__call__)
912 call_ds = getdoc(obj.__call__)
912 # Skip Python's auto-generated docstrings
913 # Skip Python's auto-generated docstrings
913 if call_ds == _func_call_docstring:
914 if call_ds == _func_call_docstring:
914 call_ds = None
915 call_ds = None
915 if call_ds:
916 if call_ds:
916 out['call_docstring'] = call_ds
917 out['call_docstring'] = call_ds
917
918
918 # Compute the object's argspec as a callable. The key is to decide
919 # Compute the object's argspec as a callable. The key is to decide
919 # whether to pull it from the object itself, from its __init__ or
920 # whether to pull it from the object itself, from its __init__ or
920 # from its __call__ method.
921 # from its __call__ method.
921
922
922 if inspect.isclass(obj):
923 if inspect.isclass(obj):
923 # Old-style classes need not have an __init__
924 # Old-style classes need not have an __init__
924 callable_obj = getattr(obj, "__init__", None)
925 callable_obj = getattr(obj, "__init__", None)
925 elif callable(obj):
926 elif callable(obj):
926 callable_obj = obj
927 callable_obj = obj
927 else:
928 else:
928 callable_obj = None
929 callable_obj = None
929
930
930 if callable_obj is not None:
931 if callable_obj is not None:
931 try:
932 try:
932 argspec = getargspec(callable_obj)
933 argspec = getargspec(callable_obj)
933 except Exception:
934 except Exception:
934 # For extensions/builtins we can't retrieve the argspec
935 # For extensions/builtins we can't retrieve the argspec
935 pass
936 pass
936 else:
937 else:
937 # named tuples' _asdict() method returns an OrderedDict, but we
938 # named tuples' _asdict() method returns an OrderedDict, but we
938 # we want a normal
939 # we want a normal
939 out['argspec'] = argspec_dict = dict(argspec._asdict())
940 out['argspec'] = argspec_dict = dict(argspec._asdict())
940 # We called this varkw before argspec became a named tuple.
941 # We called this varkw before argspec became a named tuple.
941 # With getfullargspec it's also called varkw.
942 # With getfullargspec it's also called varkw.
942 if 'varkw' not in argspec_dict:
943 if 'varkw' not in argspec_dict:
943 argspec_dict['varkw'] = argspec_dict.pop('keywords')
944 argspec_dict['varkw'] = argspec_dict.pop('keywords')
944
945
945 return object_info(**out)
946 return object_info(**out)
946
947
947 @staticmethod
948 @staticmethod
948 def _source_contains_docstring(src, doc):
949 def _source_contains_docstring(src, doc):
949 """
950 """
950 Check whether the source *src* contains the docstring *doc*.
951 Check whether the source *src* contains the docstring *doc*.
951
952
952 This is is helper function to skip displaying the docstring if the
953 This is is helper function to skip displaying the docstring if the
953 source already contains it, avoiding repetition of information.
954 source already contains it, avoiding repetition of information.
954 """
955 """
955 try:
956 try:
956 def_node, = ast.parse(dedent(src)).body
957 def_node, = ast.parse(dedent(src)).body
957 return ast.get_docstring(def_node) == doc
958 return ast.get_docstring(def_node) == doc
958 except Exception:
959 except Exception:
959 # The source can become invalid or even non-existent (because it
960 # The source can become invalid or even non-existent (because it
960 # is re-fetched from the source file) so the above code fail in
961 # is re-fetched from the source file) so the above code fail in
961 # arbitrary ways.
962 # arbitrary ways.
962 return False
963 return False
963
964
964 def psearch(self,pattern,ns_table,ns_search=[],
965 def psearch(self,pattern,ns_table,ns_search=[],
965 ignore_case=False,show_all=False):
966 ignore_case=False,show_all=False, list_types=False):
966 """Search namespaces with wildcards for objects.
967 """Search namespaces with wildcards for objects.
967
968
968 Arguments:
969 Arguments:
969
970
970 - pattern: string containing shell-like wildcards to use in namespace
971 - pattern: string containing shell-like wildcards to use in namespace
971 searches and optionally a type specification to narrow the search to
972 searches and optionally a type specification to narrow the search to
972 objects of that type.
973 objects of that type.
973
974
974 - ns_table: dict of name->namespaces for search.
975 - ns_table: dict of name->namespaces for search.
975
976
976 Optional arguments:
977 Optional arguments:
977
978
978 - ns_search: list of namespace names to include in search.
979 - ns_search: list of namespace names to include in search.
979
980
980 - ignore_case(False): make the search case-insensitive.
981 - ignore_case(False): make the search case-insensitive.
981
982
982 - show_all(False): show all names, including those starting with
983 - show_all(False): show all names, including those starting with
983 underscores.
984 underscores.
985
986 - list_types(False): list all available object types for object matching.
984 """
987 """
985 #print 'ps pattern:<%r>' % pattern # dbg
988 #print 'ps pattern:<%r>' % pattern # dbg
986
989
987 # defaults
990 # defaults
988 type_pattern = 'all'
991 type_pattern = 'all'
989 filter = ''
992 filter = ''
990
993
994 # list all object types
995 if list_types:
996 page.page('\n'.join(sorted(typestr2type)))
997 return
998
991 cmds = pattern.split()
999 cmds = pattern.split()
992 len_cmds = len(cmds)
1000 len_cmds = len(cmds)
993 if len_cmds == 1:
1001 if len_cmds == 1:
994 # Only filter pattern given
1002 # Only filter pattern given
995 filter = cmds[0]
1003 filter = cmds[0]
996 elif len_cmds == 2:
1004 elif len_cmds == 2:
997 # Both filter and type specified
1005 # Both filter and type specified
998 filter,type_pattern = cmds
1006 filter,type_pattern = cmds
999 else:
1007 else:
1000 raise ValueError('invalid argument string for psearch: <%s>' %
1008 raise ValueError('invalid argument string for psearch: <%s>' %
1001 pattern)
1009 pattern)
1002
1010
1003 # filter search namespaces
1011 # filter search namespaces
1004 for name in ns_search:
1012 for name in ns_search:
1005 if name not in ns_table:
1013 if name not in ns_table:
1006 raise ValueError('invalid namespace <%s>. Valid names: %s' %
1014 raise ValueError('invalid namespace <%s>. Valid names: %s' %
1007 (name,ns_table.keys()))
1015 (name,ns_table.keys()))
1008
1016
1009 #print 'type_pattern:',type_pattern # dbg
1017 #print 'type_pattern:',type_pattern # dbg
1010 search_result, namespaces_seen = set(), set()
1018 search_result, namespaces_seen = set(), set()
1011 for ns_name in ns_search:
1019 for ns_name in ns_search:
1012 ns = ns_table[ns_name]
1020 ns = ns_table[ns_name]
1013 # Normally, locals and globals are the same, so we just check one.
1021 # Normally, locals and globals are the same, so we just check one.
1014 if id(ns) in namespaces_seen:
1022 if id(ns) in namespaces_seen:
1015 continue
1023 continue
1016 namespaces_seen.add(id(ns))
1024 namespaces_seen.add(id(ns))
1017 tmp_res = list_namespace(ns, type_pattern, filter,
1025 tmp_res = list_namespace(ns, type_pattern, filter,
1018 ignore_case=ignore_case, show_all=show_all)
1026 ignore_case=ignore_case, show_all=show_all)
1019 search_result.update(tmp_res)
1027 search_result.update(tmp_res)
1020
1028
1021 page.page('\n'.join(sorted(search_result)))
1029 page.page('\n'.join(sorted(search_result)))
1022
1030
1023
1031
1024 def _render_signature(obj_signature, obj_name):
1032 def _render_signature(obj_signature, obj_name):
1025 """
1033 """
1026 This was mostly taken from inspect.Signature.__str__.
1034 This was mostly taken from inspect.Signature.__str__.
1027 Look there for the comments.
1035 Look there for the comments.
1028 The only change is to add linebreaks when this gets too long.
1036 The only change is to add linebreaks when this gets too long.
1029 """
1037 """
1030 result = []
1038 result = []
1031 pos_only = False
1039 pos_only = False
1032 kw_only = True
1040 kw_only = True
1033 for param in obj_signature.parameters.values():
1041 for param in obj_signature.parameters.values():
1034 if param.kind == inspect._POSITIONAL_ONLY:
1042 if param.kind == inspect._POSITIONAL_ONLY:
1035 pos_only = True
1043 pos_only = True
1036 elif pos_only:
1044 elif pos_only:
1037 result.append('/')
1045 result.append('/')
1038 pos_only = False
1046 pos_only = False
1039
1047
1040 if param.kind == inspect._VAR_POSITIONAL:
1048 if param.kind == inspect._VAR_POSITIONAL:
1041 kw_only = False
1049 kw_only = False
1042 elif param.kind == inspect._KEYWORD_ONLY and kw_only:
1050 elif param.kind == inspect._KEYWORD_ONLY and kw_only:
1043 result.append('*')
1051 result.append('*')
1044 kw_only = False
1052 kw_only = False
1045
1053
1046 result.append(str(param))
1054 result.append(str(param))
1047
1055
1048 if pos_only:
1056 if pos_only:
1049 result.append('/')
1057 result.append('/')
1050
1058
1051 # add up name, parameters, braces (2), and commas
1059 # add up name, parameters, braces (2), and commas
1052 if len(obj_name) + sum(len(r) + 2 for r in result) > 75:
1060 if len(obj_name) + sum(len(r) + 2 for r in result) > 75:
1053 # This doesn’t fit behind “Signature: ” in an inspect window.
1061 # This doesn’t fit behind “Signature: ” in an inspect window.
1054 rendered = '{}(\n{})'.format(obj_name, ''.join(
1062 rendered = '{}(\n{})'.format(obj_name, ''.join(
1055 ' {},\n'.format(r) for r in result)
1063 ' {},\n'.format(r) for r in result)
1056 )
1064 )
1057 else:
1065 else:
1058 rendered = '{}({})'.format(obj_name, ', '.join(result))
1066 rendered = '{}({})'.format(obj_name, ', '.join(result))
1059
1067
1060 if obj_signature.return_annotation is not inspect._empty:
1068 if obj_signature.return_annotation is not inspect._empty:
1061 anno = inspect.formatannotation(obj_signature.return_annotation)
1069 anno = inspect.formatannotation(obj_signature.return_annotation)
1062 rendered += ' -> {}'.format(anno)
1070 rendered += ' -> {}'.format(anno)
1063
1071
1064 return rendered
1072 return rendered
General Comments 0
You need to be logged in to leave comments. Login now