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