namespace.py
711 lines
| 24.2 KiB
| text/x-python
|
PythonLexer
|
r6962 | """Implementation of namespace-related magic functions. | ||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# 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 | ||||
|
r8278 | from IPython.core.error import StdinNotImplementedError, UsageError | ||
|
r6973 | from IPython.core.magic import Magics, magics_class, line_magic | ||
|
r6962 | from IPython.testing.skipdoctest import skip_doctest | ||
from IPython.utils.encoding import DEFAULT_ENCODING | ||||
|
r8319 | from IPython.utils.openpy import read_py_file | ||
|
r6962 | from IPython.utils.path import get_py_filename | ||
#----------------------------------------------------------------------------- | ||||
# Magic implementation classes | ||||
#----------------------------------------------------------------------------- | ||||
|
r6973 | @magics_class | ||
|
r6962 | 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.""" | ||||
|
r28756 | # print('pinfo par: <%s>' % parameter_s) # dbg | ||
|
r6962 | # 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 = \ | ||||
|
r24780 | re.match(r'(pinfo )?(\?*)(.*?)(\??$)',parameter_s).groups() | ||
|
r6962 | 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): | ||||
|
r8707 | """Print the call signature for any callable object. | ||
|
r6962 | |||
If the object is a class, print the constructor information. | ||||
Examples | ||||
-------- | ||||
:: | ||||
In [3]: %pdef urllib.urlopen | ||||
urllib.urlopen(url, data=None, proxies=None) | ||||
""" | ||||
|
r7289 | self.shell._inspect('pdef',parameter_s, namespaces) | ||
|
r6962 | |||
@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.""" | ||||
|
r7289 | self.shell._inspect('pdoc',parameter_s, namespaces) | ||
|
r6962 | |||
@line_magic | ||||
def psource(self, parameter_s='', namespaces=None): | ||||
"""Print (or run through pager) the source code for an object.""" | ||||
|
r8278 | if not parameter_s: | ||
raise UsageError('Missing object name.') | ||||
|
r7289 | self.shell._inspect('psource',parameter_s, namespaces) | ||
|
r6962 | |||
@line_magic | ||||
|
r8699 | def pfile(self, parameter_s='', namespaces=None): | ||
|
r6962 | """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 | ||||
|
r8699 | out = self.shell._inspect('pfile',parameter_s, namespaces) | ||
|
r6962 | # if not, try the input as a filename | ||
if out == 'not found': | ||||
try: | ||||
filename = get_py_filename(parameter_s) | ||||
|
r7787 | except IOError as msg: | ||
|
r13348 | print(msg) | ||
|
r6962 | return | ||
|
r8321 | page.page(self.shell.pycolorize(read_py_file(filename, skip_encoding_cookie=False))) | ||
|
r6962 | |||
@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. | ||||
|
r27294 | |||
|
r24996 | -l: List all available object types for object matching. This function | ||
can be used without arguments. | ||||
|
r6962 | |||
'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 | ||||
|
r27294 | |||
|
r24996 | List available objects:: | ||
|
r27294 | |||
|
r24996 | %psearch -l list all available object types | ||
|
r6962 | """ | ||
# default namespaces to be searched | ||||
def_search = ['user_local', 'user_global', 'builtin'] | ||||
# Process options/args | ||||
|
r24996 | opts,args = self.parse_options(parameter_s,'cias:e:l',list_all=True) | ||
|
r6962 | opt = opts.get | ||
shell = self.shell | ||||
psearch = shell.inspector.psearch | ||||
|
r24996 | |||
# select list object types | ||||
list_types = False | ||||
if 'l' in opts: | ||||
list_types = True | ||||
|
r6962 | |||
# select case options | ||||
|
r7859 | if 'i' in opts: | ||
|
r6962 | ignore_case = True | ||
|
r7859 | elif 'c' in opts: | ||
|
r6962 | 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, | ||||
|
r24996 | show_all=opt('a'),ignore_case=ignore_case, list_types=list_types) | ||
|
r6962 | 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 | ||||
|
r12257 | nonmatching = object() # This can never be in user_ns | ||
|
r6962 | out = [ i for i in user_ns | ||
if not i.startswith('_') \ | ||||
|
r12257 | and (user_ns[i] is not user_ns_hidden.get(i, nonmatching)) ] | ||
|
r6962 | |||
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: | ||||
|
r13348 | print('No variables match your requested type.') | ||
|
r6962 | else: | ||
|
r13348 | print('Interactive namespace is empty.') | ||
|
r6962 | return | ||
# if we have variables, move on... | ||||
count = 0 | ||||
for i in varlist: | ||||
|
r13348 | print(i+'\t', end=' ') | ||
|
r6962 | count += 1 | ||
if count > 8: | ||||
count = 0 | ||||
|
r13348 | print() | ||
print() | ||||
|
r6962 | |||
@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 | ||||
|
r12553 | elements, typecode and size in memory. | ||
|
r6962 | |||
- Everything else: a string representation, snipping their middle if | ||||
|
r12553 | too long. | ||
|
r6962 | |||
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: | ||||
|
r13348 | print('No variables match your requested type.') | ||
|
r6962 | else: | ||
|
r13348 | print('Interactive namespace is empty.') | ||
|
r6962 | 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) | ||||
|
r13375 | varlist = [self.shell.user_ns[n] for n in varnames] | ||
|
r6962 | |||
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 | ||||
|
r13348 | print(varlabel.ljust(varwidth) + typelabel.ljust(typewidth) + \ | ||
' '+datalabel+'\n' + '-'*(varwidth+typewidth+len(datalabel)+1)) | ||||
|
r6962 | # and the table itself | ||
kb = 1024 | ||||
Mb = 1048576 # kb**2 | ||||
for vname,var,vtype in zip(varnames,varlist,typelist): | ||||
|
r13348 | print(vformat.format(vname, vtype, varwidth=varwidth, typewidth=typewidth), end=' ') | ||
|
r6962 | if vtype in seq_types: | ||
|
r13348 | print("n="+str(len(var))) | ||
|
r6962 | 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: | ||||
|
r13348 | print(aformat % (vshape, vsize, vdtype, vbytes)) | ||
|
r6962 | else: | ||
|
r13348 | print(aformat % (vshape, vsize, vdtype, vbytes), end=' ') | ||
|
r6962 | if vbytes < Mb: | ||
|
r13348 | print('(%s kb)' % (vbytes/kb,)) | ||
|
r6962 | else: | ||
|
r13348 | print('(%s Mb)' % (vbytes/Mb,)) | ||
|
r6962 | else: | ||
try: | ||||
vstr = str(var) | ||||
except UnicodeEncodeError: | ||||
|
r23044 | vstr = var.encode(DEFAULT_ENCODING, | ||
'backslashreplace') | ||||
|
r6962 | except: | ||
vstr = "<object with id %d (str() failed)>" % id(var) | ||||
|
r6986 | vstr = vstr.replace('\n', '\\n') | ||
|
r6962 | if len(vstr) < 50: | ||
|
r13348 | print(vstr) | ||
|
r6962 | else: | ||
|
r13348 | print(vstr[:25] + "<...>" + vstr[-25:]) | ||
|
r6962 | |||
@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 | ||||
---------- | ||||
|
r27297 | -f | ||
|
r27363 | force reset without asking for confirmation. | ||
|
r27297 | -s | ||
|
r27363 | 'Soft' reset: Only clears your namespace, leaving history intact. | ||
|
r6962 | 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. | ||||
|
r27297 | --aggressive | ||
Try to aggressively remove modules from sys.modules ; this | ||||
|
r26229 | may allow you to reimport Python modules that have been updated and | ||
|
r27821 | pick up changes, but can have unintended consequences. | ||
|
r27297 | |||
|
r27363 | in | ||
reset input history | ||||
out | ||||
reset output history | ||||
dhist | ||||
reset directory history | ||||
array | ||||
reset only variables that are NumPy arrays | ||||
|
r6962 | |||
See Also | ||||
-------- | ||||
|
r13684 | reset_selective : invoked as ``%reset_selective`` | ||
|
r6962 | |||
Examples | ||||
-------- | ||||
:: | ||||
In [6]: a = 1 | ||||
In [7]: a | ||||
Out[7]: 1 | ||||
|
r25075 | In [8]: 'a' in get_ipython().user_ns | ||
|
r6962 | Out[8]: True | ||
In [9]: %reset -f | ||||
|
r25075 | In [1]: 'a' in get_ipython().user_ns | ||
|
r6962 | 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. | ||||
""" | ||||
|
r26229 | opts, args = self.parse_options(parameter_s, "sf", "aggressive", mode="list") | ||
if "f" in opts: | ||||
|
r6962 | 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: | ||||
|
r13348 | print('Nothing done.') | ||
|
r6962 | 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 | ||||
|
r26229 | self.shell.reset(new_session=False, aggressive=("aggressive" in opts)) | ||
|
r6962 | |||
# 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': | ||||
|
r13348 | print("Flushing output cache (%d entries)" % len(user_ns['_oh'])) | ||
|
r6962 | self.shell.displayhook.flush() | ||
elif target == 'in': | ||||
|
r13348 | print("Flushing input history") | ||
|
r6962 | 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. | ||||
|
r13375 | for x,val in list(user_ns.items()): | ||
|
r6962 | if isinstance(val,ndarray): | ||
del user_ns[x] | ||||
except ImportError: | ||||
|
r13348 | print("reset array only works if Numpy is available.") | ||
|
r6962 | |||
elif target == 'dhist': | ||||
|
r13348 | print("Flushing directory history") | ||
|
r6962 | del user_ns['_dh'][:] | ||
else: | ||||
|
r13348 | print("Don't know how to reset ", end=' ') | ||
print(target + ", please run `%reset?` for details") | ||||
|
r6962 | |||
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 | ||||
-------- | ||||
|
r13684 | reset : invoked as ``%reset`` | ||
|
r6962 | |||
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') | ||||
|
r7859 | if 'f' in opts: | ||
|
r6962 | 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: | ||||
|
r13348 | print('Nothing done.') | ||
|
r6962 | return | ||
user_ns = self.shell.user_ns | ||||
if not regex: | ||||
|
r13348 | print('No regex pattern specified. Nothing done.') | ||
|
r6962 | return | ||
else: | ||||
try: | ||||
m = re.compile(regex) | ||||
|
r25827 | except TypeError as e: | ||
raise TypeError('regex must be a string or compiled pattern') from e | ||||
|
r6962 | 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: | ||||
|
r13348 | print(type(e).__name__ +": "+ str(e)) | ||