1"""Implementation of namespace-related magic functions.
2"""
3#-----------------------------------------------------------------------------
4# Copyright (c) 2012 The IPython Development Team.
5#
6# Distributed under the terms of the Modified BSD License.
7#
8# The full license is in the file COPYING.txt, distributed with this software.
9#-----------------------------------------------------------------------------
10
11#-----------------------------------------------------------------------------
12# Imports
13#-----------------------------------------------------------------------------
14
15# Stdlib
16import gc
17import re
18import sys
19
20# Our own packages
21from IPython.core import page
22from IPython.core.error import StdinNotImplementedError, UsageError
23from IPython.core.magic import Magics, magics_class, line_magic
24from IPython.testing.skipdoctest import skip_doctest
25from IPython.utils.encoding import DEFAULT_ENCODING
26from IPython.utils.openpy import read_py_file
27from IPython.utils.path import get_py_filename
28
29#-----------------------------------------------------------------------------
30# Magic implementation classes
31#-----------------------------------------------------------------------------
32
33@magics_class
34class NamespaceMagics(Magics):
35 """Magics to manage various aspects of the user's namespace.
36
37 These include listing variables, introspecting into them, etc.
38 """
39
40 @line_magic
41 def pinfo(self, parameter_s='', namespaces=None):
42 """Provide detailed information about an object.
43
44 '%pinfo object' is just a synonym for object? or ?object."""
45
46 # print('pinfo par: <%s>' % parameter_s) # dbg
47 # detail_level: 0 -> obj? , 1 -> obj??
48 detail_level = 0
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.
51 pinfo,qmark1,oname,qmark2 = \
52 re.match(r'(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
53 if pinfo or qmark1 or qmark2:
54 detail_level = 1
55 if "*" in oname:
56 self.psearch(oname)
57 else:
58 self.shell._inspect('pinfo', oname, detail_level=detail_level,
59 namespaces=namespaces)
60
61 @line_magic
62 def pinfo2(self, parameter_s='', namespaces=None):
63 """Provide extra detailed information about an object.
64
65 '%pinfo2 object' is just a synonym for object?? or ??object."""
66 self.shell._inspect('pinfo', parameter_s, detail_level=1,
67 namespaces=namespaces)
68
69 @skip_doctest
70 @line_magic
71 def pdef(self, parameter_s='', namespaces=None):
72 """Print the call signature for any callable object.
73
74 If the object is a class, print the constructor information.
75
76 Examples
77 --------
78 ::
79
80 In [3]: %pdef urllib.urlopen
81 urllib.urlopen(url, data=None, proxies=None)
82 """
83 self.shell._inspect('pdef',parameter_s, namespaces)
84
85 @line_magic
86 def pdoc(self, parameter_s='', namespaces=None):
87 """Print the docstring for an object.
88
89 If the given object is a class, it will print both the class and the
90 constructor docstrings."""
91 self.shell._inspect('pdoc',parameter_s, namespaces)
92
93 @line_magic
94 def psource(self, parameter_s='', namespaces=None):
95 """Print (or run through pager) the source code for an object."""
96 if not parameter_s:
97 raise UsageError('Missing object name.')
98 self.shell._inspect('psource',parameter_s, namespaces)
99
100 @line_magic
101 def pfile(self, parameter_s='', namespaces=None):
102 """Print (or run through pager) the file where an object is defined.
103
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
106 do its best to print the file in a convenient form.
107
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
110 if needed). You can thus use %pfile as a syntax highlighting code
111 viewer."""
112
113 # first interpret argument as an object name
114 out = self.shell._inspect('pfile',parameter_s, namespaces)
115 # if not, try the input as a filename
116 if out == 'not found':
117 try:
118 filename = get_py_filename(parameter_s)
119 except IOError as msg:
120 print(msg)
121 return
122 page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False)))
123
124 @line_magic
125 def psearch(self, parameter_s=''):
126 """Search for object in namespaces by wildcard.
127
128 %psearch [options] PATTERN [OBJECT TYPE]
129
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
132 rest of the command line must be unchanged (options come first), so
133 for example the following forms are equivalent
134
135 %psearch -i a* function
136 -i a* function?
137 ?-i a* function
138
139 Arguments:
140
141 PATTERN
142
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
145 search path. By default objects starting with a single _ are not
146 matched, many IPython generated objects have a single
147 underscore. The default is case insensitive matching. Matching is
148 also done on the attributes of objects and not only on the objects
149 in a module.
150
151 [OBJECT TYPE]
152
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
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
157 types (this is the default).
158
159 Options:
160
161 -a: makes the pattern match even objects whose names start with a
162 single underscore. These names are normally omitted from the
163 search.
164
165 -i/-c: make the pattern case insensitive/sensitive. If neither of
166 these options are given, the default is read from your configuration
167 file, with the option ``InteractiveShell.wildcards_case_sensitive``.
168 If this option is not specified in your configuration file, IPython's
169 internal default is to do a case sensitive search.
170
171 -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
172 specify can be searched in any of the following namespaces:
173 'builtin', 'user', 'user_global','internal', 'alias', where
174 'builtin' and 'user' are the search defaults. Note that you should
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.
179
180 'Builtin' contains the python module builtin, 'user' contains all
181 user data, 'alias' only contain the shell aliases and no python
182 objects, 'internal' contains objects used by IPython. The
183 'user_global' namespace is only used by embedded IPython instances,
184 and it contains module-level globals. You can add namespaces to the
185 search with -s or exclude them with -e (these options can be given
186 more than once).
187
188 Examples
189 --------
190 ::
191
192 %psearch a* -> objects beginning with an a
193 %psearch -e builtin a* -> objects NOT in the builtin space starting in a
194 %psearch a* function -> all functions beginning with an a
195 %psearch re.e* -> objects beginning with an e in module re
196 %psearch r*.e* -> objects that start with e in modules starting in r
197 %psearch r*.* string -> all strings in modules beginning with r
198
199 Case sensitive search::
200
201 %psearch -c a* list all object beginning with lower case a
202
203 Show objects beginning with a single _::
204
205 %psearch -a _* list objects beginning with a single underscore
206
207 List available objects::
208
209 %psearch -l list all available object types
210 """
211 # default namespaces to be searched
212 def_search = ['user_local', 'user_global', 'builtin']
213
214 # Process options/args
215 opts,args = self.parse_options(parameter_s,'cias:e:l',list_all=True)
216 opt = opts.get
217 shell = self.shell
218 psearch = shell.inspector.psearch
219
220 # select list object types
221 list_types = False
222 if 'l' in opts:
223 list_types = True
224
225 # select case options
226 if 'i' in opts:
227 ignore_case = True
228 elif 'c' in opts:
229 ignore_case = False
230 else:
231 ignore_case = not shell.wildcards_case_sensitive
232
233 # Build list of namespaces to search from user options
234 def_search.extend(opt('s',[]))
235 ns_exclude = ns_exclude=opt('e',[])
236 ns_search = [nm for nm in def_search if nm not in ns_exclude]
237
238 # Call the actual search
239 try:
240 psearch(args,shell.ns_table,ns_search,
241 show_all=opt('a'),ignore_case=ignore_case, list_types=list_types)
242 except:
243 shell.showtraceback()
244
245 @skip_doctest
246 @line_magic
247 def who_ls(self, parameter_s=''):
248 """Return a sorted list of all interactive variables.
249
250 If arguments are given, only variables of types matching these
251 arguments are returned.
252
253 Examples
254 --------
255 Define two variables and list them with who_ls::
256
257 In [1]: alpha = 123
258
259 In [2]: beta = 'test'
260
261 In [3]: %who_ls
262 Out[3]: ['alpha', 'beta']
263
264 In [4]: %who_ls int
265 Out[4]: ['alpha']
266
267 In [5]: %who_ls str
268 Out[5]: ['beta']
269 """
270
271 user_ns = self.shell.user_ns
272 user_ns_hidden = self.shell.user_ns_hidden
273 nonmatching = object() # This can never be in user_ns
274 out = [ i for i in user_ns
275 if not i.startswith('_') \
276 and (user_ns[i] is not user_ns_hidden.get(i, nonmatching)) ]
277
278 typelist = parameter_s.split()
279 if typelist:
280 typeset = set(typelist)
281 out = [i for i in out if type(user_ns[i]).__name__ in typeset]
282
283 out.sort()
284 return out
285
286 @skip_doctest
287 @line_magic
288 def who(self, parameter_s=''):
289 """Print all interactive variables, with some minimal formatting.
290
291 If any arguments are given, only variables whose type matches one of
292 these are printed. For example::
293
294 %who function str
295
296 will only list functions and strings, excluding all other types of
297 variables. To find the proper type names, simply use type(var) at a
298 command line to see how python prints type names. For example:
299
300 ::
301
302 In [1]: type('hello')\\
303 Out[1]: <type 'str'>
304
305 indicates that the type name for strings is 'str'.
306
307 ``%who`` always excludes executed names loaded through your configuration
308 file and things which are internal to IPython.
309
310 This is deliberate, as typically you may load many modules and the
311 purpose of %who is to show you only what you've manually defined.
312
313 Examples
314 --------
315
316 Define two variables and list them with who::
317
318 In [1]: alpha = 123
319
320 In [2]: beta = 'test'
321
322 In [3]: %who
323 alpha beta
324
325 In [4]: %who int
326 alpha
327
328 In [5]: %who str
329 beta
330 """
331
332 varlist = self.who_ls(parameter_s)
333 if not varlist:
334 if parameter_s:
335 print('No variables match your requested type.')
336 else:
337 print('Interactive namespace is empty.')
338 return
339
340 # if we have variables, move on...
341 count = 0
342 for i in varlist:
343 print(i+'\t', end=' ')
344 count += 1
345 if count > 8:
346 count = 0
347 print()
348 print()
349
350 @skip_doctest
351 @line_magic
352 def whos(self, parameter_s=''):
353 """Like %who, but gives some extra information about each variable.
354
355 The same type filtering of %who can be applied here.
356
357 For all variables, the type is printed. Additionally it prints:
358
359 - For {},[],(): their length.
360
361 - For numpy arrays, a summary with shape, number of
362 elements, typecode and size in memory.
363
364 - For DataFrame and Series types: their shape.
365
366 - Everything else: a string representation, snipping their middle if
367 too long.
368
369 Examples
370 --------
371 Define two variables and list them with whos::
372
373 In [1]: alpha = 123
374
375 In [2]: beta = 'test'
376
377 In [3]: df = pd.DataFrame({"a": range(10), "b": range(10,20)})
378
379 In [4]: s = df["a"]
380
381 In [5]: %whos
382 Variable Type Data/Info
383 --------------------------------
384 alpha int 123
385 beta str test
386 df DataFrame Shape: (10, 2)
387 s Series Shape: (10, )
388 """
389
390 varnames = self.who_ls(parameter_s)
391 if not varnames:
392 if parameter_s:
393 print('No variables match your requested type.')
394 else:
395 print('Interactive namespace is empty.')
396 return
397
398 # if we have variables, move on...
399
400 # for these types, show len() instead of data:
401 seq_types = ['dict', 'list', 'tuple']
402
403 # for numpy arrays, display summary info
404 ndarray_type = None
405 if 'numpy' in sys.modules:
406 try:
407 from numpy import ndarray
408 except ImportError:
409 pass
410 else:
411 ndarray_type = ndarray.__name__
412
413 # Find all variable names and types so we can figure out column sizes
414
415 # some types are well known and can be shorter
416 abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
417 def type_name(v):
418 tn = type(v).__name__
419 return abbrevs.get(tn,tn)
420
421 varlist = [self.shell.user_ns[n] for n in varnames]
422
423 typelist = []
424 for vv in varlist:
425 tt = type_name(vv)
426
427 if tt=='instance':
428 typelist.append( abbrevs.get(str(vv.__class__),
429 str(vv.__class__)))
430 else:
431 typelist.append(tt)
432
433 # column labels and # of spaces as separator
434 varlabel = 'Variable'
435 typelabel = 'Type'
436 datalabel = 'Data/Info'
437 colsep = 3
438 # variable format strings
439 vformat = "{0:<{varwidth}}{1:<{typewidth}}"
440 aformat = "%s: %s elems, type `%s`, %s bytes"
441 # find the size of the columns to format the output nicely
442 varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
443 typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
444 # table header
445 print(varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
446 ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1))
447 # and the table itself
448 kb = 1024
449 Mb = 1048576 # kb**2
450 for vname,var,vtype in zip(varnames,varlist,typelist):
451 print(vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth), end=' ')
452 if vtype in seq_types:
453 print("n="+str(len(var)))
454 elif vtype == ndarray_type:
455 vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
456 if vtype==ndarray_type:
457 # numpy
458 vsize = var.size
459 vbytes = vsize*var.itemsize
460 vdtype = var.dtype
461
462 if vbytes < 100000:
463 print(aformat % (vshape, vsize, vdtype, vbytes))
464 else:
465 print(aformat % (vshape, vsize, vdtype, vbytes), end=' ')
466 if vbytes < Mb:
467 print("(%s kb)" % (vbytes / kb,))
468 else:
469 print("(%s Mb)" % (vbytes / Mb,))
470 elif vtype in ["DataFrame", "Series"]:
471 # Useful for DataFrames and Series
472 # Ought to work for both pandas and polars
473 print(f"Shape: {var.shape}")
474 else:
475 try:
476 vstr = str(var)
477 except UnicodeEncodeError:
478 vstr = var.encode(DEFAULT_ENCODING,
479 'backslashreplace')
480 except:
481 vstr = "<object with id %d (str() failed)>" % id(var)
482 vstr = vstr.replace('\n', '\\n')
483 if len(vstr) < 50:
484 print(vstr)
485 else:
486 print(vstr[:25] + "<...>" + vstr[-25:])
487
488 @line_magic
489 def reset(self, parameter_s=''):
490 """Resets the namespace by removing all names defined by the user, if
491 called without arguments, or by removing some types of objects, such
492 as everything currently in IPython's In[] and Out[] containers (see
493 the parameters for details).
494
495 Parameters
496 ----------
497 -f
498 force reset without asking for confirmation.
499 -s
500 'Soft' reset: Only clears your namespace, leaving history intact.
501 References to objects may be kept. By default (without this option),
502 we do a 'hard' reset, giving you a new session and removing all
503 references to objects from the current session.
504 --aggressive
505 Try to aggressively remove modules from sys.modules ; this
506 may allow you to reimport Python modules that have been updated and
507 pick up changes, but can have unintended consequences.
508
509 in
510 reset input history
511 out
512 reset output history
513 dhist
514 reset directory history
515 array
516 reset only variables that are NumPy arrays
517
518 See Also
519 --------
520 reset_selective : invoked as ``%reset_selective``
521
522 Examples
523 --------
524 ::
525
526 In [6]: a = 1
527
528 In [7]: a
529 Out[7]: 1
530
531 In [8]: 'a' in get_ipython().user_ns
532 Out[8]: True
533
534 In [9]: %reset -f
535
536 In [1]: 'a' in get_ipython().user_ns
537 Out[1]: False
538
539 In [2]: %reset -f in
540 Flushing input history
541
542 In [3]: %reset -f dhist in
543 Flushing directory history
544 Flushing input history
545
546 Notes
547 -----
548 Calling this magic from clients that do not implement standard input,
549 such as the ipython notebook interface, will reset the namespace
550 without confirmation.
551 """
552 opts, args = self.parse_options(parameter_s, "sf", "aggressive", mode="list")
553 if "f" in opts:
554 ans = True
555 else:
556 try:
557 ans = self.shell.ask_yes_no(
558 "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
559 default='n')
560 except StdinNotImplementedError:
561 ans = True
562 if not ans:
563 print('Nothing done.')
564 return
565
566 if 's' in opts: # Soft reset
567 user_ns = self.shell.user_ns
568 for i in self.who_ls():
569 del(user_ns[i])
570 elif len(args) == 0: # Hard reset
571 self.shell.reset(new_session=False, aggressive=("aggressive" in opts))
572
573 # reset in/out/dhist/array: previously extensinions/clearcmd.py
574 ip = self.shell
575 user_ns = self.shell.user_ns # local lookup, heavily used
576
577 for target in args:
578 target = target.lower() # make matches case insensitive
579 if target == 'out':
580 print("Flushing output cache (%d entries)" % len(user_ns['_oh']))
581 self.shell.displayhook.flush()
582
583 elif target == 'in':
584 print("Flushing input history")
585 pc = self.shell.displayhook.prompt_count + 1
586 for n in range(1, pc):
587 key = '_i'+repr(n)
588 user_ns.pop(key,None)
589 user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
590 hm = ip.history_manager
591 # don't delete these, as %save and %macro depending on the
592 # length of these lists to be preserved
593 hm.input_hist_parsed[:] = [''] * pc
594 hm.input_hist_raw[:] = [''] * pc
595 # hm has internal machinery for _i,_ii,_iii, clear it out
596 hm._i = hm._ii = hm._iii = hm._i00 = u''
597
598 elif target == 'array':
599 # Support cleaning up numpy arrays
600 try:
601 from numpy import ndarray
602 # This must be done with items and not iteritems because
603 # we're going to modify the dict in-place.
604 for x,val in list(user_ns.items()):
605 if isinstance(val,ndarray):
606 del user_ns[x]
607 except ImportError:
608 print("reset array only works if Numpy is available.")
609
610 elif target == 'dhist':
611 print("Flushing directory history")
612 del user_ns['_dh'][:]
613
614 else:
615 print("Don't know how to reset ", end=' ')
616 print(target + ", please run `%reset?` for details")
617
618 gc.collect()
619
620 @line_magic
621 def reset_selective(self, parameter_s=''):
622 """Resets the namespace by removing names defined by the user.
623
624 Input/Output history are left around in case you need them.
625
626 %reset_selective [-f] regex
627
628 No action is taken if regex is not included
629
630 Options
631 -f : force reset without asking for confirmation.
632
633 See Also
634 --------
635 reset : invoked as ``%reset``
636
637 Examples
638 --------
639 We first fully reset the namespace so your output looks identical to
640 this example for pedagogical reasons; in practice you do not need a
641 full reset::
642
643 In [1]: %reset -f
644
645 Now, with a clean namespace we can make a few variables and use
646 ``%reset_selective`` to only delete names that match our regexp::
647
648 In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
649
650 In [3]: who_ls
651 Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
652
653 In [4]: %reset_selective -f b[2-3]m
654
655 In [5]: who_ls
656 Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
657
658 In [6]: %reset_selective -f d
659
660 In [7]: who_ls
661 Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
662
663 In [8]: %reset_selective -f c
664
665 In [9]: who_ls
666 Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
667
668 In [10]: %reset_selective -f b
669
670 In [11]: who_ls
671 Out[11]: ['a']
672
673 Notes
674 -----
675 Calling this magic from clients that do not implement standard input,
676 such as the ipython notebook interface, will reset the namespace
677 without confirmation.
678 """
679
680 opts, regex = self.parse_options(parameter_s,'f')
681
682 if 'f' in opts:
683 ans = True
684 else:
685 try:
686 ans = self.shell.ask_yes_no(
687 "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
688 default='n')
689 except StdinNotImplementedError:
690 ans = True
691 if not ans:
692 print('Nothing done.')
693 return
694 user_ns = self.shell.user_ns
695 if not regex:
696 print('No regex pattern specified. Nothing done.')
697 return
698 else:
699 try:
700 m = re.compile(regex)
701 except TypeError as e:
702 raise TypeError('regex must be a string or compiled pattern') from e
703 for i in self.who_ls():
704 if m.search(i):
705 del(user_ns[i])
706
707 @line_magic
708 def xdel(self, parameter_s=''):
709 """Delete a variable, trying to clear it from anywhere that
710 IPython's machinery has references to it. By default, this uses
711 the identity of the named object in the user namespace to remove
712 references held under other names. The object is also removed
713 from the output history.
714
715 Options
716 -n : Delete the specified name from all namespaces, without
717 checking their identity.
718 """
719 opts, varname = self.parse_options(parameter_s,'n')
720 try:
721 self.shell.del_var(varname, ('n' in opts))
722 except (NameError, ValueError) as e:
723 print(type(e).__name__ +": "+ str(e))