Show More
|
1 | NO CONTENT: modified file chmod 100644 => 100755 |
@@ -54,8 +54,9 b' class DisplayHook(Configurable):' | |||
|
54 | 54 | """ |
|
55 | 55 | |
|
56 | 56 | shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') |
|
57 | ||
|
57 | 58 | # Each call to the In[] prompt raises it by 1, even the first. |
|
58 | prompt_count = Int(0) | |
|
59 | #prompt_count = Int(0) | |
|
59 | 60 | |
|
60 | 61 | def __init__(self, shell=None, cache_size=1000, |
|
61 | 62 | colors='NoColor', input_sep='\n', |
@@ -114,6 +115,10 b' class DisplayHook(Configurable):' | |||
|
114 | 115 | to_user_ns = {'_':self._,'__':self.__,'___':self.___} |
|
115 | 116 | self.shell.user_ns.update(to_user_ns) |
|
116 | 117 | |
|
118 | @property | |
|
119 | def prompt_count(self): | |
|
120 | return self.shell.execution_count | |
|
121 | ||
|
117 | 122 | def _set_prompt_str(self,p_str,cache_def,no_cache_def): |
|
118 | 123 | if p_str is None: |
|
119 | 124 | if self.do_full_cache: |
@@ -249,7 +254,7 b' class DisplayHook(Configurable):' | |||
|
249 | 254 | def log_output(self, result): |
|
250 | 255 | """Log the output.""" |
|
251 | 256 | if self.shell.logger.log_output: |
|
252 | self.shell.logger.log_write(repr(result),'output') | |
|
257 | self.shell.logger.log_write(repr(result), 'output') | |
|
253 | 258 | |
|
254 | 259 | def finish_displayhook(self): |
|
255 | 260 | """Finish up all displayhook activities.""" |
@@ -1,14 +1,238 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | 1 |
|
|
2 | #----------------------------------------------------------------------------- | |
|
3 | # Copyright (C) 2010 The IPython Development Team. | |
|
4 | # | |
|
5 | # Distributed under the terms of the BSD License. | |
|
6 | # | |
|
7 | # The full license is in the file COPYING.txt, distributed with this software. | |
|
8 | #----------------------------------------------------------------------------- | |
|
9 | ||
|
10 | #----------------------------------------------------------------------------- | |
|
11 | # Imports | |
|
12 | #----------------------------------------------------------------------------- | |
|
13 | from __future__ import print_function | |
|
3 | 14 | |
|
4 | 15 | # Stdlib imports |
|
5 | 16 | import fnmatch |
|
6 | 17 | import os |
|
18 | import sys | |
|
7 | 19 | |
|
20 | # Our own packages | |
|
8 | 21 | import IPython.utils.io |
|
22 | ||
|
23 | from IPython.core import ipapi | |
|
24 | from IPython.core.inputlist import InputList | |
|
25 | from IPython.utils.pickleshare import PickleShareDB | |
|
9 | 26 | from IPython.utils.io import ask_yes_no |
|
10 | 27 | from IPython.utils.warn import warn |
|
11 | from IPython.core import ipapi | |
|
28 | ||
|
29 | #----------------------------------------------------------------------------- | |
|
30 | # Classes and functions | |
|
31 | #----------------------------------------------------------------------------- | |
|
32 | ||
|
33 | class HistoryManager(object): | |
|
34 | """A class to organize all history-related functionality in one place. | |
|
35 | """ | |
|
36 | # Public interface | |
|
37 | ||
|
38 | # An instance of the IPython shell we are attached to | |
|
39 | shell = None | |
|
40 | # An InputList instance to hold processed history | |
|
41 | input_hist = None | |
|
42 | # An InputList instance to hold raw history (as typed by user) | |
|
43 | input_hist_raw = None | |
|
44 | # A list of directories visited during session | |
|
45 | dir_hist = None | |
|
46 | # A dict of output history, keyed with ints from the shell's execution count | |
|
47 | output_hist = None | |
|
48 | # String with path to the history file | |
|
49 | hist_file = None | |
|
50 | # PickleShareDB instance holding the raw data for the shadow history | |
|
51 | shadow_db = None | |
|
52 | # ShadowHist instance with the actual shadow history | |
|
53 | shadow_hist = None | |
|
54 | ||
|
55 | # Private interface | |
|
56 | # Variables used to store the three last inputs from the user. On each new | |
|
57 | # history update, we populate the user's namespace with these, shifted as | |
|
58 | # necessary. | |
|
59 | _i00, _i, _ii, _iii = '','','','' | |
|
60 | ||
|
61 | def __init__(self, shell): | |
|
62 | """Create a new history manager associated with a shell instance. | |
|
63 | """ | |
|
64 | # We need a pointer back to the shell for various tasks. | |
|
65 | self.shell = shell | |
|
66 | ||
|
67 | # List of input with multi-line handling. | |
|
68 | self.input_hist = InputList() | |
|
69 | # This one will hold the 'raw' input history, without any | |
|
70 | # pre-processing. This will allow users to retrieve the input just as | |
|
71 | # it was exactly typed in by the user, with %hist -r. | |
|
72 | self.input_hist_raw = InputList() | |
|
73 | ||
|
74 | # list of visited directories | |
|
75 | try: | |
|
76 | self.dir_hist = [os.getcwd()] | |
|
77 | except OSError: | |
|
78 | self.dir_hist = [] | |
|
79 | ||
|
80 | # dict of output history | |
|
81 | self.output_hist = {} | |
|
82 | ||
|
83 | # Now the history file | |
|
84 | if shell.profile: | |
|
85 | histfname = 'history-%s' % shell.profile | |
|
86 | else: | |
|
87 | histfname = 'history' | |
|
88 | self.hist_file = os.path.join(shell.ipython_dir, histfname) | |
|
89 | ||
|
90 | # Objects related to shadow history management | |
|
91 | self._init_shadow_hist() | |
|
92 | ||
|
93 | self._i00, self._i, self._ii, self._iii = '','','','' | |
|
94 | ||
|
95 | # Object is fully initialized, we can now call methods on it. | |
|
96 | ||
|
97 | # Fill the history zero entry, user counter starts at 1 | |
|
98 | self.store_inputs('\n', '\n') | |
|
99 | ||
|
100 | # For backwards compatibility, we must put these back in the shell | |
|
101 | # object, until we've removed all direct uses of the history objects in | |
|
102 | # the shell itself. | |
|
103 | shell.input_hist = self.input_hist | |
|
104 | shell.input_hist_raw = self.input_hist_raw | |
|
105 | shell.output_hist = self.output_hist | |
|
106 | shell.dir_hist = self.dir_hist | |
|
107 | shell.histfile = self.hist_file | |
|
108 | shell.shadowhist = self.shadow_hist | |
|
109 | shell.db = self.shadow_db | |
|
110 | ||
|
111 | def _init_shadow_hist(self): | |
|
112 | try: | |
|
113 | self.shadow_db = PickleShareDB(os.path.join( | |
|
114 | self.shell.ipython_dir, 'db')) | |
|
115 | except UnicodeDecodeError: | |
|
116 | print("Your ipython_dir can't be decoded to unicode!") | |
|
117 | print("Please set HOME environment variable to something that") | |
|
118 | print(r"only has ASCII characters, e.g. c:\home") | |
|
119 | print("Now it is", self.ipython_dir) | |
|
120 | sys.exit() | |
|
121 | self.shadow_hist = ShadowHist(self.shadow_db) | |
|
122 | ||
|
123 | def save_hist(self): | |
|
124 | """Save input history to a file (via readline library).""" | |
|
125 | ||
|
126 | try: | |
|
127 | self.shell.readline.write_history_file(self.hist_file) | |
|
128 | except: | |
|
129 | print('Unable to save IPython command history to file: ' + | |
|
130 | `self.hist_file`) | |
|
131 | ||
|
132 | def reload_hist(self): | |
|
133 | """Reload the input history from disk file.""" | |
|
134 | ||
|
135 | try: | |
|
136 | self.shell.readline.clear_history() | |
|
137 | self.shell.readline.read_history_file(self.hist_file) | |
|
138 | except AttributeError: | |
|
139 | pass | |
|
140 | ||
|
141 | def get_history(self, index=None, raw=False, output=True): | |
|
142 | """Get the history list. | |
|
143 | ||
|
144 | Get the input and output history. | |
|
145 | ||
|
146 | Parameters | |
|
147 | ---------- | |
|
148 | index : n or (n1, n2) or None | |
|
149 | If n, then the last entries. If a tuple, then all in | |
|
150 | range(n1, n2). If None, then all entries. Raises IndexError if | |
|
151 | the format of index is incorrect. | |
|
152 | raw : bool | |
|
153 | If True, return the raw input. | |
|
154 | output : bool | |
|
155 | If True, then return the output as well. | |
|
156 | ||
|
157 | Returns | |
|
158 | ------- | |
|
159 | If output is True, then return a dict of tuples, keyed by the prompt | |
|
160 | numbers and with values of (input, output). If output is False, then | |
|
161 | a dict, keyed by the prompt number with the values of input. Raises | |
|
162 | IndexError if no history is found. | |
|
163 | """ | |
|
164 | if raw: | |
|
165 | input_hist = self.input_hist_raw | |
|
166 | else: | |
|
167 | input_hist = self.input_hist | |
|
168 | if output: | |
|
169 | output_hist = self.output_hist | |
|
170 | n = len(input_hist) | |
|
171 | if index is None: | |
|
172 | start=0; stop=n | |
|
173 | elif isinstance(index, int): | |
|
174 | start=n-index; stop=n | |
|
175 | elif isinstance(index, tuple) and len(index) == 2: | |
|
176 | start=index[0]; stop=index[1] | |
|
177 | else: | |
|
178 | raise IndexError('Not a valid index for the input history: %r' | |
|
179 | % index) | |
|
180 | hist = {} | |
|
181 | for i in range(start, stop): | |
|
182 | if output: | |
|
183 | hist[i] = (input_hist[i], output_hist.get(i)) | |
|
184 | else: | |
|
185 | hist[i] = input_hist[i] | |
|
186 | if not hist: | |
|
187 | raise IndexError('No history for range of indices: %r' % index) | |
|
188 | return hist | |
|
189 | ||
|
190 | def store_inputs(self, source, source_raw=None): | |
|
191 | """Store source and raw input in history and create input cache | |
|
192 | variables _i*. | |
|
193 | ||
|
194 | Parameters | |
|
195 | ---------- | |
|
196 | source : str | |
|
197 | Python input. | |
|
198 | ||
|
199 | source_raw : str, optional | |
|
200 | If given, this is the raw input without any IPython transformations | |
|
201 | applied to it. If not given, ``source`` is used. | |
|
202 | """ | |
|
203 | if source_raw is None: | |
|
204 | source_raw = source | |
|
205 | self.input_hist.append(source) | |
|
206 | self.input_hist_raw.append(source_raw) | |
|
207 | self.shadow_hist.add(source) | |
|
208 | ||
|
209 | # update the auto _i variables | |
|
210 | self._iii = self._ii | |
|
211 | self._ii = self._i | |
|
212 | self._i = self._i00 | |
|
213 | self._i00 = source_raw | |
|
214 | ||
|
215 | # hackish access to user namespace to create _i1,_i2... dynamically | |
|
216 | new_i = '_i%s' % self.shell.execution_count | |
|
217 | to_main = {'_i': self._i, | |
|
218 | '_ii': self._ii, | |
|
219 | '_iii': self._iii, | |
|
220 | new_i : self._i00 } | |
|
221 | self.shell.user_ns.update(to_main) | |
|
222 | ||
|
223 | def sync_inputs(self): | |
|
224 | """Ensure raw and translated histories have same length.""" | |
|
225 | if len(self.input_hist) != len (self.input_hist_raw): | |
|
226 | self.input_hist_raw = InputList(self.input_hist) | |
|
227 | ||
|
228 | def reset(self): | |
|
229 | """Clear all histories managed by this object.""" | |
|
230 | self.input_hist[:] = [] | |
|
231 | self.input_hist_raw[:] = [] | |
|
232 | self.output_hist.clear() | |
|
233 | # The directory history can't be completely empty | |
|
234 | self.dir_hist[:] = [os.getcwd()] | |
|
235 | ||
|
12 | 236 | |
|
13 | 237 | def magic_history(self, parameter_s = ''): |
|
14 | 238 | """Print input history (_i<n> variables), with most recent last. |
@@ -55,7 +279,7 b" def magic_history(self, parameter_s = ''):" | |||
|
55 | 279 | """ |
|
56 | 280 | |
|
57 | 281 | if not self.shell.displayhook.do_full_cache: |
|
58 |
print |
|
|
282 | print('This feature is only available if numbered prompts are in use.') | |
|
59 | 283 | return |
|
60 | 284 | opts,args = self.parse_options(parameter_s,'gnoptsrf:',mode='list') |
|
61 | 285 | |
@@ -69,7 +293,7 b" def magic_history(self, parameter_s = ''):" | |||
|
69 | 293 | else: |
|
70 | 294 | if os.path.exists(outfname): |
|
71 | 295 | if not ask_yes_no("File %r exists. Overwrite?" % outfname): |
|
72 |
print |
|
|
296 | print('Aborting.') | |
|
73 | 297 | return |
|
74 | 298 | |
|
75 | 299 | outfile = open(outfname,'w') |
@@ -103,7 +327,7 b" def magic_history(self, parameter_s = ''):" | |||
|
103 | 327 | init, final = map(int, args) |
|
104 | 328 | else: |
|
105 | 329 | warn('%hist takes 0, 1 or 2 arguments separated by spaces.') |
|
106 | print >> IPython.utils.io.Term.cout, self.magic_hist.__doc__ | |
|
330 | print(self.magic_hist.__doc__, file=IPython.utils.io.Term.cout) | |
|
107 | 331 | return |
|
108 | 332 | |
|
109 | 333 | width = len(str(final)) |
@@ -117,14 +341,14 b" def magic_history(self, parameter_s = ''):" | |||
|
117 | 341 | sh = self.shell.shadowhist.all() |
|
118 | 342 | for idx, s in sh: |
|
119 | 343 | if fnmatch.fnmatch(s, pattern): |
|
120 |
print |
|
|
344 | print("0%d: %s" %(idx, s.expandtabs(4)), file=outfile) | |
|
121 | 345 | found = True |
|
122 | 346 | |
|
123 | 347 | if found: |
|
124 |
print |
|
|
125 | print >> outfile, \ | |
|
126 | "shadow history ends, fetch by %rep <number> (must start with 0)" | |
|
127 |
print |
|
|
348 | print("===", file=outfile) | |
|
349 | print("shadow history ends, fetch by %rep <number> (must start with 0)", | |
|
350 | file=outfile) | |
|
351 | print("=== start of normal history ===", file=outfile) | |
|
128 | 352 | |
|
129 | 353 | for in_num in range(init, final): |
|
130 | 354 | # Print user history with tabs expanded to 4 spaces. The GUI clients |
@@ -137,22 +361,22 b" def magic_history(self, parameter_s = ''):" | |||
|
137 | 361 | |
|
138 | 362 | multiline = int(inline.count('\n') > 1) |
|
139 | 363 | if print_nums: |
|
140 | print >> outfile, \ | |
|
141 | '%s:%s' % (str(in_num).ljust(width), line_sep[multiline]), | |
|
364 | print('%s:%s' % (str(in_num).ljust(width), line_sep[multiline]), | |
|
365 | file=outfile) | |
|
142 | 366 | if pyprompts: |
|
143 |
print |
|
|
367 | print('>>>', file=outfile) | |
|
144 | 368 | if multiline: |
|
145 | 369 | lines = inline.splitlines() |
|
146 |
print |
|
|
147 |
print |
|
|
370 | print('\n... '.join(lines), file=outfile) | |
|
371 | print('... ', file=outfile) | |
|
148 | 372 | else: |
|
149 |
print |
|
|
373 | print(inline, end='', file=outfile) | |
|
150 | 374 | else: |
|
151 |
print |
|
|
375 | print(inline,end='', file=outfile) | |
|
152 | 376 | if print_outputs: |
|
153 | 377 | output = self.shell.output_hist.get(in_num) |
|
154 | 378 | if output is not None: |
|
155 |
print |
|
|
379 | print(repr(output), file=outfile) | |
|
156 | 380 | |
|
157 | 381 | if close_at_end: |
|
158 | 382 | outfile.close() |
@@ -223,10 +447,10 b' def rep_f(self, arg):' | |||
|
223 | 447 | |
|
224 | 448 | try: |
|
225 | 449 | lines = self.extract_input_slices(args, True) |
|
226 |
print |
|
|
227 |
self.run |
|
|
450 | print("lines", lines) | |
|
451 | self.run_cell(lines) | |
|
228 | 452 | except ValueError: |
|
229 |
print |
|
|
453 | print("Not found in recent history:", args) | |
|
230 | 454 | |
|
231 | 455 | |
|
232 | 456 | _sentinel = object() |
@@ -251,11 +475,11 b' class ShadowHist(object):' | |||
|
251 | 475 | if old is not _sentinel: |
|
252 | 476 | return |
|
253 | 477 | newidx = self.inc_idx() |
|
254 |
#print |
|
|
478 | #print("new", newidx) # dbg | |
|
255 | 479 | self.db.hset('shadowhist',ent, newidx) |
|
256 | 480 | except: |
|
257 | 481 | ipapi.get().showtraceback() |
|
258 |
print |
|
|
482 | print("WARNING: disabling shadow history") | |
|
259 | 483 | self.disabled = True |
|
260 | 484 | |
|
261 | 485 | def all(self): |
@@ -268,7 +492,6 b' class ShadowHist(object):' | |||
|
268 | 492 | all = self.all() |
|
269 | 493 | |
|
270 | 494 | for k, v in all: |
|
271 | #print k,v | |
|
272 | 495 | if k == idx: |
|
273 | 496 | return v |
|
274 | 497 |
@@ -53,7 +53,7 b' import IPython.utils.io' | |||
|
53 | 53 | __all__ = ['editor', 'fix_error_editor', 'synchronize_with_editor', |
|
54 | 54 | 'input_prefilter', 'shutdown_hook', 'late_startup_hook', |
|
55 | 55 | 'generate_prompt', 'show_in_pager','pre_prompt_hook', |
|
56 | 'pre_runcode_hook', 'clipboard_get'] | |
|
56 | 'pre_run_code_hook', 'clipboard_get'] | |
|
57 | 57 | |
|
58 | 58 | def editor(self,filename, linenum=None): |
|
59 | 59 | """Open the default editor at the given filename and linenumber. |
@@ -238,7 +238,7 b' def pre_prompt_hook(self):' | |||
|
238 | 238 | return None |
|
239 | 239 | |
|
240 | 240 | |
|
241 | def pre_runcode_hook(self): | |
|
241 | def pre_run_code_hook(self): | |
|
242 | 242 | """ Executed before running the (prefiltered) code in IPython """ |
|
243 | 243 | return None |
|
244 | 244 |
@@ -371,15 +371,6 b' class InputSplitter(object):' | |||
|
371 | 371 | if self.input_mode == 'cell': |
|
372 | 372 | self.reset() |
|
373 | 373 | |
|
374 | # If the source code has leading blanks, add 'if 1:\n' to it | |
|
375 | # this allows execution of indented pasted code. It is tempting | |
|
376 | # to add '\n' at the end of source to run commands like ' a=1' | |
|
377 | # directly, but this fails for more complicated scenarios | |
|
378 | ||
|
379 | if not self._buffer and lines[:1] in [' ', '\t'] and \ | |
|
380 | not comment_line_re.match(lines): | |
|
381 | lines = 'if 1:\n%s' % lines | |
|
382 | ||
|
383 | 374 | self._store(lines) |
|
384 | 375 | source = self.source |
|
385 | 376 | |
@@ -594,26 +585,29 b' class InputSplitter(object):' | |||
|
594 | 585 | #print 'safety' # dbg |
|
595 | 586 | |
|
596 | 587 | return indent_spaces, full_dedent |
|
597 |
|
|
|
588 | ||
|
598 | 589 | def _update_indent(self, lines): |
|
599 | 590 | for line in remove_comments(lines).splitlines(): |
|
600 | 591 | if line and not line.isspace(): |
|
601 | 592 | self.indent_spaces, self._full_dedent = self._find_indent(line) |
|
602 | 593 | |
|
603 | def _store(self, lines): | |
|
594 | def _store(self, lines, buffer=None, store='source'): | |
|
604 | 595 | """Store one or more lines of input. |
|
605 | 596 | |
|
606 | 597 | If input lines are not newline-terminated, a newline is automatically |
|
607 | 598 | appended.""" |
|
608 | 599 | |
|
600 | if buffer is None: | |
|
601 | buffer = self._buffer | |
|
602 | ||
|
609 | 603 | if lines.endswith('\n'): |
|
610 |
|
|
|
604 | buffer.append(lines) | |
|
611 | 605 | else: |
|
612 |
|
|
|
613 | self._set_source() | |
|
606 | buffer.append(lines+'\n') | |
|
607 | setattr(self, store, self._set_source(buffer)) | |
|
614 | 608 | |
|
615 | def _set_source(self): | |
|
616 |
|
|
|
609 | def _set_source(self, buffer): | |
|
610 | return ''.join(buffer).encode(self.encoding) | |
|
617 | 611 | |
|
618 | 612 | |
|
619 | 613 | #----------------------------------------------------------------------------- |
@@ -932,6 +926,32 b' transform_escaped = EscapedTransformer()' | |||
|
932 | 926 | class IPythonInputSplitter(InputSplitter): |
|
933 | 927 | """An input splitter that recognizes all of IPython's special syntax.""" |
|
934 | 928 | |
|
929 | # String with raw, untransformed input. | |
|
930 | source_raw = '' | |
|
931 | ||
|
932 | # Private attributes | |
|
933 | ||
|
934 | # List with lines of raw input accumulated so far. | |
|
935 | _buffer_raw = None | |
|
936 | ||
|
937 | def __init__(self, input_mode=None): | |
|
938 | InputSplitter.__init__(self, input_mode) | |
|
939 | self._buffer_raw = [] | |
|
940 | ||
|
941 | def reset(self): | |
|
942 | """Reset the input buffer and associated state.""" | |
|
943 | InputSplitter.reset(self) | |
|
944 | self._buffer_raw[:] = [] | |
|
945 | self.source_raw = '' | |
|
946 | ||
|
947 | def source_raw_reset(self): | |
|
948 | """Return input and raw source and perform a full reset. | |
|
949 | """ | |
|
950 | out = self.source | |
|
951 | out_r = self.source_raw | |
|
952 | self.reset() | |
|
953 | return out, out_r | |
|
954 | ||
|
935 | 955 | def push(self, lines): |
|
936 | 956 | """Push one or more lines of IPython input. |
|
937 | 957 | """ |
@@ -963,13 +983,18 b' class IPythonInputSplitter(InputSplitter):' | |||
|
963 | 983 | # by one. Note that this only matters if the input has more than one |
|
964 | 984 | # line. |
|
965 | 985 | changed_input_mode = False |
|
966 | ||
|
967 |
if |
|
|
986 | ||
|
987 | if self.input_mode == 'cell': | |
|
968 | 988 | self.reset() |
|
969 | 989 | changed_input_mode = True |
|
970 | 990 | saved_input_mode = 'cell' |
|
971 | 991 | self.input_mode = 'line' |
|
972 | 992 | |
|
993 | # Store raw source before applying any transformations to it. Note | |
|
994 | # that this must be done *after* the reset() call that would otherwise | |
|
995 | # flush the buffer. | |
|
996 | self._store(lines, self._buffer_raw, 'source_raw') | |
|
997 | ||
|
973 | 998 | try: |
|
974 | 999 | push = super(IPythonInputSplitter, self).push |
|
975 | 1000 | for line in lines_list: |
@@ -982,5 +1007,4 b' class IPythonInputSplitter(InputSplitter):' | |||
|
982 | 1007 | finally: |
|
983 | 1008 | if changed_input_mode: |
|
984 | 1009 | self.input_mode = saved_input_mode |
|
985 | ||
|
986 | 1010 | return out |
@@ -1,6 +1,4 b'' | |||
|
1 | # -*- coding: utf-8 -*- | |
|
2 | """ | |
|
3 | Logger class for IPython's logging facilities. | |
|
1 | """Logger class for IPython's logging facilities. | |
|
4 | 2 | """ |
|
5 | 3 | |
|
6 | 4 | #***************************************************************************** |
@@ -26,13 +24,12 b' import time' | |||
|
26 | 24 | class Logger(object): |
|
27 | 25 | """A Logfile class with different policies for file creation""" |
|
28 | 26 | |
|
29 |
def __init__(self, |
|
|
30 | ||
|
31 | self._i00,self._i,self._ii,self._iii = '','','','' | |
|
27 | def __init__(self, home_dir, logfname='Logger.log', loghead='', | |
|
28 | logmode='over'): | |
|
32 | 29 | |
|
33 | 30 | # this is the full ipython instance, we need some attributes from it |
|
34 | 31 | # which won't exist until later. What a mess, clean up later... |
|
35 |
self. |
|
|
32 | self.home_dir = home_dir | |
|
36 | 33 | |
|
37 | 34 | self.logfname = logfname |
|
38 | 35 | self.loghead = loghead |
@@ -102,7 +99,7 b' class Logger(object):' | |||
|
102 | 99 | self.logfile = open(self.logfname,'w') |
|
103 | 100 | |
|
104 | 101 | elif logmode == 'global': |
|
105 |
self.logfname = os.path.join(self. |
|
|
102 | self.logfname = os.path.join(self.home_dir,self.logfname) | |
|
106 | 103 | self.logfile = open(self.logfname, 'a') |
|
107 | 104 | |
|
108 | 105 | elif logmode == 'over': |
@@ -166,63 +163,18 b' which already exists. But you must first start the logging process with' | |||
|
166 | 163 | print 'Timestamping :',self.timestamp |
|
167 | 164 | print 'State :',state |
|
168 | 165 | |
|
169 |
def log(self, |
|
|
170 | """Write the line to a log and create input cache variables _i*. | |
|
166 | def log(self, line_mod, line_ori): | |
|
167 | """Write the sources to a log. | |
|
171 | 168 | |
|
172 | 169 | Inputs: |
|
173 | 170 | |
|
174 | - line_ori: unmodified input line from the user. This is not | |
|
175 | necessarily valid Python. | |
|
176 | ||
|
177 | 171 | - line_mod: possibly modified input, such as the transformations made |
|
178 | 172 | by input prefilters or input handlers of various kinds. This should |
|
179 | 173 | always be valid Python. |
|
180 | 174 | |
|
181 | - continuation: if True, indicates this is part of multi-line input.""" | |
|
182 | ||
|
183 | # update the auto _i tables | |
|
184 | #print '***logging line',line_mod # dbg | |
|
185 | #print '***cache_count', self.shell.displayhook.prompt_count # dbg | |
|
186 | try: | |
|
187 | input_hist = self.shell.user_ns['_ih'] | |
|
188 | except: | |
|
189 | #print 'userns:',self.shell.user_ns.keys() # dbg | |
|
190 | return | |
|
191 | ||
|
192 | out_cache = self.shell.displayhook | |
|
193 | ||
|
194 | # add blank lines if the input cache fell out of sync. | |
|
195 | if out_cache.do_full_cache and \ | |
|
196 | out_cache.prompt_count +1 > len(input_hist): | |
|
197 | input_hist.extend(['\n'] * (out_cache.prompt_count - len(input_hist))) | |
|
198 | ||
|
199 | if not continuation and line_mod: | |
|
200 | self._iii = self._ii | |
|
201 | self._ii = self._i | |
|
202 | self._i = self._i00 | |
|
203 | # put back the final \n of every input line | |
|
204 | self._i00 = line_mod+'\n' | |
|
205 | #print 'Logging input:<%s>' % line_mod # dbg | |
|
206 | input_hist.append(self._i00) | |
|
207 | #print '---[%s]' % (len(input_hist)-1,) # dbg | |
|
208 | ||
|
209 | # hackish access to top-level namespace to create _i1,_i2... dynamically | |
|
210 | to_main = {'_i':self._i,'_ii':self._ii,'_iii':self._iii} | |
|
211 | if self.shell.displayhook.do_full_cache: | |
|
212 | in_num = self.shell.displayhook.prompt_count | |
|
213 | ||
|
214 | # but if the opposite is true (a macro can produce multiple inputs | |
|
215 | # with no output display called), then bring the output counter in | |
|
216 | # sync: | |
|
217 | last_num = len(input_hist)-1 | |
|
218 | if in_num != last_num: | |
|
219 | in_num = self.shell.displayhook.prompt_count = last_num | |
|
220 | new_i = '_i%s' % in_num | |
|
221 | if continuation: | |
|
222 | self._i00 = '%s%s\n' % (self.shell.user_ns[new_i],line_mod) | |
|
223 | input_hist[in_num] = self._i00 | |
|
224 | to_main[new_i] = self._i00 | |
|
225 | self.shell.user_ns.update(to_main) | |
|
175 | - line_ori: unmodified input line from the user. This is not | |
|
176 | necessarily valid Python. | |
|
177 | """ | |
|
226 | 178 | |
|
227 | 179 | # Write the log line, but decide which one according to the |
|
228 | 180 | # log_raw_input flag, set when the log is started. |
@@ -231,7 +183,7 b' which already exists. But you must first start the logging process with' | |||
|
231 | 183 | else: |
|
232 | 184 | self.log_write(line_mod) |
|
233 | 185 | |
|
234 | def log_write(self,data,kind='input'): | |
|
186 | def log_write(self, data, kind='input'): | |
|
235 | 187 | """Write data to the log file, if active""" |
|
236 | 188 | |
|
237 | 189 | #print 'data: %r' % data # dbg |
@@ -241,10 +193,10 b' which already exists. But you must first start the logging process with' | |||
|
241 | 193 | if self.timestamp: |
|
242 | 194 | write(time.strftime('# %a, %d %b %Y %H:%M:%S\n', |
|
243 | 195 | time.localtime())) |
|
244 |
write( |
|
|
196 | write(data) | |
|
245 | 197 | elif kind=='output' and self.log_output: |
|
246 | 198 | odata = '\n'.join(['#[Out]# %s' % s |
|
247 |
for s in data.split( |
|
|
199 | for s in data.splitlines()]) | |
|
248 | 200 | write('%s\n' % odata) |
|
249 | 201 | self.logfile.flush() |
|
250 | 202 |
@@ -20,9 +20,7 b' class Macro(IPyAutocall):' | |||
|
20 | 20 | """ |
|
21 | 21 | |
|
22 | 22 | def __init__(self,data): |
|
23 | ||
|
24 | # store the macro value, as a single string which can be evaluated by | |
|
25 | # runlines() | |
|
23 | # store the macro value, as a single string which can be executed | |
|
26 | 24 | self.value = ''.join(data).rstrip()+'\n' |
|
27 | 25 | |
|
28 | 26 | def __str__(self): |
@@ -34,7 +32,7 b' class Macro(IPyAutocall):' | |||
|
34 | 32 | def __call__(self,*args): |
|
35 | 33 | IPython.utils.io.Term.cout.flush() |
|
36 | 34 | self._ip.user_ns['_margv'] = args |
|
37 |
self._ip.run |
|
|
35 | self._ip.run_cell(self.value) | |
|
38 | 36 | |
|
39 | 37 | def __getstate__(self): |
|
40 | 38 | """ needed for safe pickling via %store """ |
@@ -41,11 +41,6 b' except ImportError:' | |||
|
41 | 41 | except ImportError: |
|
42 | 42 | profile = pstats = None |
|
43 | 43 | |
|
44 | # print_function was added to __future__ in Python2.6, remove this when we drop | |
|
45 | # 2.5 compatibility | |
|
46 | if not hasattr(__future__,'CO_FUTURE_PRINT_FUNCTION'): | |
|
47 | __future__.CO_FUTURE_PRINT_FUNCTION = 65536 | |
|
48 | ||
|
49 | 44 | import IPython |
|
50 | 45 | from IPython.core import debugger, oinspect |
|
51 | 46 | from IPython.core.error import TryNext |
@@ -1556,7 +1551,7 b' Currently the magic system has the following functions:\\n"""' | |||
|
1556 | 1551 | |
|
1557 | 1552 | stats = None |
|
1558 | 1553 | try: |
|
1559 | self.shell.savehist() | |
|
1554 | self.shell.save_hist() | |
|
1560 | 1555 | |
|
1561 | 1556 | if opts.has_key('p'): |
|
1562 | 1557 | stats = self.magic_prun('',0,opts,arg_lst,prog_ns) |
@@ -1675,7 +1670,7 b' Currently the magic system has the following functions:\\n"""' | |||
|
1675 | 1670 | # contained therein. |
|
1676 | 1671 | del sys.modules[main_mod_name] |
|
1677 | 1672 | |
|
1678 | self.shell.reloadhist() | |
|
1673 | self.shell.reload_hist() | |
|
1679 | 1674 | |
|
1680 | 1675 | return stats |
|
1681 | 1676 | |
@@ -2331,7 +2326,7 b' Currently the magic system has the following functions:\\n"""' | |||
|
2331 | 2326 | else: |
|
2332 | 2327 | print 'done. Executing edited code...' |
|
2333 | 2328 | if opts_r: |
|
2334 |
self.shell.run |
|
|
2329 | self.shell.run_cell(file_read(filename)) | |
|
2335 | 2330 | else: |
|
2336 | 2331 | self.shell.safe_execfile(filename,self.shell.user_ns, |
|
2337 | 2332 | self.shell.user_ns) |
@@ -2992,7 +2987,7 b' Defaulting color scheme to \'NoColor\'"""' | |||
|
2992 | 2987 | (input.startswith(start) or input.startswith(start_magic)): |
|
2993 | 2988 | #print 'match',`input` # dbg |
|
2994 | 2989 | print 'Executing:',input, |
|
2995 |
self.shell.run |
|
|
2990 | self.shell.run_cell(input) | |
|
2996 | 2991 | return |
|
2997 | 2992 | print 'No previous input matching `%s` found.' % start |
|
2998 | 2993 |
@@ -373,10 +373,6 b' class PrefilterManager(Configurable):' | |||
|
373 | 373 | # print "prefilter_line: ", line, continue_prompt |
|
374 | 374 | # All handlers *must* return a value, even if it's blank (''). |
|
375 | 375 | |
|
376 | # Lines are NOT logged here. Handlers should process the line as | |
|
377 | # needed, update the cache AND log it (so that the input cache array | |
|
378 | # stays synced). | |
|
379 | ||
|
380 | 376 | # save the line away in case we crash, so the post-mortem handler can |
|
381 | 377 | # record it |
|
382 | 378 | self.shell._last_input_line = line |
@@ -792,7 +788,6 b' class PrefilterHandler(Configurable):' | |||
|
792 | 788 | ): |
|
793 | 789 | line = '' |
|
794 | 790 | |
|
795 | self.shell.log(line, line, continue_prompt) | |
|
796 | 791 | return line |
|
797 | 792 | |
|
798 | 793 | def __str__(self): |
@@ -811,7 +806,6 b' class AliasHandler(PrefilterHandler):' | |||
|
811 | 806 | line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace, |
|
812 | 807 | make_quoted_expr(transformed)) |
|
813 | 808 | |
|
814 | self.shell.log(line_info.line, line_out, line_info.continue_prompt) | |
|
815 | 809 | return line_out |
|
816 | 810 | |
|
817 | 811 | |
@@ -840,8 +834,6 b' class ShellEscapeHandler(PrefilterHandler):' | |||
|
840 | 834 | cmd = line.lstrip().lstrip(ESC_SHELL) |
|
841 | 835 | line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace, |
|
842 | 836 | make_quoted_expr(cmd)) |
|
843 | # update cache/log and return | |
|
844 | self.shell.log(line, line_out, line_info.continue_prompt) | |
|
845 | 837 | return line_out |
|
846 | 838 | |
|
847 | 839 | |
@@ -856,7 +848,6 b' class MagicHandler(PrefilterHandler):' | |||
|
856 | 848 | the_rest = line_info.the_rest |
|
857 | 849 | cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace, |
|
858 | 850 | make_quoted_expr(ifun + " " + the_rest)) |
|
859 | self.shell.log(line_info.line, cmd, line_info.continue_prompt) | |
|
860 | 851 | return cmd |
|
861 | 852 | |
|
862 | 853 | |
@@ -877,7 +868,6 b' class AutoHandler(PrefilterHandler):' | |||
|
877 | 868 | |
|
878 | 869 | # This should only be active for single-line input! |
|
879 | 870 | if continue_prompt: |
|
880 | self.shell.log(line,line,continue_prompt) | |
|
881 | 871 | return line |
|
882 | 872 | |
|
883 | 873 | force_auto = isinstance(obj, IPyAutocall) |
@@ -918,9 +908,6 b' class AutoHandler(PrefilterHandler):' | |||
|
918 | 908 | if auto_rewrite: |
|
919 | 909 | self.shell.auto_rewrite_input(newcmd) |
|
920 | 910 | |
|
921 | # log what is now valid Python, not the actual user input (without the | |
|
922 | # final newline) | |
|
923 | self.shell.log(line,newcmd,continue_prompt) | |
|
924 | 911 | return newcmd |
|
925 | 912 | |
|
926 | 913 | |
@@ -947,7 +934,6 b' class HelpHandler(PrefilterHandler):' | |||
|
947 | 934 | line = line[1:] |
|
948 | 935 | elif line[-1]==ESC_HELP: |
|
949 | 936 | line = line[:-1] |
|
950 | self.shell.log(line, '#?'+line, line_info.continue_prompt) | |
|
951 | 937 | if line: |
|
952 | 938 | #print 'line:<%r>' % line # dbg |
|
953 | 939 | self.shell.magic_pinfo(line) |
@@ -372,15 +372,7 b' class Prompt1(BasePrompt):' | |||
|
372 | 372 | self.col_p_ni = self.col_p.replace('\001','').replace('\002','') |
|
373 | 373 | self.col_norm_ni = Colors.normal |
|
374 | 374 | |
|
375 | def peek_next_prompt(self): | |
|
376 | """Get the next prompt, but don't increment the counter.""" | |
|
377 | self.cache.prompt_count += 1 | |
|
378 | next_prompt = str_safe(self.p_str) | |
|
379 | self.cache.prompt_count -= 1 | |
|
380 | return next_prompt | |
|
381 | ||
|
382 | 375 | def __str__(self): |
|
383 | self.cache.prompt_count += 1 | |
|
384 | 376 | self.cache.last_prompt = str_safe(self.p_str_nocolor).split('\n')[-1] |
|
385 | 377 | return str_safe(self.p_str) |
|
386 | 378 |
@@ -162,6 +162,12 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
162 | 162 | self.assertEqual(isp.indent_spaces, 4) |
|
163 | 163 | isp.push('y=2\n') |
|
164 | 164 | self.assertEqual(isp.indent_spaces, 0) |
|
165 | ||
|
166 | def test_indent2(self): | |
|
167 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
168 | if self.isp.input_mode == 'cell': return | |
|
169 | ||
|
170 | isp = self.isp | |
|
165 | 171 | isp.push('if 1:') |
|
166 | 172 | self.assertEqual(isp.indent_spaces, 4) |
|
167 | 173 | isp.push(' x=1') |
@@ -170,7 +176,10 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
170 | 176 | isp.push(' '*2) |
|
171 | 177 | self.assertEqual(isp.indent_spaces, 4) |
|
172 | 178 | |
|
173 |
def test_indent |
|
|
179 | def test_indent3(self): | |
|
180 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
181 | if self.isp.input_mode == 'cell': return | |
|
182 | ||
|
174 | 183 | isp = self.isp |
|
175 | 184 | # When a multiline statement contains parens or multiline strings, we |
|
176 | 185 | # shouldn't get confused. |
@@ -195,13 +204,6 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
195 | 204 | for line in [' x=1', '# a comment', ' y=2']: |
|
196 | 205 | self.assertTrue(isp.push(line)) |
|
197 | 206 | |
|
198 | def test_push3(self): | |
|
199 | """Test input with leading whitespace""" | |
|
200 | isp = self.isp | |
|
201 | isp.push(' x=1') | |
|
202 | isp.push(' y=2') | |
|
203 | self.assertEqual(isp.source, 'if 1:\n x=1\n y=2\n') | |
|
204 | ||
|
205 | 207 | def test_replace_mode(self): |
|
206 | 208 | isp = self.isp |
|
207 | 209 | isp.input_mode = 'cell' |
@@ -216,6 +218,9 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
216 | 218 | self.assertFalse(isp.push_accepts_more()) |
|
217 | 219 | |
|
218 | 220 | def test_push_accepts_more2(self): |
|
221 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
222 | if self.isp.input_mode == 'cell': return | |
|
223 | ||
|
219 | 224 | isp = self.isp |
|
220 | 225 | isp.push('if 1:') |
|
221 | 226 | self.assertTrue(isp.push_accepts_more()) |
@@ -230,6 +235,9 b' class InputSplitterTestCase(unittest.TestCase):' | |||
|
230 | 235 | self.assertFalse(isp.push_accepts_more()) |
|
231 | 236 | |
|
232 | 237 | def test_push_accepts_more4(self): |
|
238 | # In cell mode, inputs must be fed in whole blocks, so skip this test | |
|
239 | if self.isp.input_mode == 'cell': return | |
|
240 | ||
|
233 | 241 | isp = self.isp |
|
234 | 242 | # When a multiline statement contains parens or multiline strings, we |
|
235 | 243 | # shouldn't get confused. |
@@ -563,6 +571,8 b' class IPythonInputTestCase(InputSplitterTestCase):' | |||
|
563 | 571 | |
|
564 | 572 | In addition, this runs the tests over the syntax and syntax_ml dicts that |
|
565 | 573 | were tested by individual functions, as part of the OO interface. |
|
574 | ||
|
575 | It also makes some checks on the raw buffer storage. | |
|
566 | 576 | """ |
|
567 | 577 | |
|
568 | 578 | def setUp(self): |
@@ -577,21 +587,26 b' class IPythonInputTestCase(InputSplitterTestCase):' | |||
|
577 | 587 | continue |
|
578 | 588 | |
|
579 | 589 | isp.push(raw) |
|
580 |
out = isp.source_reset |
|
|
581 | self.assertEqual(out, out_t) | |
|
590 | out, out_raw = isp.source_raw_reset() | |
|
591 | self.assertEqual(out.rstrip(), out_t) | |
|
592 | self.assertEqual(out_raw.rstrip(), raw.rstrip()) | |
|
582 | 593 | |
|
583 | 594 | def test_syntax_multiline(self): |
|
584 | 595 | isp = self.isp |
|
585 | 596 | for example in syntax_ml.itervalues(): |
|
586 | 597 | out_t_parts = [] |
|
598 | raw_parts = [] | |
|
587 | 599 | for line_pairs in example: |
|
588 | for raw, out_t_part in line_pairs: | |
|
589 | isp.push(raw) | |
|
600 | for lraw, out_t_part in line_pairs: | |
|
601 | isp.push(lraw) | |
|
590 | 602 | out_t_parts.append(out_t_part) |
|
603 | raw_parts.append(lraw) | |
|
591 | 604 | |
|
592 |
out = isp.source_reset |
|
|
605 | out, out_raw = isp.source_raw_reset() | |
|
593 | 606 | out_t = '\n'.join(out_t_parts).rstrip() |
|
594 | self.assertEqual(out, out_t) | |
|
607 | raw = '\n'.join(raw_parts).rstrip() | |
|
608 | self.assertEqual(out.rstrip(), out_t) | |
|
609 | self.assertEqual(out_raw.rstrip(), raw) | |
|
595 | 610 | |
|
596 | 611 | |
|
597 | 612 | class BlockIPythonInputTestCase(IPythonInputTestCase): |
@@ -616,9 +631,10 b' class BlockIPythonInputTestCase(IPythonInputTestCase):' | |||
|
616 | 631 | out_t = '\n'.join(out_t_parts) |
|
617 | 632 | |
|
618 | 633 | isp.push(raw) |
|
619 | out = isp.source_reset() | |
|
634 | out, out_raw = isp.source_raw_reset() | |
|
620 | 635 | # Match ignoring trailing whitespace |
|
621 | 636 | self.assertEqual(out.rstrip(), out_t.rstrip()) |
|
637 | self.assertEqual(out_raw.rstrip(), raw.rstrip()) | |
|
622 | 638 | |
|
623 | 639 | |
|
624 | 640 | #----------------------------------------------------------------------------- |
@@ -652,7 +668,8 b" if __name__ == '__main__':" | |||
|
652 | 668 | # Here we just return input so we can use it in a test suite, but a |
|
653 | 669 | # real interpreter would instead send it for execution somewhere. |
|
654 | 670 | #src = isp.source; raise EOFError # dbg |
|
655 | src = isp.source_reset() | |
|
671 | src, raw = isp.source_raw_reset() | |
|
656 | 672 | print 'Input source was:\n', src |
|
673 | print 'Raw source was:\n', raw | |
|
657 | 674 | except EOFError: |
|
658 | 675 | print 'Bye' |
@@ -137,29 +137,30 b' class ParalleMagic(Plugin):' | |||
|
137 | 137 | self._enable_autopx() |
|
138 | 138 | |
|
139 | 139 | def _enable_autopx(self): |
|
140 | """Enable %autopx mode by saving the original runsource and installing | |
|
141 | pxrunsource. | |
|
140 | """Enable %autopx mode by saving the original run_source and installing | |
|
141 | pxrun_source. | |
|
142 | 142 | """ |
|
143 | 143 | if self.active_multiengine_client is None: |
|
144 | 144 | print NO_ACTIVE_MULTIENGINE_CLIENT |
|
145 | 145 | return |
|
146 | 146 | |
|
147 | self._original_runsource = self.shell.runsource | |
|
148 | self.shell.runsource = new.instancemethod( | |
|
149 | self.pxrunsource, self.shell, self.shell.__class__ | |
|
147 | self._original_run_source = self.shell.run_source | |
|
148 | self.shell.run_source = new.instancemethod( | |
|
149 | self.pxrun_source, self.shell, self.shell.__class__ | |
|
150 | 150 | ) |
|
151 | 151 | self.autopx = True |
|
152 | 152 | print "%autopx enabled" |
|
153 | 153 | |
|
154 | 154 | def _disable_autopx(self): |
|
155 |
"""Disable %autopx by restoring the original InteractiveShell.runsource. |
|
|
155 | """Disable %autopx by restoring the original InteractiveShell.run_source. | |
|
156 | """ | |
|
156 | 157 | if self.autopx: |
|
157 | self.shell.runsource = self._original_runsource | |
|
158 | self.shell.run_source = self._original_run_source | |
|
158 | 159 | self.autopx = False |
|
159 | 160 | print "%autopx disabled" |
|
160 | 161 | |
|
161 | def pxrunsource(self, ipself, source, filename="<input>", symbol="single"): | |
|
162 | """A parallel replacement for InteractiveShell.runsource.""" | |
|
162 | def pxrun_source(self, ipself, source, filename="<input>", symbol="single"): | |
|
163 | """A parallel replacement for InteractiveShell.run_source.""" | |
|
163 | 164 | |
|
164 | 165 | try: |
|
165 | 166 | code = ipself.compile(source, filename, symbol) |
@@ -191,8 +191,7 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
191 | 191 | |
|
192 | 192 | # if you run stuff with -c <cmd>, raw hist is not updated |
|
193 | 193 | # ensure that it's in sync |
|
194 | if len(self.input_hist) != len (self.input_hist_raw): | |
|
195 | self.input_hist_raw = InputList(self.input_hist) | |
|
194 | self.history_manager.sync_inputs() | |
|
196 | 195 | |
|
197 | 196 | while 1: |
|
198 | 197 | try: |
@@ -218,7 +217,7 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
218 | 217 | if display_banner: |
|
219 | 218 | self.show_banner() |
|
220 | 219 | |
|
221 |
more = |
|
|
220 | more = False | |
|
222 | 221 | |
|
223 | 222 | # Mark activity in the builtins |
|
224 | 223 | __builtin__.__dict__['__IPYTHON__active'] += 1 |
@@ -227,7 +226,7 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
227 | 226 | self.readline_startup_hook(self.pre_readline) |
|
228 | 227 | # exit_now is set by a call to %Exit or %Quit, through the |
|
229 | 228 | # ask_exit callback. |
|
230 | ||
|
229 | ||
|
231 | 230 | while not self.exit_now: |
|
232 | 231 | self.hooks.pre_prompt_hook() |
|
233 | 232 | if more: |
@@ -244,7 +243,7 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
244 | 243 | except: |
|
245 | 244 | self.showtraceback() |
|
246 | 245 | try: |
|
247 |
line = self.raw_input(prompt |
|
|
246 | line = self.raw_input(prompt) | |
|
248 | 247 | if self.exit_now: |
|
249 | 248 | # quick exit on sys.std[in|out] close |
|
250 | 249 | break |
@@ -256,12 +255,7 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
256 | 255 | try: |
|
257 | 256 | self.write('\nKeyboardInterrupt\n') |
|
258 | 257 | self.resetbuffer() |
|
259 | # keep cache in sync with the prompt counter: | |
|
260 | self.displayhook.prompt_count -= 1 | |
|
261 | ||
|
262 | if self.autoindent: | |
|
263 | self.indent_current_nsp = 0 | |
|
264 | more = 0 | |
|
258 | more = False | |
|
265 | 259 | except KeyboardInterrupt: |
|
266 | 260 | pass |
|
267 | 261 | except EOFError: |
@@ -281,18 +275,22 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
281 | 275 | # asynchronously by signal handlers, for example. |
|
282 | 276 | self.showtraceback() |
|
283 | 277 | else: |
|
284 |
|
|
|
278 | self.input_splitter.push(line) | |
|
279 | more = self.input_splitter.push_accepts_more() | |
|
285 | 280 | if (self.SyntaxTB.last_syntax_error and |
|
286 | 281 | self.autoedit_syntax): |
|
287 | 282 | self.edit_syntax_error() |
|
288 | ||
|
283 | if not more: | |
|
284 | source_raw = self.input_splitter.source_raw_reset()[1] | |
|
285 | self.run_cell(source_raw) | |
|
286 | ||
|
289 | 287 | # We are off again... |
|
290 | 288 | __builtin__.__dict__['__IPYTHON__active'] -= 1 |
|
291 | 289 | |
|
292 | 290 | # Turn off the exit flag, so the mainloop can be restarted if desired |
|
293 | 291 | self.exit_now = False |
|
294 | 292 | |
|
295 | def raw_input(self,prompt='',continue_prompt=False): | |
|
293 | def raw_input(self, prompt='', continue_prompt=False): | |
|
296 | 294 | """Write a prompt and read a line. |
|
297 | 295 | |
|
298 | 296 | The returned line does not include the trailing newline. |
@@ -305,8 +303,6 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
305 | 303 | - continue_prompt(False): whether this line is the first one or a |
|
306 | 304 | continuation in a sequence of inputs. |
|
307 | 305 | """ |
|
308 | # growl.notify("raw_input: ", "prompt = %r\ncontinue_prompt = %s" % (prompt, continue_prompt)) | |
|
309 | ||
|
310 | 306 | # Code run by the user may have modified the readline completer state. |
|
311 | 307 | # We must ensure that our completer is back in place. |
|
312 | 308 | |
@@ -324,8 +320,6 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
324 | 320 | # Try to be reasonably smart about not re-indenting pasted input more |
|
325 | 321 | # than necessary. We do this by trimming out the auto-indent initial |
|
326 | 322 | # spaces, if the user's actual input started itself with whitespace. |
|
327 | #debugx('self.buffer[-1]') | |
|
328 | ||
|
329 | 323 | if self.autoindent: |
|
330 | 324 | if num_ini_spaces(line) > self.indent_current_nsp: |
|
331 | 325 | line = line[self.indent_current_nsp:] |
@@ -335,22 +329,15 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
335 | 329 | # it. |
|
336 | 330 | if line.strip(): |
|
337 | 331 | if continue_prompt: |
|
338 | self.input_hist_raw[-1] += '%s\n' % line | |
|
339 | 332 | if self.has_readline and self.readline_use: |
|
340 | try: | |
|
341 | histlen = self.readline.get_current_history_length() | |
|
342 | if histlen > 1: | |
|
343 | newhist = self.input_hist_raw[-1].rstrip() | |
|
344 |
|
|
|
345 | self.readline.replace_history_item(histlen-2, | |
|
346 | newhist.encode(self.stdin_encoding)) | |
|
347 | except AttributeError: | |
|
348 | pass # re{move,place}_history_item are new in 2.4. | |
|
333 | histlen = self.readline.get_current_history_length() | |
|
334 | if histlen > 1: | |
|
335 | newhist = self.input_hist_raw[-1].rstrip() | |
|
336 | self.readline.remove_history_item(histlen-1) | |
|
337 | self.readline.replace_history_item(histlen-2, | |
|
338 | newhist.encode(self.stdin_encoding)) | |
|
349 | 339 | else: |
|
350 | 340 | self.input_hist_raw.append('%s\n' % line) |
|
351 | # only entries starting at first column go to shadow history | |
|
352 | if line.lstrip() == line: | |
|
353 | self.shadowhist.add(line.strip()) | |
|
354 | 341 | elif not continue_prompt: |
|
355 | 342 | self.input_hist_raw.append('\n') |
|
356 | 343 | try: |
@@ -363,67 +350,43 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
363 | 350 | else: |
|
364 | 351 | return lineout |
|
365 | 352 | |
|
366 | # TODO: The following three methods are an early attempt to refactor | |
|
367 | # the main code execution logic. We don't use them, but they may be | |
|
368 | # helpful when we refactor the code execution logic further. | |
|
369 | # def interact_prompt(self): | |
|
370 | # """ Print the prompt (in read-eval-print loop) | |
|
371 | # | |
|
372 | # Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not | |
|
373 | # used in standard IPython flow. | |
|
374 | # """ | |
|
375 | # if self.more: | |
|
376 | # try: | |
|
377 | # prompt = self.hooks.generate_prompt(True) | |
|
378 | # except: | |
|
379 | # self.showtraceback() | |
|
380 | # if self.autoindent: | |
|
381 | # self.rl_do_indent = True | |
|
382 | # | |
|
383 | # else: | |
|
384 | # try: | |
|
385 | # prompt = self.hooks.generate_prompt(False) | |
|
386 |
|
|
|
387 | # self.showtraceback() | |
|
388 | # self.write(prompt) | |
|
389 | # | |
|
390 | # def interact_handle_input(self,line): | |
|
391 | # """ Handle the input line (in read-eval-print loop) | |
|
392 | # | |
|
393 | # Provided for those who want to implement their own read-eval-print loop (e.g. GUIs), not | |
|
394 | # used in standard IPython flow. | |
|
395 | # """ | |
|
396 | # if line.lstrip() == line: | |
|
397 | # self.shadowhist.add(line.strip()) | |
|
398 | # lineout = self.prefilter_manager.prefilter_lines(line,self.more) | |
|
399 | # | |
|
400 | # if line.strip(): | |
|
401 | # if self.more: | |
|
402 | # self.input_hist_raw[-1] += '%s\n' % line | |
|
403 | # else: | |
|
404 | # self.input_hist_raw.append('%s\n' % line) | |
|
405 | # | |
|
406 | # | |
|
407 | # self.more = self.push_line(lineout) | |
|
408 | # if (self.SyntaxTB.last_syntax_error and | |
|
409 | # self.autoedit_syntax): | |
|
410 | # self.edit_syntax_error() | |
|
411 | # | |
|
412 | # def interact_with_readline(self): | |
|
413 | # """ Demo of using interact_handle_input, interact_prompt | |
|
414 | # | |
|
415 | # This is the main read-eval-print loop. If you need to implement your own (e.g. for GUI), | |
|
416 | # it should work like this. | |
|
417 | # """ | |
|
418 | # self.readline_startup_hook(self.pre_readline) | |
|
419 | # while not self.exit_now: | |
|
420 | # self.interact_prompt() | |
|
421 | # if self.more: | |
|
422 | # self.rl_do_indent = True | |
|
423 | # else: | |
|
424 | # self.rl_do_indent = False | |
|
425 | # line = raw_input_original().decode(self.stdin_encoding) | |
|
426 | # self.interact_handle_input(line) | |
|
353 | ||
|
354 | def raw_input(self, prompt=''): | |
|
355 | """Write a prompt and read a line. | |
|
356 | ||
|
357 | The returned line does not include the trailing newline. | |
|
358 | When the user enters the EOF key sequence, EOFError is raised. | |
|
359 | ||
|
360 | Optional inputs: | |
|
361 | ||
|
362 | - prompt(''): a string to be printed to prompt the user. | |
|
363 | ||
|
364 | - continue_prompt(False): whether this line is the first one or a | |
|
365 | continuation in a sequence of inputs. | |
|
366 | """ | |
|
367 | # Code run by the user may have modified the readline completer state. | |
|
368 | # We must ensure that our completer is back in place. | |
|
369 | ||
|
370 | if self.has_readline: | |
|
371 | self.set_readline_completer() | |
|
372 | ||
|
373 | try: | |
|
374 | line = raw_input_original(prompt).decode(self.stdin_encoding) | |
|
375 | except ValueError: | |
|
376 | warn("\n********\nYou or a %run:ed script called sys.stdin.close()" | |
|
377 | " or sys.stdout.close()!\nExiting IPython!") | |
|
378 | self.ask_exit() | |
|
379 | return "" | |
|
380 | ||
|
381 | # Try to be reasonably smart about not re-indenting pasted input more | |
|
382 | # than necessary. We do this by trimming out the auto-indent initial | |
|
383 | # spaces, if the user's actual input started itself with whitespace. | |
|
384 | if self.autoindent: | |
|
385 | if num_ini_spaces(line) > self.indent_current_nsp: | |
|
386 | line = line[self.indent_current_nsp:] | |
|
387 | self.indent_current_nsp = 0 | |
|
388 | ||
|
389 | return line | |
|
427 | 390 | |
|
428 | 391 | #------------------------------------------------------------------------- |
|
429 | 392 | # Methods to support auto-editing of SyntaxErrors. |
@@ -571,7 +571,7 b' class IPythonApp(Application):' | |||
|
571 | 571 | try: |
|
572 | 572 | self.log.info("Running code in user namespace: %s" % |
|
573 | 573 | line) |
|
574 |
self.shell.run |
|
|
574 | self.shell.run_cell(line) | |
|
575 | 575 | except: |
|
576 | 576 | self.log.warn("Error in executing line in user " |
|
577 | 577 | "namespace: %s" % line) |
@@ -616,7 +616,7 b' class IPythonApp(Application):' | |||
|
616 | 616 | try: |
|
617 | 617 | self.log.info("Running code given at command line (-c): %s" % |
|
618 | 618 | line) |
|
619 |
self.shell.run |
|
|
619 | self.shell.run_cell(line) | |
|
620 | 620 | except: |
|
621 | 621 | self.log.warn("Error in executing line in user namespace: %s" % |
|
622 | 622 | line) |
@@ -248,7 +248,7 b' class Demo(object):' | |||
|
248 | 248 | self.ip_ns = ip.user_ns |
|
249 | 249 | self.ip_colorize = ip.pycolorize |
|
250 | 250 | self.ip_showtb = ip.showtraceback |
|
251 |
self.ip_run |
|
|
251 | self.ip_run_cell = ip.run_cell | |
|
252 | 252 | self.shell = ip |
|
253 | 253 | |
|
254 | 254 | # load user data and initialize data structures |
@@ -411,7 +411,7 b' class Demo(object):' | |||
|
411 | 411 | print >>IPython.utils.io.Term.cout, block, |
|
412 | 412 | sys.stdout.flush() |
|
413 | 413 | |
|
414 |
def run |
|
|
414 | def run_cell(self,source): | |
|
415 | 415 | """Execute a string with one or more lines of code""" |
|
416 | 416 | |
|
417 | 417 | exec source in self.user_ns |
@@ -449,7 +449,7 b' class Demo(object):' | |||
|
449 | 449 | try: |
|
450 | 450 | save_argv = sys.argv |
|
451 | 451 | sys.argv = self.sys_argv |
|
452 |
self.run |
|
|
452 | self.run_cell(next_block) | |
|
453 | 453 | self.post_cmd() |
|
454 | 454 | finally: |
|
455 | 455 | sys.argv = save_argv |
@@ -496,10 +496,10 b' class IPythonDemo(Demo):' | |||
|
496 | 496 | class requires the input to be valid, pure Python code. |
|
497 | 497 | """ |
|
498 | 498 | |
|
499 |
def run |
|
|
499 | def run_cell(self,source): | |
|
500 | 500 | """Execute a string with one or more lines of code""" |
|
501 | 501 | |
|
502 |
self.shell.run |
|
|
502 | self.shell.run_cell(source) | |
|
503 | 503 | |
|
504 | 504 | class LineDemo(Demo): |
|
505 | 505 | """Demo where each line is executed as a separate block. |
@@ -209,19 +209,13 b' class Kernel(Configurable):' | |||
|
209 | 209 | reply_content = {} |
|
210 | 210 | try: |
|
211 | 211 | if silent: |
|
212 | # runcode uses 'exec' mode, so no displayhook will fire, and it | |
|
212 | # run_code uses 'exec' mode, so no displayhook will fire, and it | |
|
213 | 213 | # doesn't call logging or history manipulations. Print |
|
214 | 214 | # statements in that code will obviously still execute. |
|
215 | shell.runcode(code) | |
|
215 | shell.run_code(code) | |
|
216 | 216 | else: |
|
217 |
# FIXME: |
|
|
217 | # FIXME: the shell calls the exception handler itself. | |
|
218 | 218 | shell._reply_content = None |
|
219 | ||
|
220 | # For now leave this here until we're sure we can stop using it | |
|
221 | #shell.runlines(code) | |
|
222 | ||
|
223 | # Experimental: cell mode! Test more before turning into | |
|
224 | # default and removing the hacks around runlines. | |
|
225 | 219 | shell.run_cell(code) |
|
226 | 220 | except: |
|
227 | 221 | status = u'error' |
@@ -238,8 +232,9 b' class Kernel(Configurable):' | |||
|
238 | 232 | status = u'ok' |
|
239 | 233 | |
|
240 | 234 | reply_content[u'status'] = status |
|
241 | # Compute the execution counter so clients can display prompts | |
|
242 | reply_content['execution_count'] = shell.displayhook.prompt_count | |
|
235 | ||
|
236 | # Return the execution counter so clients can display prompts | |
|
237 | reply_content['execution_count'] = shell.execution_count -1 | |
|
243 | 238 | |
|
244 | 239 | # FIXME - fish exception info out of shell, possibly left there by |
|
245 | 240 | # runlines. We'll need to clean up this logic later. |
General Comments 0
You need to be logged in to leave comments.
Login now