##// END OF EJS Templates
Use len and str from builtins in computing dynamic prompts....
Fernando Perez -
Show More
@@ -1,622 +1,622 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Classes for handling input/output prompts.
4 4 """
5 5
6 6 #*****************************************************************************
7 7 # Copyright (C) 2008-2009 The IPython Development Team
8 8 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #*****************************************************************************
13 13
14 14 #****************************************************************************
15 15 # Required modules
16 16 import __builtin__
17 17 import os
18 18 import socket
19 19 import sys
20 20 import time
21 21
22 22 # IPython's own
23 23 from IPython import ColorANSI
24 24 from IPython import Release
25 25 from IPython.external.Itpl import ItplNS
26 26 from IPython.ipapi import TryNext
27 27 from IPython.ipstruct import Struct
28 28 from IPython.macro import Macro
29 29
30 30 from IPython.genutils import *
31 31
32 32 #****************************************************************************
33 33 #Color schemes for Prompts.
34 34
35 35 PromptColors = ColorANSI.ColorSchemeTable()
36 36 InputColors = ColorANSI.InputTermColors # just a shorthand
37 37 Colors = ColorANSI.TermColors # just a shorthand
38 38
39 39 PromptColors.add_scheme(ColorANSI.ColorScheme(
40 40 'NoColor',
41 41 in_prompt = InputColors.NoColor, # Input prompt
42 42 in_number = InputColors.NoColor, # Input prompt number
43 43 in_prompt2 = InputColors.NoColor, # Continuation prompt
44 44 in_normal = InputColors.NoColor, # color off (usu. Colors.Normal)
45 45
46 46 out_prompt = Colors.NoColor, # Output prompt
47 47 out_number = Colors.NoColor, # Output prompt number
48 48
49 49 normal = Colors.NoColor # color off (usu. Colors.Normal)
50 50 ))
51 51
52 52 # make some schemes as instances so we can copy them for modification easily:
53 53 __PColLinux = ColorANSI.ColorScheme(
54 54 'Linux',
55 55 in_prompt = InputColors.Green,
56 56 in_number = InputColors.LightGreen,
57 57 in_prompt2 = InputColors.Green,
58 58 in_normal = InputColors.Normal, # color off (usu. Colors.Normal)
59 59
60 60 out_prompt = Colors.Red,
61 61 out_number = Colors.LightRed,
62 62
63 63 normal = Colors.Normal
64 64 )
65 65 # Don't forget to enter it into the table!
66 66 PromptColors.add_scheme(__PColLinux)
67 67
68 68 # Slightly modified Linux for light backgrounds
69 69 __PColLightBG = __PColLinux.copy('LightBG')
70 70
71 71 __PColLightBG.colors.update(
72 72 in_prompt = InputColors.Blue,
73 73 in_number = InputColors.LightBlue,
74 74 in_prompt2 = InputColors.Blue
75 75 )
76 76 PromptColors.add_scheme(__PColLightBG)
77 77
78 78 del Colors,InputColors
79 79
80 80 #-----------------------------------------------------------------------------
81 81 def multiple_replace(dict, text):
82 82 """ Replace in 'text' all occurences of any key in the given
83 83 dictionary by its corresponding value. Returns the new string."""
84 84
85 85 # Function by Xavier Defrang, originally found at:
86 86 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81330
87 87
88 88 # Create a regular expression from the dictionary keys
89 89 regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))
90 90 # For each match, look-up corresponding value in dictionary
91 91 return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text)
92 92
93 93 #-----------------------------------------------------------------------------
94 94 # Special characters that can be used in prompt templates, mainly bash-like
95 95
96 96 # If $HOME isn't defined (Windows), make it an absurd string so that it can
97 97 # never be expanded out into '~'. Basically anything which can never be a
98 98 # reasonable directory name will do, we just want the $HOME -> '~' operation
99 99 # to become a no-op. We pre-compute $HOME here so it's not done on every
100 100 # prompt call.
101 101
102 102 # FIXME:
103 103
104 104 # - This should be turned into a class which does proper namespace management,
105 105 # since the prompt specials need to be evaluated in a certain namespace.
106 106 # Currently it's just globals, which need to be managed manually by code
107 107 # below.
108 108
109 109 # - I also need to split up the color schemes from the prompt specials
110 110 # somehow. I don't have a clean design for that quite yet.
111 111
112 112 HOME = os.environ.get("HOME","//////:::::ZZZZZ,,,~~~")
113 113
114 114 # We precompute a few more strings here for the prompt_specials, which are
115 115 # fixed once ipython starts. This reduces the runtime overhead of computing
116 116 # prompt strings.
117 117 USER = os.environ.get("USER")
118 118 HOSTNAME = socket.gethostname()
119 119 HOSTNAME_SHORT = HOSTNAME.split(".")[0]
120 120 ROOT_SYMBOL = "$#"[os.name=='nt' or os.getuid()==0]
121 121
122 122 prompt_specials_color = {
123 123 # Prompt/history count
124 124 '%n' : '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
125 125 r'\#': '${self.col_num}' '${self.cache.prompt_count}' '${self.col_p}',
126 126 # Just the prompt counter number, WITHOUT any coloring wrappers, so users
127 127 # can get numbers displayed in whatever color they want.
128 128 r'\N': '${self.cache.prompt_count}',
129 129 # Prompt/history count, with the actual digits replaced by dots. Used
130 130 # mainly in continuation prompts (prompt_in2)
131 r'\D': '${"."*len(str(self.cache.prompt_count))}',
131 r'\D': '${"."*__builtins__.len(__builtins__.str(self.cache.prompt_count))}',
132 132 # Current working directory
133 133 r'\w': '${os.getcwd()}',
134 134 # Current time
135 135 r'\t' : '${time.strftime("%H:%M:%S")}',
136 136 # Basename of current working directory.
137 137 # (use os.sep to make this portable across OSes)
138 138 r'\W' : '${os.getcwd().split("%s")[-1]}' % os.sep,
139 139 # These X<N> are an extension to the normal bash prompts. They return
140 140 # N terms of the path, after replacing $HOME with '~'
141 141 r'\X0': '${os.getcwd().replace("%s","~")}' % HOME,
142 142 r'\X1': '${self.cwd_filt(1)}',
143 143 r'\X2': '${self.cwd_filt(2)}',
144 144 r'\X3': '${self.cwd_filt(3)}',
145 145 r'\X4': '${self.cwd_filt(4)}',
146 146 r'\X5': '${self.cwd_filt(5)}',
147 147 # Y<N> are similar to X<N>, but they show '~' if it's the directory
148 148 # N+1 in the list. Somewhat like %cN in tcsh.
149 149 r'\Y0': '${self.cwd_filt2(0)}',
150 150 r'\Y1': '${self.cwd_filt2(1)}',
151 151 r'\Y2': '${self.cwd_filt2(2)}',
152 152 r'\Y3': '${self.cwd_filt2(3)}',
153 153 r'\Y4': '${self.cwd_filt2(4)}',
154 154 r'\Y5': '${self.cwd_filt2(5)}',
155 155 # Hostname up to first .
156 156 r'\h': HOSTNAME_SHORT,
157 157 # Full hostname
158 158 r'\H': HOSTNAME,
159 159 # Username of current user
160 160 r'\u': USER,
161 161 # Escaped '\'
162 162 '\\\\': '\\',
163 163 # Newline
164 164 r'\n': '\n',
165 165 # Carriage return
166 166 r'\r': '\r',
167 167 # Release version
168 168 r'\v': Release.version,
169 169 # Root symbol ($ or #)
170 170 r'\$': ROOT_SYMBOL,
171 171 }
172 172
173 173 # A copy of the prompt_specials dictionary but with all color escapes removed,
174 174 # so we can correctly compute the prompt length for the auto_rewrite method.
175 175 prompt_specials_nocolor = prompt_specials_color.copy()
176 176 prompt_specials_nocolor['%n'] = '${self.cache.prompt_count}'
177 177 prompt_specials_nocolor[r'\#'] = '${self.cache.prompt_count}'
178 178
179 179 # Add in all the InputTermColors color escapes as valid prompt characters.
180 180 # They all get added as \\C_COLORNAME, so that we don't have any conflicts
181 181 # with a color name which may begin with a letter used by any other of the
182 182 # allowed specials. This of course means that \\C will never be allowed for
183 183 # anything else.
184 184 input_colors = ColorANSI.InputTermColors
185 185 for _color in dir(input_colors):
186 186 if _color[0] != '_':
187 187 c_name = r'\C_'+_color
188 188 prompt_specials_color[c_name] = getattr(input_colors,_color)
189 189 prompt_specials_nocolor[c_name] = ''
190 190
191 191 # we default to no color for safety. Note that prompt_specials is a global
192 192 # variable used by all prompt objects.
193 193 prompt_specials = prompt_specials_nocolor
194 194
195 195 #-----------------------------------------------------------------------------
196 196 def str_safe(arg):
197 197 """Convert to a string, without ever raising an exception.
198 198
199 199 If str(arg) fails, <ERROR: ... > is returned, where ... is the exception
200 200 error message."""
201 201
202 202 try:
203 203 out = str(arg)
204 204 except UnicodeError:
205 205 try:
206 206 out = arg.encode('utf_8','replace')
207 207 except Exception,msg:
208 208 # let's keep this little duplication here, so that the most common
209 209 # case doesn't suffer from a double try wrapping.
210 210 out = '<ERROR: %s>' % msg
211 211 except Exception,msg:
212 212 out = '<ERROR: %s>' % msg
213 213 return out
214 214
215 215 class BasePrompt(object):
216 216 """Interactive prompt similar to Mathematica's."""
217 217
218 218 def _get_p_template(self):
219 219 return self._p_template
220 220
221 221 def _set_p_template(self,val):
222 222 self._p_template = val
223 223 self.set_p_str()
224 224
225 225 p_template = property(_get_p_template,_set_p_template,
226 226 doc='Template for prompt string creation')
227 227
228 228 def __init__(self,cache,sep,prompt,pad_left=False):
229 229
230 230 # Hack: we access information about the primary prompt through the
231 231 # cache argument. We need this, because we want the secondary prompt
232 232 # to be aligned with the primary one. Color table info is also shared
233 233 # by all prompt classes through the cache. Nice OO spaghetti code!
234 234 self.cache = cache
235 235 self.sep = sep
236 236
237 237 # regexp to count the number of spaces at the end of a prompt
238 238 # expression, useful for prompt auto-rewriting
239 239 self.rspace = re.compile(r'(\s*)$')
240 240 # Flag to left-pad prompt strings to match the length of the primary
241 241 # prompt
242 242 self.pad_left = pad_left
243 243
244 244 # Set template to create each actual prompt (where numbers change).
245 245 # Use a property
246 246 self.p_template = prompt
247 247 self.set_p_str()
248 248
249 249 def set_p_str(self):
250 250 """ Set the interpolating prompt strings.
251 251
252 252 This must be called every time the color settings change, because the
253 253 prompt_specials global may have changed."""
254 254
255 255 import os,time # needed in locals for prompt string handling
256 256 loc = locals()
257 257 try:
258 258 self.p_str = ItplNS('%s%s%s' %
259 259 ('${self.sep}${self.col_p}',
260 260 multiple_replace(prompt_specials, self.p_template),
261 261 '${self.col_norm}'),self.cache.user_ns,loc)
262 262
263 263 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
264 264 self.p_template),
265 265 self.cache.user_ns,loc)
266 266 except:
267 267 print "Illegal prompt template (check $ usage!):",self.p_template
268 268 self.p_str = self.p_template
269 269 self.p_str_nocolor = self.p_template
270 270
271 271 def write(self,msg): # dbg
272 272 sys.stdout.write(msg)
273 273 return ''
274 274
275 275 def __str__(self):
276 276 """Return a string form of the prompt.
277 277
278 278 This for is useful for continuation and output prompts, since it is
279 279 left-padded to match lengths with the primary one (if the
280 280 self.pad_left attribute is set)."""
281 281
282 282 out_str = str_safe(self.p_str)
283 283 if self.pad_left:
284 284 # We must find the amount of padding required to match lengths,
285 285 # taking the color escapes (which are invisible on-screen) into
286 286 # account.
287 287 esc_pad = len(out_str) - len(str_safe(self.p_str_nocolor))
288 288 format = '%%%ss' % (len(str(self.cache.last_prompt))+esc_pad)
289 289 return format % out_str
290 290 else:
291 291 return out_str
292 292
293 293 # these path filters are put in as methods so that we can control the
294 294 # namespace where the prompt strings get evaluated
295 295 def cwd_filt(self,depth):
296 296 """Return the last depth elements of the current working directory.
297 297
298 298 $HOME is always replaced with '~'.
299 299 If depth==0, the full path is returned."""
300 300
301 301 cwd = os.getcwd().replace(HOME,"~")
302 302 out = os.sep.join(cwd.split(os.sep)[-depth:])
303 303 if out:
304 304 return out
305 305 else:
306 306 return os.sep
307 307
308 308 def cwd_filt2(self,depth):
309 309 """Return the last depth elements of the current working directory.
310 310
311 311 $HOME is always replaced with '~'.
312 312 If depth==0, the full path is returned."""
313 313
314 314 full_cwd = os.getcwd()
315 315 cwd = full_cwd.replace(HOME,"~").split(os.sep)
316 316 if '~' in cwd and len(cwd) == depth+1:
317 317 depth += 1
318 318 drivepart = ''
319 319 if sys.platform == 'win32' and len(cwd) > depth:
320 320 drivepart = os.path.splitdrive(full_cwd)[0]
321 321 out = drivepart + '/'.join(cwd[-depth:])
322 322
323 323 if out:
324 324 return out
325 325 else:
326 326 return os.sep
327 327
328 328 def __nonzero__(self):
329 329 """Implement boolean behavior.
330 330
331 331 Checks whether the p_str attribute is non-empty"""
332 332
333 333 return bool(self.p_template)
334 334
335 335 class Prompt1(BasePrompt):
336 336 """Input interactive prompt similar to Mathematica's."""
337 337
338 338 def __init__(self,cache,sep='\n',prompt='In [\\#]: ',pad_left=True):
339 339 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
340 340
341 341 def set_colors(self):
342 342 self.set_p_str()
343 343 Colors = self.cache.color_table.active_colors # shorthand
344 344 self.col_p = Colors.in_prompt
345 345 self.col_num = Colors.in_number
346 346 self.col_norm = Colors.in_normal
347 347 # We need a non-input version of these escapes for the '--->'
348 348 # auto-call prompts used in the auto_rewrite() method.
349 349 self.col_p_ni = self.col_p.replace('\001','').replace('\002','')
350 350 self.col_norm_ni = Colors.normal
351 351
352 352 def __str__(self):
353 353 self.cache.prompt_count += 1
354 354 self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1]
355 355 return str_safe(self.p_str)
356 356
357 357 def auto_rewrite(self):
358 358 """Print a string of the form '--->' which lines up with the previous
359 359 input string. Useful for systems which re-write the user input when
360 360 handling automatically special syntaxes."""
361 361
362 362 curr = str(self.cache.last_prompt)
363 363 nrspaces = len(self.rspace.search(curr).group())
364 364 return '%s%s>%s%s' % (self.col_p_ni,'-'*(len(curr)-nrspaces-1),
365 365 ' '*nrspaces,self.col_norm_ni)
366 366
367 367 class PromptOut(BasePrompt):
368 368 """Output interactive prompt similar to Mathematica's."""
369 369
370 370 def __init__(self,cache,sep='',prompt='Out[\\#]: ',pad_left=True):
371 371 BasePrompt.__init__(self,cache,sep,prompt,pad_left)
372 372 if not self.p_template:
373 373 self.__str__ = lambda: ''
374 374
375 375 def set_colors(self):
376 376 self.set_p_str()
377 377 Colors = self.cache.color_table.active_colors # shorthand
378 378 self.col_p = Colors.out_prompt
379 379 self.col_num = Colors.out_number
380 380 self.col_norm = Colors.normal
381 381
382 382 class Prompt2(BasePrompt):
383 383 """Interactive continuation prompt."""
384 384
385 385 def __init__(self,cache,prompt=' .\\D.: ',pad_left=True):
386 386 self.cache = cache
387 387 self.p_template = prompt
388 388 self.pad_left = pad_left
389 389 self.set_p_str()
390 390
391 391 def set_p_str(self):
392 392 import os,time # needed in locals for prompt string handling
393 393 loc = locals()
394 394 self.p_str = ItplNS('%s%s%s' %
395 395 ('${self.col_p2}',
396 396 multiple_replace(prompt_specials, self.p_template),
397 397 '$self.col_norm'),
398 398 self.cache.user_ns,loc)
399 399 self.p_str_nocolor = ItplNS(multiple_replace(prompt_specials_nocolor,
400 400 self.p_template),
401 401 self.cache.user_ns,loc)
402 402
403 403 def set_colors(self):
404 404 self.set_p_str()
405 405 Colors = self.cache.color_table.active_colors
406 406 self.col_p2 = Colors.in_prompt2
407 407 self.col_norm = Colors.in_normal
408 408 # FIXME (2004-06-16) HACK: prevent crashes for users who haven't
409 409 # updated their prompt_in2 definitions. Remove eventually.
410 410 self.col_p = Colors.out_prompt
411 411 self.col_num = Colors.out_number
412 412
413 413
414 414 #-----------------------------------------------------------------------------
415 415 class CachedOutput:
416 416 """Class for printing output from calculations while keeping a cache of
417 417 reults. It dynamically creates global variables prefixed with _ which
418 418 contain these results.
419 419
420 420 Meant to be used as a sys.displayhook replacement, providing numbered
421 421 prompts and cache services.
422 422
423 423 Initialize with initial and final values for cache counter (this defines
424 424 the maximum size of the cache."""
425 425
426 426 def __init__(self,shell,cache_size,Pprint,
427 427 colors='NoColor',input_sep='\n',
428 428 output_sep='\n',output_sep2='',
429 429 ps1 = None, ps2 = None,ps_out = None,pad_left=True):
430 430
431 431 cache_size_min = 3
432 432 if cache_size <= 0:
433 433 self.do_full_cache = 0
434 434 cache_size = 0
435 435 elif cache_size < cache_size_min:
436 436 self.do_full_cache = 0
437 437 cache_size = 0
438 438 warn('caching was disabled (min value for cache size is %s).' %
439 439 cache_size_min,level=3)
440 440 else:
441 441 self.do_full_cache = 1
442 442
443 443 self.cache_size = cache_size
444 444 self.input_sep = input_sep
445 445
446 446 # we need a reference to the user-level namespace
447 447 self.shell = shell
448 448 self.user_ns = shell.user_ns
449 449 # and to the user's input
450 450 self.input_hist = shell.input_hist
451 451 # and to the user's logger, for logging output
452 452 self.logger = shell.logger
453 453
454 454 # Set input prompt strings and colors
455 455 if cache_size == 0:
456 456 if ps1.find('%n') > -1 or ps1.find(r'\#') > -1 \
457 457 or ps1.find(r'\N') > -1:
458 458 ps1 = '>>> '
459 459 if ps2.find('%n') > -1 or ps2.find(r'\#') > -1 \
460 460 or ps2.find(r'\N') > -1:
461 461 ps2 = '... '
462 462 self.ps1_str = self._set_prompt_str(ps1,'In [\\#]: ','>>> ')
463 463 self.ps2_str = self._set_prompt_str(ps2,' .\\D.: ','... ')
464 464 self.ps_out_str = self._set_prompt_str(ps_out,'Out[\\#]: ','')
465 465
466 466 self.color_table = PromptColors
467 467 self.prompt1 = Prompt1(self,sep=input_sep,prompt=self.ps1_str,
468 468 pad_left=pad_left)
469 469 self.prompt2 = Prompt2(self,prompt=self.ps2_str,pad_left=pad_left)
470 470 self.prompt_out = PromptOut(self,sep='',prompt=self.ps_out_str,
471 471 pad_left=pad_left)
472 472 self.set_colors(colors)
473 473
474 474 # other more normal stuff
475 475 # b/c each call to the In[] prompt raises it by 1, even the first.
476 476 self.prompt_count = 0
477 477 # Store the last prompt string each time, we need it for aligning
478 478 # continuation and auto-rewrite prompts
479 479 self.last_prompt = ''
480 480 self.Pprint = Pprint
481 481 self.output_sep = output_sep
482 482 self.output_sep2 = output_sep2
483 483 self._,self.__,self.___ = '','',''
484 484 self.pprint_types = map(type,[(),[],{}])
485 485
486 486 # these are deliberately global:
487 487 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
488 488 self.user_ns.update(to_user_ns)
489 489
490 490 def _set_prompt_str(self,p_str,cache_def,no_cache_def):
491 491 if p_str is None:
492 492 if self.do_full_cache:
493 493 return cache_def
494 494 else:
495 495 return no_cache_def
496 496 else:
497 497 return p_str
498 498
499 499 def set_colors(self,colors):
500 500 """Set the active color scheme and configure colors for the three
501 501 prompt subsystems."""
502 502
503 503 # FIXME: the prompt_specials global should be gobbled inside this
504 504 # class instead. Do it when cleaning up the whole 3-prompt system.
505 505 global prompt_specials
506 506 if colors.lower()=='nocolor':
507 507 prompt_specials = prompt_specials_nocolor
508 508 else:
509 509 prompt_specials = prompt_specials_color
510 510
511 511 self.color_table.set_active_scheme(colors)
512 512 self.prompt1.set_colors()
513 513 self.prompt2.set_colors()
514 514 self.prompt_out.set_colors()
515 515
516 516 def __call__(self,arg=None):
517 517 """Printing with history cache management.
518 518
519 519 This is invoked everytime the interpreter needs to print, and is
520 520 activated by setting the variable sys.displayhook to it."""
521 521
522 522 # If something injected a '_' variable in __builtin__, delete
523 523 # ipython's automatic one so we don't clobber that. gettext() in
524 524 # particular uses _, so we need to stay away from it.
525 525 if '_' in __builtin__.__dict__:
526 526 try:
527 527 del self.user_ns['_']
528 528 except KeyError:
529 529 pass
530 530 if arg is not None:
531 531 cout_write = Term.cout.write # fast lookup
532 532 # first handle the cache and counters
533 533
534 534 # do not print output if input ends in ';'
535 535 try:
536 536 if self.input_hist[self.prompt_count].endswith(';\n'):
537 537 return
538 538 except IndexError:
539 539 # some uses of ipshellembed may fail here
540 540 pass
541 541 # don't use print, puts an extra space
542 542 cout_write(self.output_sep)
543 543 outprompt = self.shell.hooks.generate_output_prompt()
544 544 if self.do_full_cache:
545 545 cout_write(outprompt)
546 546
547 547 # and now call a possibly user-defined print mechanism
548 548 manipulated_val = self.display(arg)
549 549
550 550 # user display hooks can change the variable to be stored in
551 551 # output history
552 552
553 553 if manipulated_val is not None:
554 554 arg = manipulated_val
555 555
556 556 # avoid recursive reference when displaying _oh/Out
557 557 if arg is not self.user_ns['_oh']:
558 558 self.update(arg)
559 559
560 560 if self.logger.log_output:
561 561 self.logger.log_write(repr(arg),'output')
562 562 cout_write(self.output_sep2)
563 563 Term.cout.flush()
564 564
565 565 def _display(self,arg):
566 566 """Default printer method, uses pprint.
567 567
568 568 Do ip.set_hook("result_display", my_displayhook) for custom result
569 569 display, e.g. when your own objects need special formatting.
570 570 """
571 571 try:
572 572 return IPython.generics.result_display(arg)
573 573 except TryNext:
574 574 return self.shell.hooks.result_display(arg)
575 575
576 576 # Assign the default display method:
577 577 display = _display
578 578
579 579 def update(self,arg):
580 580 #print '***cache_count', self.cache_count # dbg
581 581 if len(self.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
582 582 warn('Output cache limit (currently '+
583 583 `self.cache_size`+' entries) hit.\n'
584 584 'Flushing cache and resetting history counter...\n'
585 585 'The only history variables available will be _,__,___ and _1\n'
586 586 'with the current result.')
587 587
588 588 self.flush()
589 589 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
590 590 # we cause buggy behavior for things like gettext).
591 591 if '_' not in __builtin__.__dict__:
592 592 self.___ = self.__
593 593 self.__ = self._
594 594 self._ = arg
595 595 self.user_ns.update({'_':self._,'__':self.__,'___':self.___})
596 596
597 597 # hackish access to top-level namespace to create _1,_2... dynamically
598 598 to_main = {}
599 599 if self.do_full_cache:
600 600 new_result = '_'+`self.prompt_count`
601 601 to_main[new_result] = arg
602 602 self.user_ns.update(to_main)
603 603 self.user_ns['_oh'][self.prompt_count] = arg
604 604
605 605 def flush(self):
606 606 if not self.do_full_cache:
607 607 raise ValueError,"You shouldn't have reached the cache flush "\
608 608 "if full caching is not enabled!"
609 609 # delete auto-generated vars from global namespace
610 610
611 611 for n in range(1,self.prompt_count + 1):
612 612 key = '_'+`n`
613 613 try:
614 614 del self.user_ns[key]
615 615 except: pass
616 616 self.user_ns['_oh'].clear()
617 617
618 618 if '_' not in __builtin__.__dict__:
619 619 self.user_ns.update({'_':None,'__':None, '___':None})
620 620 import gc
621 621 gc.collect() # xxx needed?
622 622
General Comments 0
You need to be logged in to leave comments. Login now