Show More
@@ -66,6 +66,7 b' from __future__ import print_function' | |||||
66 | # Imports |
|
66 | # Imports | |
67 | #----------------------------------------------------------------------------- |
|
67 | #----------------------------------------------------------------------------- | |
68 | # stdlib |
|
68 | # stdlib | |
|
69 | import ast | |||
69 | import codeop |
|
70 | import codeop | |
70 | import re |
|
71 | import re | |
71 | import sys |
|
72 | import sys | |
@@ -185,9 +186,6 b' def split_blocks(python):' | |||||
185 | commands : list of str |
|
186 | commands : list of str | |
186 | Separate commands that can be exec'ed independently. |
|
187 | Separate commands that can be exec'ed independently. | |
187 | """ |
|
188 | """ | |
188 |
|
||||
189 | import compiler |
|
|||
190 |
|
||||
191 | # compiler.parse treats trailing spaces after a newline as a |
|
189 | # compiler.parse treats trailing spaces after a newline as a | |
192 | # SyntaxError. This is different than codeop.CommandCompiler, which |
|
190 | # SyntaxError. This is different than codeop.CommandCompiler, which | |
193 | # will compile the trailng spaces just fine. We simply strip any |
|
191 | # will compile the trailng spaces just fine. We simply strip any | |
@@ -197,22 +195,15 b' def split_blocks(python):' | |||||
197 | python_ori = python # save original in case we bail on error |
|
195 | python_ori = python # save original in case we bail on error | |
198 | python = python.strip() |
|
196 | python = python.strip() | |
199 |
|
197 | |||
200 | # The compiler module does not like unicode. We need to convert |
|
|||
201 | # it encode it: |
|
|||
202 | if isinstance(python, unicode): |
|
|||
203 | # Use the utf-8-sig BOM so the compiler detects this a UTF-8 |
|
|||
204 | # encode string. |
|
|||
205 | python = '\xef\xbb\xbf' + python.encode('utf-8') |
|
|||
206 |
|
||||
207 | # The compiler module will parse the code into an abstract syntax tree. |
|
198 | # The compiler module will parse the code into an abstract syntax tree. | |
208 | # This has a bug with str("a\nb"), but not str("""a\nb""")!!! |
|
199 | # This has a bug with str("a\nb"), but not str("""a\nb""")!!! | |
209 | try: |
|
200 | try: | |
210 |
ast = |
|
201 | code_ast = ast.parse(python) | |
211 | except: |
|
202 | except: | |
212 | return [python_ori] |
|
203 | return [python_ori] | |
213 |
|
204 | |||
214 | # Uncomment to help debug the ast tree |
|
205 | # Uncomment to help debug the ast tree | |
215 |
# for n in |
|
206 | # for n in code_ast.body: | |
216 | # print n.lineno,'->',n |
|
207 | # print n.lineno,'->',n | |
217 |
|
208 | |||
218 | # Each separate command is available by iterating over ast.node. The |
|
209 | # Each separate command is available by iterating over ast.node. The | |
@@ -223,14 +214,7 b' def split_blocks(python):' | |||||
223 | # other situations that cause Discard nodes that shouldn't be discarded. |
|
214 | # other situations that cause Discard nodes that shouldn't be discarded. | |
224 | # We might eventually discover other cases where lineno is None and have |
|
215 | # We might eventually discover other cases where lineno is None and have | |
225 | # to put in a more sophisticated test. |
|
216 | # to put in a more sophisticated test. | |
226 |
linenos = [x.lineno-1 for x in ast. |
|
217 | linenos = [x.lineno-1 for x in code_ast.body if x.lineno is not None] | |
227 |
|
||||
228 | # When we have a bare string as the first statement, it does not end up as |
|
|||
229 | # a Discard Node in the AST as we might expect. Instead, it gets interpreted |
|
|||
230 | # as the docstring of the module. Check for this case and prepend 0 (the |
|
|||
231 | # first line number) to the list of linenos to account for it. |
|
|||
232 | if ast.doc is not None: |
|
|||
233 | linenos.insert(0, 0) |
|
|||
234 |
|
218 | |||
235 | # When we finally get the slices, we will need to slice all the way to |
|
219 | # When we finally get the slices, we will need to slice all the way to | |
236 | # the end even though we don't have a line number for it. Fortunately, |
|
220 | # the end even though we don't have a line number for it. Fortunately, | |
@@ -616,7 +600,7 b' class InputSplitter(object):' | |||||
616 | setattr(self, store, self._set_source(buffer)) |
|
600 | setattr(self, store, self._set_source(buffer)) | |
617 |
|
601 | |||
618 | def _set_source(self, buffer): |
|
602 | def _set_source(self, buffer): | |
619 |
return ''.join(buffer) |
|
603 | return ''.join(buffer) | |
620 |
|
604 | |||
621 |
|
605 | |||
622 | #----------------------------------------------------------------------------- |
|
606 | #----------------------------------------------------------------------------- |
@@ -1550,12 +1550,14 b' class InteractiveShell(Configurable, Magic):' | |||||
1550 | # otherwise we end up with a monster history after a while: |
|
1550 | # otherwise we end up with a monster history after a while: | |
1551 | readline.set_history_length(self.history_length) |
|
1551 | readline.set_history_length(self.history_length) | |
1552 |
|
1552 | |||
|
1553 | stdin_encoding = sys.stdin.encoding or "utf-8" | |||
|
1554 | ||||
1553 | # Load the last 1000 lines from history |
|
1555 | # Load the last 1000 lines from history | |
1554 | for _, _, cell in self.history_manager.get_tail(1000, |
|
1556 | for _, _, cell in self.history_manager.get_tail(1000, | |
1555 | include_latest=True): |
|
1557 | include_latest=True): | |
1556 | if cell.strip(): # Ignore blank lines |
|
1558 | if cell.strip(): # Ignore blank lines | |
1557 | for line in cell.splitlines(): |
|
1559 | for line in cell.splitlines(): | |
1558 | readline.add_history(line) |
|
1560 | readline.add_history(line.encode(stdin_encoding)) | |
1559 |
|
1561 | |||
1560 | # Configure auto-indent for all platforms |
|
1562 | # Configure auto-indent for all platforms | |
1561 | self.set_autoindent(self.autoindent) |
|
1563 | self.set_autoindent(self.autoindent) | |
@@ -2105,7 +2107,6 b' class InteractiveShell(Configurable, Magic):' | |||||
2105 | if len(cell.splitlines()) <= 1: |
|
2107 | if len(cell.splitlines()) <= 1: | |
2106 | cell = self.prefilter_manager.prefilter_line(blocks[0]) |
|
2108 | cell = self.prefilter_manager.prefilter_line(blocks[0]) | |
2107 | blocks = self.input_splitter.split_blocks(cell) |
|
2109 | blocks = self.input_splitter.split_blocks(cell) | |
2108 |
|
||||
2109 |
|
2110 | |||
2110 | # Store the 'ipython' version of the cell as well, since that's what |
|
2111 | # Store the 'ipython' version of the cell as well, since that's what | |
2111 | # needs to go into the translated history and get executed (the |
|
2112 | # needs to go into the translated history and get executed (the | |
@@ -2246,7 +2247,7 b' class InteractiveShell(Configurable, Magic):' | |||||
2246 | else: |
|
2247 | else: | |
2247 | usource = source |
|
2248 | usource = source | |
2248 |
|
2249 | |||
2249 |
if |
|
2250 | if False: # dbg | |
2250 | print 'Source:', repr(source) # dbg |
|
2251 | print 'Source:', repr(source) # dbg | |
2251 | print 'USource:', repr(usource) # dbg |
|
2252 | print 'USource:', repr(usource) # dbg | |
2252 | print 'type:', type(source) # dbg |
|
2253 | print 'type:', type(source) # dbg |
@@ -2063,7 +2063,8 b' Currently the magic system has the following functions:\\n"""' | |||||
2063 | return |
|
2063 | return | |
2064 | cmds = self.extract_input_lines(ranges, 'r' in opts) |
|
2064 | cmds = self.extract_input_lines(ranges, 'r' in opts) | |
2065 | with open(fname,'w') as f: |
|
2065 | with open(fname,'w') as f: | |
2066 |
f.write( |
|
2066 | f.write("# coding: utf-8\n") | |
|
2067 | f.write(cmds.encode("utf-8")) | |||
2067 | print 'The following commands were written to file `%s`:' % fname |
|
2068 | print 'The following commands were written to file `%s`:' % fname | |
2068 | print cmds |
|
2069 | print cmds | |
2069 |
|
2070 |
@@ -83,7 +83,8 b' def test_history():' | |||||
83 | testfilename = os.path.realpath(os.path.join(tmpdir, "test.py")) |
|
83 | testfilename = os.path.realpath(os.path.join(tmpdir, "test.py")) | |
84 | ip.magic_save(testfilename + " ~1/1-3") |
|
84 | ip.magic_save(testfilename + " ~1/1-3") | |
85 | testfile = open(testfilename, "r") |
|
85 | testfile = open(testfilename, "r") | |
86 |
nt.assert_equal(testfile.read(), |
|
86 | nt.assert_equal(testfile.read().decode("utf-8"), | |
|
87 | "# coding: utf-8\n" + "\n".join(hist)) | |||
87 |
|
88 | |||
88 | # Duplicate line numbers - check that it doesn't crash, and |
|
89 | # Duplicate line numbers - check that it doesn't crash, and | |
89 | # gets a new session |
|
90 | # gets a new session |
General Comments 0
You need to be logged in to leave comments.
Login now