123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704 |
- """Implementation of namespace-related magic functions.
- """
- from __future__ import print_function
- #-----------------------------------------------------------------------------
- # Copyright (c) 2012 The IPython Development Team.
- #
- # Distributed under the terms of the Modified BSD License.
- #
- # The full license is in the file COPYING.txt, distributed with this software.
- #-----------------------------------------------------------------------------
- #-----------------------------------------------------------------------------
- # Imports
- #-----------------------------------------------------------------------------
- # Stdlib
- import gc
- import re
- import sys
- # Our own packages
- from IPython.core import page
- from IPython.core.error import StdinNotImplementedError, UsageError
- from IPython.core.magic import Magics, magics_class, line_magic
- from IPython.testing.skipdoctest import skip_doctest
- from IPython.utils.encoding import DEFAULT_ENCODING
- from IPython.utils.openpy import read_py_file
- from IPython.utils.path import get_py_filename
- from IPython.utils.py3compat import unicode_type
- #-----------------------------------------------------------------------------
- # Magic implementation classes
- #-----------------------------------------------------------------------------
- @magics_class
- class NamespaceMagics(Magics):
- """Magics to manage various aspects of the user's namespace.
- These include listing variables, introspecting into them, etc.
- """
- @line_magic
- def pinfo(self, parameter_s='', namespaces=None):
- """Provide detailed information about an object.
- '%pinfo object' is just a synonym for object? or ?object."""
- #print 'pinfo par: <%s>' % parameter_s # dbg
- # detail_level: 0 -> obj? , 1 -> obj??
- detail_level = 0
- # We need to detect if we got called as 'pinfo pinfo foo', which can
- # happen if the user types 'pinfo foo?' at the cmd line.
- pinfo,qmark1,oname,qmark2 = \
- re.match('(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups()
- if pinfo or qmark1 or qmark2:
- detail_level = 1
- if "*" in oname:
- self.psearch(oname)
- else:
- self.shell._inspect('pinfo', oname, detail_level=detail_level,
- namespaces=namespaces)
- @line_magic
- def pinfo2(self, parameter_s='', namespaces=None):
- """Provide extra detailed information about an object.
- '%pinfo2 object' is just a synonym for object?? or ??object."""
- self.shell._inspect('pinfo', parameter_s, detail_level=1,
- namespaces=namespaces)
- @skip_doctest
- @line_magic
- def pdef(self, parameter_s='', namespaces=None):
- """Print the call signature for any callable object.
- If the object is a class, print the constructor information.
- Examples
- --------
- ::
- In [3]: %pdef urllib.urlopen
- urllib.urlopen(url, data=None, proxies=None)
- """
- self.shell._inspect('pdef',parameter_s, namespaces)
- @line_magic
- def pdoc(self, parameter_s='', namespaces=None):
- """Print the docstring for an object.
- If the given object is a class, it will print both the class and the
- constructor docstrings."""
- self.shell._inspect('pdoc',parameter_s, namespaces)
- @line_magic
- def psource(self, parameter_s='', namespaces=None):
- """Print (or run through pager) the source code for an object."""
- if not parameter_s:
- raise UsageError('Missing object name.')
- self.shell._inspect('psource',parameter_s, namespaces)
- @line_magic
- def pfile(self, parameter_s='', namespaces=None):
- """Print (or run through pager) the file where an object is defined.
- The file opens at the line where the object definition begins. IPython
- will honor the environment variable PAGER if set, and otherwise will
- do its best to print the file in a convenient form.
- If the given argument is not an object currently defined, IPython will
- try to interpret it as a filename (automatically adding a .py extension
- if needed). You can thus use %pfile as a syntax highlighting code
- viewer."""
- # first interpret argument as an object name
- out = self.shell._inspect('pfile',parameter_s, namespaces)
- # if not, try the input as a filename
- if out == 'not found':
- try:
- filename = get_py_filename(parameter_s)
- except IOError as msg:
- print(msg)
- return
- page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False)))
- @line_magic
- def psearch(self, parameter_s=''):
- """Search for object in namespaces by wildcard.
- %psearch [options] PATTERN [OBJECT TYPE]
- Note: ? can be used as a synonym for %psearch, at the beginning or at
- the end: both a*? and ?a* are equivalent to '%psearch a*'. Still, the
- rest of the command line must be unchanged (options come first), so
- for example the following forms are equivalent
- %psearch -i a* function
- -i a* function?
- ?-i a* function
- Arguments:
- PATTERN
- where PATTERN is a string containing * as a wildcard similar to its
- use in a shell. The pattern is matched in all namespaces on the
- search path. By default objects starting with a single _ are not
- matched, many IPython generated objects have a single
- underscore. The default is case insensitive matching. Matching is
- also done on the attributes of objects and not only on the objects
- in a module.
- [OBJECT TYPE]
- Is the name of a python type from the types module. The name is
- given in lowercase without the ending type, ex. StringType is
- written string. By adding a type here only objects matching the
- given type are matched. Using all here makes the pattern match all
- types (this is the default).
- Options:
- -a: makes the pattern match even objects whose names start with a
- single underscore. These names are normally omitted from the
- search.
- -i/-c: make the pattern case insensitive/sensitive. If neither of
- these options are given, the default is read from your configuration
- file, with the option ``InteractiveShell.wildcards_case_sensitive``.
- If this option is not specified in your configuration file, IPython's
- internal default is to do a case sensitive search.
- -e/-s NAMESPACE: exclude/search a given namespace. The pattern you
- specify can be searched in any of the following namespaces:
- 'builtin', 'user', 'user_global','internal', 'alias', where
- 'builtin' and 'user' are the search defaults. Note that you should
- not use quotes when specifying namespaces.
- 'Builtin' contains the python module builtin, 'user' contains all
- user data, 'alias' only contain the shell aliases and no python
- objects, 'internal' contains objects used by IPython. The
- 'user_global' namespace is only used by embedded IPython instances,
- and it contains module-level globals. You can add namespaces to the
- search with -s or exclude them with -e (these options can be given
- more than once).
- Examples
- --------
- ::
- %psearch a* -> objects beginning with an a
- %psearch -e builtin a* -> objects NOT in the builtin space starting in a
- %psearch a* function -> all functions beginning with an a
- %psearch re.e* -> objects beginning with an e in module re
- %psearch r*.e* -> objects that start with e in modules starting in r
- %psearch r*.* string -> all strings in modules beginning with r
- Case sensitive search::
- %psearch -c a* list all object beginning with lower case a
- Show objects beginning with a single _::
- %psearch -a _* list objects beginning with a single underscore
- """
- try:
- parameter_s.encode('ascii')
- except UnicodeEncodeError:
- print('Python identifiers can only contain ascii characters.')
- return
- # default namespaces to be searched
- def_search = ['user_local', 'user_global', 'builtin']
- # Process options/args
- opts,args = self.parse_options(parameter_s,'cias:e:',list_all=True)
- opt = opts.get
- shell = self.shell
- psearch = shell.inspector.psearch
- # select case options
- if 'i' in opts:
- ignore_case = True
- elif 'c' in opts:
- ignore_case = False
- else:
- ignore_case = not shell.wildcards_case_sensitive
- # Build list of namespaces to search from user options
- def_search.extend(opt('s',[]))
- ns_exclude = ns_exclude=opt('e',[])
- ns_search = [nm for nm in def_search if nm not in ns_exclude]
- # Call the actual search
- try:
- psearch(args,shell.ns_table,ns_search,
- show_all=opt('a'),ignore_case=ignore_case)
- except:
- shell.showtraceback()
- @skip_doctest
- @line_magic
- def who_ls(self, parameter_s=''):
- """Return a sorted list of all interactive variables.
- If arguments are given, only variables of types matching these
- arguments are returned.
- Examples
- --------
- Define two variables and list them with who_ls::
- In [1]: alpha = 123
- In [2]: beta = 'test'
- In [3]: %who_ls
- Out[3]: ['alpha', 'beta']
- In [4]: %who_ls int
- Out[4]: ['alpha']
- In [5]: %who_ls str
- Out[5]: ['beta']
- """
- user_ns = self.shell.user_ns
- user_ns_hidden = self.shell.user_ns_hidden
- nonmatching = object() # This can never be in user_ns
- out = [ i for i in user_ns
- if not i.startswith('_') \
- and (user_ns[i] is not user_ns_hidden.get(i, nonmatching)) ]
- typelist = parameter_s.split()
- if typelist:
- typeset = set(typelist)
- out = [i for i in out if type(user_ns[i]).__name__ in typeset]
- out.sort()
- return out
- @skip_doctest
- @line_magic
- def who(self, parameter_s=''):
- """Print all interactive variables, with some minimal formatting.
- If any arguments are given, only variables whose type matches one of
- these are printed. For example::
- %who function str
- will only list functions and strings, excluding all other types of
- variables. To find the proper type names, simply use type(var) at a
- command line to see how python prints type names. For example:
- ::
- In [1]: type('hello')\\
- Out[1]: <type 'str'>
- indicates that the type name for strings is 'str'.
- ``%who`` always excludes executed names loaded through your configuration
- file and things which are internal to IPython.
- This is deliberate, as typically you may load many modules and the
- purpose of %who is to show you only what you've manually defined.
- Examples
- --------
- Define two variables and list them with who::
- In [1]: alpha = 123
- In [2]: beta = 'test'
- In [3]: %who
- alpha beta
- In [4]: %who int
- alpha
- In [5]: %who str
- beta
- """
- varlist = self.who_ls(parameter_s)
- if not varlist:
- if parameter_s:
- print('No variables match your requested type.')
- else:
- print('Interactive namespace is empty.')
- return
- # if we have variables, move on...
- count = 0
- for i in varlist:
- print(i+'\t', end=' ')
- count += 1
- if count > 8:
- count = 0
- print()
- print()
- @skip_doctest
- @line_magic
- def whos(self, parameter_s=''):
- """Like %who, but gives some extra information about each variable.
- The same type filtering of %who can be applied here.
- For all variables, the type is printed. Additionally it prints:
- - For {},[],(): their length.
- - For numpy arrays, a summary with shape, number of
- elements, typecode and size in memory.
- - Everything else: a string representation, snipping their middle if
- too long.
- Examples
- --------
- Define two variables and list them with whos::
- In [1]: alpha = 123
- In [2]: beta = 'test'
- In [3]: %whos
- Variable Type Data/Info
- --------------------------------
- alpha int 123
- beta str test
- """
- varnames = self.who_ls(parameter_s)
- if not varnames:
- if parameter_s:
- print('No variables match your requested type.')
- else:
- print('Interactive namespace is empty.')
- return
- # if we have variables, move on...
- # for these types, show len() instead of data:
- seq_types = ['dict', 'list', 'tuple']
- # for numpy arrays, display summary info
- ndarray_type = None
- if 'numpy' in sys.modules:
- try:
- from numpy import ndarray
- except ImportError:
- pass
- else:
- ndarray_type = ndarray.__name__
- # Find all variable names and types so we can figure out column sizes
- # some types are well known and can be shorter
- abbrevs = {'IPython.core.macro.Macro' : 'Macro'}
- def type_name(v):
- tn = type(v).__name__
- return abbrevs.get(tn,tn)
- varlist = [self.shell.user_ns[n] for n in varnames]
- typelist = []
- for vv in varlist:
- tt = type_name(vv)
- if tt=='instance':
- typelist.append( abbrevs.get(str(vv.__class__),
- str(vv.__class__)))
- else:
- typelist.append(tt)
- # column labels and # of spaces as separator
- varlabel = 'Variable'
- typelabel = 'Type'
- datalabel = 'Data/Info'
- colsep = 3
- # variable format strings
- vformat = "{0:<{varwidth}}{1:<{typewidth}}"
- aformat = "%s: %s elems, type `%s`, %s bytes"
- # find the size of the columns to format the output nicely
- varwidth = max(max(map(len,varnames)), len(varlabel)) + colsep
- typewidth = max(max(map(len,typelist)), len(typelabel)) + colsep
- # table header
- print(varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \
- ' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1))
- # and the table itself
- kb = 1024
- Mb = 1048576 # kb**2
- for vname,var,vtype in zip(varnames,varlist,typelist):
- print(vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth), end=' ')
- if vtype in seq_types:
- print("n="+str(len(var)))
- elif vtype == ndarray_type:
- vshape = str(var.shape).replace(',','').replace(' ','x')[1:-1]
- if vtype==ndarray_type:
- # numpy
- vsize = var.size
- vbytes = vsize*var.itemsize
- vdtype = var.dtype
- if vbytes < 100000:
- print(aformat % (vshape, vsize, vdtype, vbytes))
- else:
- print(aformat % (vshape, vsize, vdtype, vbytes), end=' ')
- if vbytes < Mb:
- print('(%s kb)' % (vbytes/kb,))
- else:
- print('(%s Mb)' % (vbytes/Mb,))
- else:
- try:
- vstr = str(var)
- except UnicodeEncodeError:
- vstr = unicode_type(var).encode(DEFAULT_ENCODING,
- 'backslashreplace')
- except:
- vstr = "<object with id %d (str() failed)>" % id(var)
- vstr = vstr.replace('\n', '\\n')
- if len(vstr) < 50:
- print(vstr)
- else:
- print(vstr[:25] + "<...>" + vstr[-25:])
- @line_magic
- def reset(self, parameter_s=''):
- """Resets the namespace by removing all names defined by the user, if
- called without arguments, or by removing some types of objects, such
- as everything currently in IPython's In[] and Out[] containers (see
- the parameters for details).
- Parameters
- ----------
- -f : force reset without asking for confirmation.
- -s : 'Soft' reset: Only clears your namespace, leaving history intact.
- References to objects may be kept. By default (without this option),
- we do a 'hard' reset, giving you a new session and removing all
- references to objects from the current session.
- in : reset input history
- out : reset output history
- dhist : reset directory history
- array : reset only variables that are NumPy arrays
- See Also
- --------
- reset_selective : invoked as ``%reset_selective``
- Examples
- --------
- ::
- In [6]: a = 1
- In [7]: a
- Out[7]: 1
- In [8]: 'a' in _ip.user_ns
- Out[8]: True
- In [9]: %reset -f
- In [1]: 'a' in _ip.user_ns
- Out[1]: False
- In [2]: %reset -f in
- Flushing input history
- In [3]: %reset -f dhist in
- Flushing directory history
- Flushing input history
- Notes
- -----
- Calling this magic from clients that do not implement standard input,
- such as the ipython notebook interface, will reset the namespace
- without confirmation.
- """
- opts, args = self.parse_options(parameter_s,'sf', mode='list')
- if 'f' in opts:
- ans = True
- else:
- try:
- ans = self.shell.ask_yes_no(
- "Once deleted, variables cannot be recovered. Proceed (y/[n])?",
- default='n')
- except StdinNotImplementedError:
- ans = True
- if not ans:
- print('Nothing done.')
- return
- if 's' in opts: # Soft reset
- user_ns = self.shell.user_ns
- for i in self.who_ls():
- del(user_ns[i])
- elif len(args) == 0: # Hard reset
- self.shell.reset(new_session = False)
- # reset in/out/dhist/array: previously extensinions/clearcmd.py
- ip = self.shell
- user_ns = self.shell.user_ns # local lookup, heavily used
- for target in args:
- target = target.lower() # make matches case insensitive
- if target == 'out':
- print("Flushing output cache (%d entries)" % len(user_ns['_oh']))
- self.shell.displayhook.flush()
- elif target == 'in':
- print("Flushing input history")
- pc = self.shell.displayhook.prompt_count + 1
- for n in range(1, pc):
- key = '_i'+repr(n)
- user_ns.pop(key,None)
- user_ns.update(dict(_i=u'',_ii=u'',_iii=u''))
- hm = ip.history_manager
- # don't delete these, as %save and %macro depending on the
- # length of these lists to be preserved
- hm.input_hist_parsed[:] = [''] * pc
- hm.input_hist_raw[:] = [''] * pc
- # hm has internal machinery for _i,_ii,_iii, clear it out
- hm._i = hm._ii = hm._iii = hm._i00 = u''
- elif target == 'array':
- # Support cleaning up numpy arrays
- try:
- from numpy import ndarray
- # This must be done with items and not iteritems because
- # we're going to modify the dict in-place.
- for x,val in list(user_ns.items()):
- if isinstance(val,ndarray):
- del user_ns[x]
- except ImportError:
- print("reset array only works if Numpy is available.")
- elif target == 'dhist':
- print("Flushing directory history")
- del user_ns['_dh'][:]
- else:
- print("Don't know how to reset ", end=' ')
- print(target + ", please run `%reset?` for details")
- gc.collect()
- @line_magic
- def reset_selective(self, parameter_s=''):
- """Resets the namespace by removing names defined by the user.
- Input/Output history are left around in case you need them.
- %reset_selective [-f] regex
- No action is taken if regex is not included
- Options
- -f : force reset without asking for confirmation.
- See Also
- --------
- reset : invoked as ``%reset``
- Examples
- --------
- We first fully reset the namespace so your output looks identical to
- this example for pedagogical reasons; in practice you do not need a
- full reset::
- In [1]: %reset -f
- Now, with a clean namespace we can make a few variables and use
- ``%reset_selective`` to only delete names that match our regexp::
- In [2]: a=1; b=2; c=3; b1m=4; b2m=5; b3m=6; b4m=7; b2s=8
- In [3]: who_ls
- Out[3]: ['a', 'b', 'b1m', 'b2m', 'b2s', 'b3m', 'b4m', 'c']
- In [4]: %reset_selective -f b[2-3]m
- In [5]: who_ls
- Out[5]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
- In [6]: %reset_selective -f d
- In [7]: who_ls
- Out[7]: ['a', 'b', 'b1m', 'b2s', 'b4m', 'c']
- In [8]: %reset_selective -f c
- In [9]: who_ls
- Out[9]: ['a', 'b', 'b1m', 'b2s', 'b4m']
- In [10]: %reset_selective -f b
- In [11]: who_ls
- Out[11]: ['a']
- Notes
- -----
- Calling this magic from clients that do not implement standard input,
- such as the ipython notebook interface, will reset the namespace
- without confirmation.
- """
- opts, regex = self.parse_options(parameter_s,'f')
- if 'f' in opts:
- ans = True
- else:
- try:
- ans = self.shell.ask_yes_no(
- "Once deleted, variables cannot be recovered. Proceed (y/[n])? ",
- default='n')
- except StdinNotImplementedError:
- ans = True
- if not ans:
- print('Nothing done.')
- return
- user_ns = self.shell.user_ns
- if not regex:
- print('No regex pattern specified. Nothing done.')
- return
- else:
- try:
- m = re.compile(regex)
- except TypeError:
- raise TypeError('regex must be a string or compiled pattern')
- for i in self.who_ls():
- if m.search(i):
- del(user_ns[i])
- @line_magic
- def xdel(self, parameter_s=''):
- """Delete a variable, trying to clear it from anywhere that
- IPython's machinery has references to it. By default, this uses
- the identity of the named object in the user namespace to remove
- references held under other names. The object is also removed
- from the output history.
- Options
- -n : Delete the specified name from all namespaces, without
- checking their identity.
- """
- opts, varname = self.parse_options(parameter_s,'n')
- try:
- self.shell.del_var(varname, ('n' in opts))
- except (NameError, ValueError) as e:
- print(type(e).__name__ +": "+ str(e))
|