Show More
@@ -1,495 +1,487 | |||||
1 | import tokenize |
|
1 | import tokenize | |
2 | import nose.tools as nt |
|
2 | import nose.tools as nt | |
3 |
|
3 | |||
4 | from IPython.testing import tools as tt |
|
4 | from IPython.testing import tools as tt | |
5 | from IPython.utils import py3compat |
|
5 | from IPython.utils import py3compat | |
6 | u_fmt = py3compat.u_format |
|
|||
7 |
|
6 | |||
8 | from IPython.core import inputtransformer as ipt |
|
7 | from IPython.core import inputtransformer as ipt | |
9 |
|
8 | |||
10 | def transform_and_reset(transformer): |
|
9 | def transform_and_reset(transformer): | |
11 | transformer = transformer() |
|
10 | transformer = transformer() | |
12 | def transform(inp): |
|
11 | def transform(inp): | |
13 | try: |
|
12 | try: | |
14 | return transformer.push(inp) |
|
13 | return transformer.push(inp) | |
15 | finally: |
|
14 | finally: | |
16 | transformer.reset() |
|
15 | transformer.reset() | |
17 |
|
16 | |||
18 | return transform |
|
17 | return transform | |
19 |
|
18 | |||
20 | # Transformer tests |
|
19 | # Transformer tests | |
21 | def transform_checker(tests, transformer, **kwargs): |
|
20 | def transform_checker(tests, transformer, **kwargs): | |
22 | """Utility to loop over test inputs""" |
|
21 | """Utility to loop over test inputs""" | |
23 | transformer = transformer(**kwargs) |
|
22 | transformer = transformer(**kwargs) | |
24 | try: |
|
23 | try: | |
25 | for inp, tr in tests: |
|
24 | for inp, tr in tests: | |
26 | if inp is None: |
|
25 | if inp is None: | |
27 | out = transformer.reset() |
|
26 | out = transformer.reset() | |
28 | else: |
|
27 | else: | |
29 | out = transformer.push(inp) |
|
28 | out = transformer.push(inp) | |
30 | nt.assert_equal(out, tr) |
|
29 | nt.assert_equal(out, tr) | |
31 | finally: |
|
30 | finally: | |
32 | transformer.reset() |
|
31 | transformer.reset() | |
33 |
|
32 | |||
34 | # Data for all the syntax tests in the form of lists of pairs of |
|
33 | # Data for all the syntax tests in the form of lists of pairs of | |
35 | # raw/transformed input. We store it here as a global dict so that we can use |
|
34 | # raw/transformed input. We store it here as a global dict so that we can use | |
36 | # it both within single-function tests and also to validate the behavior of the |
|
35 | # it both within single-function tests and also to validate the behavior of the | |
37 | # larger objects |
|
36 | # larger objects | |
38 |
|
37 | |||
39 | syntax = \ |
|
38 | syntax = \ | |
40 | dict(assign_system = |
|
39 | dict(assign_system = | |
41 | [(i,py3compat.u_format(o)) for i,o in \ |
|
|||
42 | [(u'a =! ls', "a = get_ipython().getoutput('ls')"), |
|
40 | [(u'a =! ls', "a = get_ipython().getoutput('ls')"), | |
43 | (u'b = !ls', "b = get_ipython().getoutput('ls')"), |
|
41 | (u'b = !ls', "b = get_ipython().getoutput('ls')"), | |
44 | (u'c= !ls', "c = get_ipython().getoutput('ls')"), |
|
42 | (u'c= !ls', "c = get_ipython().getoutput('ls')"), | |
45 | (u'd == !ls', u'd == !ls'), # Invalid syntax, but we leave == alone. |
|
43 | (u'd == !ls', u'd == !ls'), # Invalid syntax, but we leave == alone. | |
46 | ('x=1', 'x=1'), # normal input is unmodified |
|
44 | ('x=1', 'x=1'), # normal input is unmodified | |
47 | (' ',' '), # blank lines are kept intact |
|
45 | (' ',' '), # blank lines are kept intact | |
48 | # Tuple unpacking |
|
46 | # Tuple unpacking | |
49 | (u"a, b = !echo 'a\\nb'", u"a, b = get_ipython().getoutput(\"echo 'a\\\\nb'\")"), |
|
47 | (u"a, b = !echo 'a\\nb'", u"a, b = get_ipython().getoutput(\"echo 'a\\\\nb'\")"), | |
50 | (u"a,= !echo 'a'", u"a, = get_ipython().getoutput(\"echo 'a'\")"), |
|
48 | (u"a,= !echo 'a'", u"a, = get_ipython().getoutput(\"echo 'a'\")"), | |
51 | (u"a, *bc = !echo 'a\\nb\\nc'", u"a, *bc = get_ipython().getoutput(\"echo 'a\\\\nb\\\\nc'\")"), |
|
49 | (u"a, *bc = !echo 'a\\nb\\nc'", u"a, *bc = get_ipython().getoutput(\"echo 'a\\\\nb\\\\nc'\")"), | |
52 | # Tuple unpacking with regular Python expressions, not our syntax. |
|
50 | # Tuple unpacking with regular Python expressions, not our syntax. | |
53 | (u"a, b = range(2)", u"a, b = range(2)"), |
|
51 | (u"a, b = range(2)", u"a, b = range(2)"), | |
54 | (u"a, = range(1)", u"a, = range(1)"), |
|
52 | (u"a, = range(1)", u"a, = range(1)"), | |
55 | (u"a, *bc = range(3)", u"a, *bc = range(3)"), |
|
53 | (u"a, *bc = range(3)", u"a, *bc = range(3)"), | |
56 |
] |
|
54 | ], | |
57 |
|
55 | |||
58 | assign_magic = |
|
56 | assign_magic = | |
59 | [(i,py3compat.u_format(o)) for i,o in \ |
|
|||
60 | [(u'a =% who', "a = get_ipython().run_line_magic('who', '')"), |
|
57 | [(u'a =% who', "a = get_ipython().run_line_magic('who', '')"), | |
61 | (u'b = %who', "b = get_ipython().run_line_magic('who', '')"), |
|
58 | (u'b = %who', "b = get_ipython().run_line_magic('who', '')"), | |
62 | (u'c= %ls', "c = get_ipython().run_line_magic('ls', '')"), |
|
59 | (u'c= %ls', "c = get_ipython().run_line_magic('ls', '')"), | |
63 | (u'd == %ls', u'd == %ls'), # Invalid syntax, but we leave == alone. |
|
60 | (u'd == %ls', u'd == %ls'), # Invalid syntax, but we leave == alone. | |
64 | ('x=1', 'x=1'), # normal input is unmodified |
|
61 | ('x=1', 'x=1'), # normal input is unmodified | |
65 | (' ',' '), # blank lines are kept intact |
|
62 | (' ',' '), # blank lines are kept intact | |
66 | (u"a, b = %foo", u"a, b = get_ipython().run_line_magic('foo', '')"), |
|
63 | (u"a, b = %foo", u"a, b = get_ipython().run_line_magic('foo', '')"), | |
67 |
] |
|
64 | ], | |
68 |
|
65 | |||
69 | classic_prompt = |
|
66 | classic_prompt = | |
70 | [('>>> x=1', 'x=1'), |
|
67 | [('>>> x=1', 'x=1'), | |
71 | ('x=1', 'x=1'), # normal input is unmodified |
|
68 | ('x=1', 'x=1'), # normal input is unmodified | |
72 | (' ', ' '), # blank lines are kept intact |
|
69 | (' ', ' '), # blank lines are kept intact | |
73 | ], |
|
70 | ], | |
74 |
|
71 | |||
75 | ipy_prompt = |
|
72 | ipy_prompt = | |
76 | [('In [1]: x=1', 'x=1'), |
|
73 | [('In [1]: x=1', 'x=1'), | |
77 | ('x=1', 'x=1'), # normal input is unmodified |
|
74 | ('x=1', 'x=1'), # normal input is unmodified | |
78 | (' ',' '), # blank lines are kept intact |
|
75 | (' ',' '), # blank lines are kept intact | |
79 | ], |
|
76 | ], | |
80 |
|
77 | |||
81 | # Tests for the escape transformer to leave normal code alone |
|
78 | # Tests for the escape transformer to leave normal code alone | |
82 | escaped_noesc = |
|
79 | escaped_noesc = | |
83 | [ (' ', ' '), |
|
80 | [ (' ', ' '), | |
84 | ('x=1', 'x=1'), |
|
81 | ('x=1', 'x=1'), | |
85 | ], |
|
82 | ], | |
86 |
|
83 | |||
87 | # System calls |
|
84 | # System calls | |
88 | escaped_shell = |
|
85 | escaped_shell = | |
89 | [(i,py3compat.u_format(o)) for i,o in \ |
|
|||
90 | [ (u'!ls', "get_ipython().system('ls')"), |
|
86 | [ (u'!ls', "get_ipython().system('ls')"), | |
91 | # Double-escape shell, this means to capture the output of the |
|
87 | # Double-escape shell, this means to capture the output of the | |
92 | # subprocess and return it |
|
88 | # subprocess and return it | |
93 | (u'!!ls', "get_ipython().getoutput('ls')"), |
|
89 | (u'!!ls', "get_ipython().getoutput('ls')"), | |
94 |
] |
|
90 | ], | |
95 |
|
91 | |||
96 | # Help/object info |
|
92 | # Help/object info | |
97 | escaped_help = |
|
93 | escaped_help = | |
98 | [(i,py3compat.u_format(o)) for i,o in \ |
|
|||
99 | [ (u'?', 'get_ipython().show_usage()'), |
|
94 | [ (u'?', 'get_ipython().show_usage()'), | |
100 | (u'?x1', "get_ipython().run_line_magic('pinfo', 'x1')"), |
|
95 | (u'?x1', "get_ipython().run_line_magic('pinfo', 'x1')"), | |
101 | (u'??x2', "get_ipython().run_line_magic('pinfo2', 'x2')"), |
|
96 | (u'??x2', "get_ipython().run_line_magic('pinfo2', 'x2')"), | |
102 | (u'?a.*s', "get_ipython().run_line_magic('psearch', 'a.*s')"), |
|
97 | (u'?a.*s', "get_ipython().run_line_magic('psearch', 'a.*s')"), | |
103 | (u'?%hist1', "get_ipython().run_line_magic('pinfo', '%hist1')"), |
|
98 | (u'?%hist1', "get_ipython().run_line_magic('pinfo', '%hist1')"), | |
104 | (u'?%%hist2', "get_ipython().run_line_magic('pinfo', '%%hist2')"), |
|
99 | (u'?%%hist2', "get_ipython().run_line_magic('pinfo', '%%hist2')"), | |
105 | (u'?abc = qwe', "get_ipython().run_line_magic('pinfo', 'abc')"), |
|
100 | (u'?abc = qwe', "get_ipython().run_line_magic('pinfo', 'abc')"), | |
106 |
] |
|
101 | ], | |
107 |
|
102 | |||
108 | end_help = |
|
103 | end_help = | |
109 | [(i,py3compat.u_format(o)) for i,o in \ |
|
|||
110 | [ (u'x3?', "get_ipython().run_line_magic('pinfo', 'x3')"), |
|
104 | [ (u'x3?', "get_ipython().run_line_magic('pinfo', 'x3')"), | |
111 | (u'x4??', "get_ipython().run_line_magic('pinfo2', 'x4')"), |
|
105 | (u'x4??', "get_ipython().run_line_magic('pinfo2', 'x4')"), | |
112 | (u'%hist1?', "get_ipython().run_line_magic('pinfo', '%hist1')"), |
|
106 | (u'%hist1?', "get_ipython().run_line_magic('pinfo', '%hist1')"), | |
113 | (u'%hist2??', "get_ipython().run_line_magic('pinfo2', '%hist2')"), |
|
107 | (u'%hist2??', "get_ipython().run_line_magic('pinfo2', '%hist2')"), | |
114 | (u'%%hist3?', "get_ipython().run_line_magic('pinfo', '%%hist3')"), |
|
108 | (u'%%hist3?', "get_ipython().run_line_magic('pinfo', '%%hist3')"), | |
115 | (u'%%hist4??', "get_ipython().run_line_magic('pinfo2', '%%hist4')"), |
|
109 | (u'%%hist4??', "get_ipython().run_line_magic('pinfo2', '%%hist4')"), | |
116 | (u'Ο.foo?', "get_ipython().run_line_magic('pinfo', 'Ο.foo')"), |
|
110 | (u'Ο.foo?', "get_ipython().run_line_magic('pinfo', 'Ο.foo')"), | |
117 | (u'f*?', "get_ipython().run_line_magic('psearch', 'f*')"), |
|
111 | (u'f*?', "get_ipython().run_line_magic('psearch', 'f*')"), | |
118 | (u'ax.*aspe*?', "get_ipython().run_line_magic('psearch', 'ax.*aspe*')"), |
|
112 | (u'ax.*aspe*?', "get_ipython().run_line_magic('psearch', 'ax.*aspe*')"), | |
119 | (u'a = abc?', "get_ipython().set_next_input('a = abc');" |
|
113 | (u'a = abc?', "get_ipython().set_next_input('a = abc');" | |
120 | "get_ipython().run_line_magic('pinfo', 'abc')"), |
|
114 | "get_ipython().run_line_magic('pinfo', 'abc')"), | |
121 | (u'a = abc.qe??', "get_ipython().set_next_input('a = abc.qe');" |
|
115 | (u'a = abc.qe??', "get_ipython().set_next_input('a = abc.qe');" | |
122 | "get_ipython().run_line_magic('pinfo2', 'abc.qe')"), |
|
116 | "get_ipython().run_line_magic('pinfo2', 'abc.qe')"), | |
123 | (u'a = *.items?', "get_ipython().set_next_input('a = *.items');" |
|
117 | (u'a = *.items?', "get_ipython().set_next_input('a = *.items');" | |
124 | "get_ipython().run_line_magic('psearch', '*.items')"), |
|
118 | "get_ipython().run_line_magic('psearch', '*.items')"), | |
125 | (u'plot(a?', "get_ipython().set_next_input('plot(a');" |
|
119 | (u'plot(a?', "get_ipython().set_next_input('plot(a');" | |
126 | "get_ipython().run_line_magic('pinfo', 'a')"), |
|
120 | "get_ipython().run_line_magic('pinfo', 'a')"), | |
127 | (u'a*2 #comment?', 'a*2 #comment?'), |
|
121 | (u'a*2 #comment?', 'a*2 #comment?'), | |
128 |
] |
|
122 | ], | |
129 |
|
123 | |||
130 | # Explicit magic calls |
|
124 | # Explicit magic calls | |
131 | escaped_magic = |
|
125 | escaped_magic = | |
132 | [(i,py3compat.u_format(o)) for i,o in \ |
|
|||
133 | [ (u'%cd', "get_ipython().run_line_magic('cd', '')"), |
|
126 | [ (u'%cd', "get_ipython().run_line_magic('cd', '')"), | |
134 | (u'%cd /home', "get_ipython().run_line_magic('cd', '/home')"), |
|
127 | (u'%cd /home', "get_ipython().run_line_magic('cd', '/home')"), | |
135 | # Backslashes need to be escaped. |
|
128 | # Backslashes need to be escaped. | |
136 | (u'%cd C:\\User', "get_ipython().run_line_magic('cd', 'C:\\\\User')"), |
|
129 | (u'%cd C:\\User', "get_ipython().run_line_magic('cd', 'C:\\\\User')"), | |
137 | (u' %magic', " get_ipython().run_line_magic('magic', '')"), |
|
130 | (u' %magic', " get_ipython().run_line_magic('magic', '')"), | |
138 |
] |
|
131 | ], | |
139 |
|
132 | |||
140 | # Quoting with separate arguments |
|
133 | # Quoting with separate arguments | |
141 | escaped_quote = |
|
134 | escaped_quote = | |
142 | [ (',f', 'f("")'), |
|
135 | [ (',f', 'f("")'), | |
143 | (',f x', 'f("x")'), |
|
136 | (',f x', 'f("x")'), | |
144 | (' ,f y', ' f("y")'), |
|
137 | (' ,f y', ' f("y")'), | |
145 | (',f a b', 'f("a", "b")'), |
|
138 | (',f a b', 'f("a", "b")'), | |
146 | ], |
|
139 | ], | |
147 |
|
140 | |||
148 | # Quoting with single argument |
|
141 | # Quoting with single argument | |
149 | escaped_quote2 = |
|
142 | escaped_quote2 = | |
150 | [ (';f', 'f("")'), |
|
143 | [ (';f', 'f("")'), | |
151 | (';f x', 'f("x")'), |
|
144 | (';f x', 'f("x")'), | |
152 | (' ;f y', ' f("y")'), |
|
145 | (' ;f y', ' f("y")'), | |
153 | (';f a b', 'f("a b")'), |
|
146 | (';f a b', 'f("a b")'), | |
154 | ], |
|
147 | ], | |
155 |
|
148 | |||
156 | # Simply apply parens |
|
149 | # Simply apply parens | |
157 | escaped_paren = |
|
150 | escaped_paren = | |
158 | [ ('/f', 'f()'), |
|
151 | [ ('/f', 'f()'), | |
159 | ('/f x', 'f(x)'), |
|
152 | ('/f x', 'f(x)'), | |
160 | (' /f y', ' f(y)'), |
|
153 | (' /f y', ' f(y)'), | |
161 | ('/f a b', 'f(a, b)'), |
|
154 | ('/f a b', 'f(a, b)'), | |
162 | ], |
|
155 | ], | |
163 |
|
156 | |||
164 | # Check that we transform prompts before other transforms |
|
157 | # Check that we transform prompts before other transforms | |
165 | mixed = |
|
158 | mixed = | |
166 | [(i,py3compat.u_format(o)) for i,o in \ |
|
|||
167 | [ (u'In [1]: %lsmagic', "get_ipython().run_line_magic('lsmagic', '')"), |
|
159 | [ (u'In [1]: %lsmagic', "get_ipython().run_line_magic('lsmagic', '')"), | |
168 | (u'>>> %lsmagic', "get_ipython().run_line_magic('lsmagic', '')"), |
|
160 | (u'>>> %lsmagic', "get_ipython().run_line_magic('lsmagic', '')"), | |
169 | (u'In [2]: !ls', "get_ipython().system('ls')"), |
|
161 | (u'In [2]: !ls', "get_ipython().system('ls')"), | |
170 | (u'In [3]: abs?', "get_ipython().run_line_magic('pinfo', 'abs')"), |
|
162 | (u'In [3]: abs?', "get_ipython().run_line_magic('pinfo', 'abs')"), | |
171 | (u'In [4]: b = %who', "b = get_ipython().run_line_magic('who', '')"), |
|
163 | (u'In [4]: b = %who', "b = get_ipython().run_line_magic('who', '')"), | |
172 |
] |
|
164 | ], | |
173 | ) |
|
165 | ) | |
174 |
|
166 | |||
175 | # multiline syntax examples. Each of these should be a list of lists, with |
|
167 | # multiline syntax examples. Each of these should be a list of lists, with | |
176 | # each entry itself having pairs of raw/transformed input. The union (with |
|
168 | # each entry itself having pairs of raw/transformed input. The union (with | |
177 | # '\n'.join() of the transformed inputs is what the splitter should produce |
|
169 | # '\n'.join() of the transformed inputs is what the splitter should produce | |
178 | # when fed the raw lines one at a time via push. |
|
170 | # when fed the raw lines one at a time via push. | |
179 | syntax_ml = \ |
|
171 | syntax_ml = \ | |
180 | dict(classic_prompt = |
|
172 | dict(classic_prompt = | |
181 | [ [('>>> for i in range(10):','for i in range(10):'), |
|
173 | [ [('>>> for i in range(10):','for i in range(10):'), | |
182 | ('... print i',' print i'), |
|
174 | ('... print i',' print i'), | |
183 | ('... ', ''), |
|
175 | ('... ', ''), | |
184 | ], |
|
176 | ], | |
185 | [('>>> a="""','a="""'), |
|
177 | [('>>> a="""','a="""'), | |
186 | ('... 123"""','123"""'), |
|
178 | ('... 123"""','123"""'), | |
187 | ], |
|
179 | ], | |
188 | [('a="""','a="""'), |
|
180 | [('a="""','a="""'), | |
189 | ('... 123','123'), |
|
181 | ('... 123','123'), | |
190 | ('... 456"""','456"""'), |
|
182 | ('... 456"""','456"""'), | |
191 | ], |
|
183 | ], | |
192 | [('a="""','a="""'), |
|
184 | [('a="""','a="""'), | |
193 | ('>>> 123','123'), |
|
185 | ('>>> 123','123'), | |
194 | ('... 456"""','456"""'), |
|
186 | ('... 456"""','456"""'), | |
195 | ], |
|
187 | ], | |
196 | [('a="""','a="""'), |
|
188 | [('a="""','a="""'), | |
197 | ('123','123'), |
|
189 | ('123','123'), | |
198 | ('... 456"""','... 456"""'), |
|
190 | ('... 456"""','... 456"""'), | |
199 | ], |
|
191 | ], | |
200 | [('....__class__','....__class__'), |
|
192 | [('....__class__','....__class__'), | |
201 | ], |
|
193 | ], | |
202 | [('a=5', 'a=5'), |
|
194 | [('a=5', 'a=5'), | |
203 | ('...', ''), |
|
195 | ('...', ''), | |
204 | ], |
|
196 | ], | |
205 | [('>>> def f(x):', 'def f(x):'), |
|
197 | [('>>> def f(x):', 'def f(x):'), | |
206 | ('...', ''), |
|
198 | ('...', ''), | |
207 | ('... return x', ' return x'), |
|
199 | ('... return x', ' return x'), | |
208 | ], |
|
200 | ], | |
209 | [('board = """....', 'board = """....'), |
|
201 | [('board = """....', 'board = """....'), | |
210 | ('....', '....'), |
|
202 | ('....', '....'), | |
211 | ('...."""', '...."""'), |
|
203 | ('...."""', '...."""'), | |
212 | ], |
|
204 | ], | |
213 | ], |
|
205 | ], | |
214 |
|
206 | |||
215 | ipy_prompt = |
|
207 | ipy_prompt = | |
216 | [ [('In [24]: for i in range(10):','for i in range(10):'), |
|
208 | [ [('In [24]: for i in range(10):','for i in range(10):'), | |
217 | (' ....: print i',' print i'), |
|
209 | (' ....: print i',' print i'), | |
218 | (' ....: ', ''), |
|
210 | (' ....: ', ''), | |
219 | ], |
|
211 | ], | |
220 | [('In [24]: for i in range(10):','for i in range(10):'), |
|
212 | [('In [24]: for i in range(10):','for i in range(10):'), | |
221 | # Qt console prompts expand with spaces, not dots |
|
213 | # Qt console prompts expand with spaces, not dots | |
222 | (' ...: print i',' print i'), |
|
214 | (' ...: print i',' print i'), | |
223 | (' ...: ', ''), |
|
215 | (' ...: ', ''), | |
224 | ], |
|
216 | ], | |
225 | [('In [24]: for i in range(10):','for i in range(10):'), |
|
217 | [('In [24]: for i in range(10):','for i in range(10):'), | |
226 | # Sometimes whitespace preceding '...' has been removed |
|
218 | # Sometimes whitespace preceding '...' has been removed | |
227 | ('...: print i',' print i'), |
|
219 | ('...: print i',' print i'), | |
228 | ('...: ', ''), |
|
220 | ('...: ', ''), | |
229 | ], |
|
221 | ], | |
230 | [('In [24]: for i in range(10):','for i in range(10):'), |
|
222 | [('In [24]: for i in range(10):','for i in range(10):'), | |
231 | # Space after last continuation prompt has been removed (issue #6674) |
|
223 | # Space after last continuation prompt has been removed (issue #6674) | |
232 | ('...: print i',' print i'), |
|
224 | ('...: print i',' print i'), | |
233 | ('...:', ''), |
|
225 | ('...:', ''), | |
234 | ], |
|
226 | ], | |
235 | [('In [2]: a="""','a="""'), |
|
227 | [('In [2]: a="""','a="""'), | |
236 | (' ...: 123"""','123"""'), |
|
228 | (' ...: 123"""','123"""'), | |
237 | ], |
|
229 | ], | |
238 | [('a="""','a="""'), |
|
230 | [('a="""','a="""'), | |
239 | (' ...: 123','123'), |
|
231 | (' ...: 123','123'), | |
240 | (' ...: 456"""','456"""'), |
|
232 | (' ...: 456"""','456"""'), | |
241 | ], |
|
233 | ], | |
242 | [('a="""','a="""'), |
|
234 | [('a="""','a="""'), | |
243 | ('In [1]: 123','123'), |
|
235 | ('In [1]: 123','123'), | |
244 | (' ...: 456"""','456"""'), |
|
236 | (' ...: 456"""','456"""'), | |
245 | ], |
|
237 | ], | |
246 | [('a="""','a="""'), |
|
238 | [('a="""','a="""'), | |
247 | ('123','123'), |
|
239 | ('123','123'), | |
248 | (' ...: 456"""',' ...: 456"""'), |
|
240 | (' ...: 456"""',' ...: 456"""'), | |
249 | ], |
|
241 | ], | |
250 | ], |
|
242 | ], | |
251 |
|
243 | |||
252 | multiline_datastructure_prompt = |
|
244 | multiline_datastructure_prompt = | |
253 | [ [('>>> a = [1,','a = [1,'), |
|
245 | [ [('>>> a = [1,','a = [1,'), | |
254 | ('... 2]','2]'), |
|
246 | ('... 2]','2]'), | |
255 | ], |
|
247 | ], | |
256 | ], |
|
248 | ], | |
257 |
|
249 | |||
258 | multiline_datastructure = |
|
250 | multiline_datastructure = | |
259 | [ [('b = ("%s"', None), |
|
251 | [ [('b = ("%s"', None), | |
260 | ('# comment', None), |
|
252 | ('# comment', None), | |
261 | ('%foo )', 'b = ("%s"\n# comment\n%foo )'), |
|
253 | ('%foo )', 'b = ("%s"\n# comment\n%foo )'), | |
262 | ], |
|
254 | ], | |
263 | ], |
|
255 | ], | |
264 |
|
256 | |||
265 | multiline_string = |
|
257 | multiline_string = | |
266 | [ [("'''foo?", None), |
|
258 | [ [("'''foo?", None), | |
267 | ("bar'''", "'''foo?\nbar'''"), |
|
259 | ("bar'''", "'''foo?\nbar'''"), | |
268 | ], |
|
260 | ], | |
269 | ], |
|
261 | ], | |
270 |
|
262 | |||
271 | leading_indent = |
|
263 | leading_indent = | |
272 | [ [(' print "hi"','print "hi"'), |
|
264 | [ [(' print "hi"','print "hi"'), | |
273 | ], |
|
265 | ], | |
274 | [(' for a in range(5):','for a in range(5):'), |
|
266 | [(' for a in range(5):','for a in range(5):'), | |
275 | (' a*2',' a*2'), |
|
267 | (' a*2',' a*2'), | |
276 | ], |
|
268 | ], | |
277 | [(' a="""','a="""'), |
|
269 | [(' a="""','a="""'), | |
278 | (' 123"""','123"""'), |
|
270 | (' 123"""','123"""'), | |
279 | ], |
|
271 | ], | |
280 | [('a="""','a="""'), |
|
272 | [('a="""','a="""'), | |
281 | (' 123"""',' 123"""'), |
|
273 | (' 123"""',' 123"""'), | |
282 | ], |
|
274 | ], | |
283 | ], |
|
275 | ], | |
284 |
|
276 | |||
285 | cellmagic = |
|
277 | cellmagic = | |
286 | [ [(u'%%foo a', None), |
|
278 | [ [(u'%%foo a', None), | |
287 |
(None, |
|
279 | (None, "get_ipython().run_cell_magic('foo', 'a', '')"), | |
288 | ], |
|
280 | ], | |
289 | [(u'%%bar 123', None), |
|
281 | [(u'%%bar 123', None), | |
290 | (u'hello', None), |
|
282 | (u'hello', None), | |
291 |
(None , |
|
283 | (None , "get_ipython().run_cell_magic('bar', '123', 'hello')"), | |
292 | ], |
|
284 | ], | |
293 | [(u'a=5', 'a=5'), |
|
285 | [(u'a=5', 'a=5'), | |
294 | (u'%%cellmagic', '%%cellmagic'), |
|
286 | (u'%%cellmagic', '%%cellmagic'), | |
295 | ], |
|
287 | ], | |
296 | ], |
|
288 | ], | |
297 |
|
289 | |||
298 | escaped = |
|
290 | escaped = | |
299 | [ [('%abc def \\', None), |
|
291 | [ [('%abc def \\', None), | |
300 |
('ghi', |
|
292 | ('ghi', "get_ipython().run_line_magic('abc', 'def ghi')"), | |
301 | ], |
|
293 | ], | |
302 | [('%abc def \\', None), |
|
294 | [('%abc def \\', None), | |
303 | ('ghi\\', None), |
|
295 | ('ghi\\', None), | |
304 |
(None, |
|
296 | (None, "get_ipython().run_line_magic('abc', 'def ghi')"), | |
305 | ], |
|
297 | ], | |
306 | ], |
|
298 | ], | |
307 |
|
299 | |||
308 | assign_magic = |
|
300 | assign_magic = | |
309 | [ [(u'a = %bc de \\', None), |
|
301 | [ [(u'a = %bc de \\', None), | |
310 |
(u'fg', |
|
302 | (u'fg', "a = get_ipython().run_line_magic('bc', 'de fg')"), | |
311 | ], |
|
303 | ], | |
312 | [(u'a = %bc de \\', None), |
|
304 | [(u'a = %bc de \\', None), | |
313 | (u'fg\\', None), |
|
305 | (u'fg\\', None), | |
314 |
(None, |
|
306 | (None, "a = get_ipython().run_line_magic('bc', 'de fg')"), | |
315 | ], |
|
307 | ], | |
316 | ], |
|
308 | ], | |
317 |
|
309 | |||
318 | assign_system = |
|
310 | assign_system = | |
319 | [ [(u'a = !bc de \\', None), |
|
311 | [ [(u'a = !bc de \\', None), | |
320 |
(u'fg', |
|
312 | (u'fg', "a = get_ipython().getoutput('bc de fg')"), | |
321 | ], |
|
313 | ], | |
322 | [(u'a = !bc de \\', None), |
|
314 | [(u'a = !bc de \\', None), | |
323 | (u'fg\\', None), |
|
315 | (u'fg\\', None), | |
324 |
(None, |
|
316 | (None, "a = get_ipython().getoutput('bc de fg')"), | |
325 | ], |
|
317 | ], | |
326 | ], |
|
318 | ], | |
327 | ) |
|
319 | ) | |
328 |
|
320 | |||
329 |
|
321 | |||
330 | def test_assign_system(): |
|
322 | def test_assign_system(): | |
331 | tt.check_pairs(transform_and_reset(ipt.assign_from_system), syntax['assign_system']) |
|
323 | tt.check_pairs(transform_and_reset(ipt.assign_from_system), syntax['assign_system']) | |
332 |
|
324 | |||
333 | def test_assign_magic(): |
|
325 | def test_assign_magic(): | |
334 | tt.check_pairs(transform_and_reset(ipt.assign_from_magic), syntax['assign_magic']) |
|
326 | tt.check_pairs(transform_and_reset(ipt.assign_from_magic), syntax['assign_magic']) | |
335 |
|
327 | |||
336 | def test_classic_prompt(): |
|
328 | def test_classic_prompt(): | |
337 | tt.check_pairs(transform_and_reset(ipt.classic_prompt), syntax['classic_prompt']) |
|
329 | tt.check_pairs(transform_and_reset(ipt.classic_prompt), syntax['classic_prompt']) | |
338 | for example in syntax_ml['classic_prompt']: |
|
330 | for example in syntax_ml['classic_prompt']: | |
339 | transform_checker(example, ipt.classic_prompt) |
|
331 | transform_checker(example, ipt.classic_prompt) | |
340 | for example in syntax_ml['multiline_datastructure_prompt']: |
|
332 | for example in syntax_ml['multiline_datastructure_prompt']: | |
341 | transform_checker(example, ipt.classic_prompt) |
|
333 | transform_checker(example, ipt.classic_prompt) | |
342 |
|
334 | |||
343 | # Check that we don't transform the second line if the first is obviously |
|
335 | # Check that we don't transform the second line if the first is obviously | |
344 | # IPython syntax |
|
336 | # IPython syntax | |
345 | transform_checker([ |
|
337 | transform_checker([ | |
346 | (u'%foo', '%foo'), |
|
338 | (u'%foo', '%foo'), | |
347 | (u'>>> bar', '>>> bar'), |
|
339 | (u'>>> bar', '>>> bar'), | |
348 | ], ipt.classic_prompt) |
|
340 | ], ipt.classic_prompt) | |
349 |
|
341 | |||
350 |
|
342 | |||
351 | def test_ipy_prompt(): |
|
343 | def test_ipy_prompt(): | |
352 | tt.check_pairs(transform_and_reset(ipt.ipy_prompt), syntax['ipy_prompt']) |
|
344 | tt.check_pairs(transform_and_reset(ipt.ipy_prompt), syntax['ipy_prompt']) | |
353 | for example in syntax_ml['ipy_prompt']: |
|
345 | for example in syntax_ml['ipy_prompt']: | |
354 | transform_checker(example, ipt.ipy_prompt) |
|
346 | transform_checker(example, ipt.ipy_prompt) | |
355 |
|
347 | |||
356 | # Check that we don't transform the second line if we're inside a cell magic |
|
348 | # Check that we don't transform the second line if we're inside a cell magic | |
357 | transform_checker([ |
|
349 | transform_checker([ | |
358 | (u'%%foo', '%%foo'), |
|
350 | (u'%%foo', '%%foo'), | |
359 | (u'In [1]: bar', 'In [1]: bar'), |
|
351 | (u'In [1]: bar', 'In [1]: bar'), | |
360 | ], ipt.ipy_prompt) |
|
352 | ], ipt.ipy_prompt) | |
361 |
|
353 | |||
362 | def test_assemble_logical_lines(): |
|
354 | def test_assemble_logical_lines(): | |
363 | tests = \ |
|
355 | tests = \ | |
364 | [ [(u"a = \\", None), |
|
356 | [ [(u"a = \\", None), | |
365 | (u"123", u"a = 123"), |
|
357 | (u"123", u"a = 123"), | |
366 | ], |
|
358 | ], | |
367 | [(u"a = \\", None), # Test resetting when within a multi-line string |
|
359 | [(u"a = \\", None), # Test resetting when within a multi-line string | |
368 | (u"12 *\\", None), |
|
360 | (u"12 *\\", None), | |
369 | (None, u"a = 12 *"), |
|
361 | (None, u"a = 12 *"), | |
370 | ], |
|
362 | ], | |
371 | [(u"# foo\\", u"# foo\\"), # Comments can't be continued like this |
|
363 | [(u"# foo\\", u"# foo\\"), # Comments can't be continued like this | |
372 | ], |
|
364 | ], | |
373 | ] |
|
365 | ] | |
374 | for example in tests: |
|
366 | for example in tests: | |
375 | transform_checker(example, ipt.assemble_logical_lines) |
|
367 | transform_checker(example, ipt.assemble_logical_lines) | |
376 |
|
368 | |||
377 | def test_assemble_python_lines(): |
|
369 | def test_assemble_python_lines(): | |
378 | tests = \ |
|
370 | tests = \ | |
379 | [ [(u"a = '''", None), |
|
371 | [ [(u"a = '''", None), | |
380 | (u"abc'''", u"a = '''\nabc'''"), |
|
372 | (u"abc'''", u"a = '''\nabc'''"), | |
381 | ], |
|
373 | ], | |
382 | [(u"a = '''", None), # Test resetting when within a multi-line string |
|
374 | [(u"a = '''", None), # Test resetting when within a multi-line string | |
383 | (u"def", None), |
|
375 | (u"def", None), | |
384 | (None, u"a = '''\ndef"), |
|
376 | (None, u"a = '''\ndef"), | |
385 | ], |
|
377 | ], | |
386 | [(u"a = [1,", None), |
|
378 | [(u"a = [1,", None), | |
387 | (u"2]", u"a = [1,\n2]"), |
|
379 | (u"2]", u"a = [1,\n2]"), | |
388 | ], |
|
380 | ], | |
389 | [(u"a = [1,", None), # Test resetting when within a multi-line string |
|
381 | [(u"a = [1,", None), # Test resetting when within a multi-line string | |
390 | (u"2,", None), |
|
382 | (u"2,", None), | |
391 | (None, u"a = [1,\n2,"), |
|
383 | (None, u"a = [1,\n2,"), | |
392 | ], |
|
384 | ], | |
393 | [(u"a = '''", None), # Test line continuation within a multi-line string |
|
385 | [(u"a = '''", None), # Test line continuation within a multi-line string | |
394 | (u"abc\\", None), |
|
386 | (u"abc\\", None), | |
395 | (u"def", None), |
|
387 | (u"def", None), | |
396 | (u"'''", u"a = '''\nabc\\\ndef\n'''"), |
|
388 | (u"'''", u"a = '''\nabc\\\ndef\n'''"), | |
397 | ], |
|
389 | ], | |
398 | ] + syntax_ml['multiline_datastructure'] |
|
390 | ] + syntax_ml['multiline_datastructure'] | |
399 | for example in tests: |
|
391 | for example in tests: | |
400 | transform_checker(example, ipt.assemble_python_lines) |
|
392 | transform_checker(example, ipt.assemble_python_lines) | |
401 |
|
393 | |||
402 |
|
394 | |||
403 | def test_help_end(): |
|
395 | def test_help_end(): | |
404 | tt.check_pairs(transform_and_reset(ipt.help_end), syntax['end_help']) |
|
396 | tt.check_pairs(transform_and_reset(ipt.help_end), syntax['end_help']) | |
405 |
|
397 | |||
406 | def test_escaped_noesc(): |
|
398 | def test_escaped_noesc(): | |
407 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_noesc']) |
|
399 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_noesc']) | |
408 |
|
400 | |||
409 |
|
401 | |||
410 | def test_escaped_shell(): |
|
402 | def test_escaped_shell(): | |
411 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_shell']) |
|
403 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_shell']) | |
412 |
|
404 | |||
413 |
|
405 | |||
414 | def test_escaped_help(): |
|
406 | def test_escaped_help(): | |
415 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_help']) |
|
407 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_help']) | |
416 |
|
408 | |||
417 |
|
409 | |||
418 | def test_escaped_magic(): |
|
410 | def test_escaped_magic(): | |
419 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_magic']) |
|
411 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_magic']) | |
420 |
|
412 | |||
421 |
|
413 | |||
422 | def test_escaped_quote(): |
|
414 | def test_escaped_quote(): | |
423 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_quote']) |
|
415 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_quote']) | |
424 |
|
416 | |||
425 |
|
417 | |||
426 | def test_escaped_quote2(): |
|
418 | def test_escaped_quote2(): | |
427 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_quote2']) |
|
419 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_quote2']) | |
428 |
|
420 | |||
429 |
|
421 | |||
430 | def test_escaped_paren(): |
|
422 | def test_escaped_paren(): | |
431 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_paren']) |
|
423 | tt.check_pairs(transform_and_reset(ipt.escaped_commands), syntax['escaped_paren']) | |
432 |
|
424 | |||
433 |
|
425 | |||
434 | def test_cellmagic(): |
|
426 | def test_cellmagic(): | |
435 | for example in syntax_ml['cellmagic']: |
|
427 | for example in syntax_ml['cellmagic']: | |
436 | transform_checker(example, ipt.cellmagic) |
|
428 | transform_checker(example, ipt.cellmagic) | |
437 |
|
429 | |||
438 | line_example = [(u'%%bar 123', None), |
|
430 | line_example = [(u'%%bar 123', None), | |
439 | (u'hello', None), |
|
431 | (u'hello', None), | |
440 |
(u'' , |
|
432 | (u'' , "get_ipython().run_cell_magic('bar', '123', 'hello')"), | |
441 | ] |
|
433 | ] | |
442 | transform_checker(line_example, ipt.cellmagic, end_on_blank_line=True) |
|
434 | transform_checker(line_example, ipt.cellmagic, end_on_blank_line=True) | |
443 |
|
435 | |||
444 | def test_has_comment(): |
|
436 | def test_has_comment(): | |
445 | tests = [('text', False), |
|
437 | tests = [('text', False), | |
446 | ('text #comment', True), |
|
438 | ('text #comment', True), | |
447 | ('text #comment\n', True), |
|
439 | ('text #comment\n', True), | |
448 | ('#comment', True), |
|
440 | ('#comment', True), | |
449 | ('#comment\n', True), |
|
441 | ('#comment\n', True), | |
450 | ('a = "#string"', False), |
|
442 | ('a = "#string"', False), | |
451 | ('a = "#string" # comment', True), |
|
443 | ('a = "#string" # comment', True), | |
452 | ('a #comment not "string"', True), |
|
444 | ('a #comment not "string"', True), | |
453 | ] |
|
445 | ] | |
454 | tt.check_pairs(ipt.has_comment, tests) |
|
446 | tt.check_pairs(ipt.has_comment, tests) | |
455 |
|
447 | |||
456 | @ipt.TokenInputTransformer.wrap |
|
448 | @ipt.TokenInputTransformer.wrap | |
457 | def decistmt(tokens): |
|
449 | def decistmt(tokens): | |
458 | """Substitute Decimals for floats in a string of statements. |
|
450 | """Substitute Decimals for floats in a string of statements. | |
459 |
|
451 | |||
460 | Based on an example from the tokenize module docs. |
|
452 | Based on an example from the tokenize module docs. | |
461 | """ |
|
453 | """ | |
462 | result = [] |
|
454 | result = [] | |
463 | for toknum, tokval, _, _, _ in tokens: |
|
455 | for toknum, tokval, _, _, _ in tokens: | |
464 | if toknum == tokenize.NUMBER and '.' in tokval: # replace NUMBER tokens |
|
456 | if toknum == tokenize.NUMBER and '.' in tokval: # replace NUMBER tokens | |
465 | for newtok in [ |
|
457 | for newtok in [ | |
466 | (tokenize.NAME, 'Decimal'), |
|
458 | (tokenize.NAME, 'Decimal'), | |
467 | (tokenize.OP, '('), |
|
459 | (tokenize.OP, '('), | |
468 | (tokenize.STRING, repr(tokval)), |
|
460 | (tokenize.STRING, repr(tokval)), | |
469 | (tokenize.OP, ')') |
|
461 | (tokenize.OP, ')') | |
470 | ]: |
|
462 | ]: | |
471 | yield newtok |
|
463 | yield newtok | |
472 | else: |
|
464 | else: | |
473 | yield (toknum, tokval) |
|
465 | yield (toknum, tokval) | |
474 |
|
466 | |||
475 |
|
467 | |||
476 |
|
468 | |||
477 | def test_token_input_transformer(): |
|
469 | def test_token_input_transformer(): | |
478 |
tests = [(u'1.2', |
|
470 | tests = [(u'1.2', u"Decimal ('1.2')"), | |
479 | (u'"1.2"', u'"1.2"'), |
|
471 | (u'"1.2"', u'"1.2"'), | |
480 | ] |
|
472 | ] | |
481 | tt.check_pairs(transform_and_reset(decistmt), tests) |
|
473 | tt.check_pairs(transform_and_reset(decistmt), tests) | |
482 | ml_tests = \ |
|
474 | ml_tests = \ | |
483 | [ [(u"a = 1.2; b = '''x", None), |
|
475 | [ [(u"a = 1.2; b = '''x", None), | |
484 |
(u"y'''", |
|
476 | (u"y'''", u"a =Decimal ('1.2');b ='''x\ny'''"), | |
485 | ], |
|
477 | ], | |
486 | [(u"a = [1.2,", None), |
|
478 | [(u"a = [1.2,", None), | |
487 |
(u"3]", |
|
479 | (u"3]", u"a =[Decimal ('1.2'),\n3 ]"), | |
488 | ], |
|
480 | ], | |
489 | [(u"a = '''foo", None), # Test resetting when within a multi-line string |
|
481 | [(u"a = '''foo", None), # Test resetting when within a multi-line string | |
490 | (u"bar", None), |
|
482 | (u"bar", None), | |
491 | (None, u"a = '''foo\nbar"), |
|
483 | (None, u"a = '''foo\nbar"), | |
492 | ], |
|
484 | ], | |
493 | ] |
|
485 | ] | |
494 | for example in ml_tests: |
|
486 | for example in ml_tests: | |
495 | transform_checker(example, decistmt) |
|
487 | transform_checker(example, decistmt) |
@@ -1,191 +1,159 | |||||
1 | # coding: utf-8 |
|
1 | # coding: utf-8 | |
2 | """Compatibility tricks for Python 3. Mainly to do with unicode. |
|
2 | """Compatibility tricks for Python 3. Mainly to do with unicode. | |
3 |
|
3 | |||
4 | This file is deprecated and will be removed in a future version. |
|
4 | This file is deprecated and will be removed in a future version. | |
5 | """ |
|
5 | """ | |
6 | import functools |
|
6 | import functools | |
7 | import os |
|
7 | import os | |
8 | import sys |
|
8 | import sys | |
9 | import re |
|
9 | import re | |
10 | import shutil |
|
10 | import shutil | |
11 | import types |
|
11 | import types | |
12 | import platform |
|
12 | import platform | |
13 |
|
13 | |||
14 | from .encoding import DEFAULT_ENCODING |
|
14 | from .encoding import DEFAULT_ENCODING | |
15 |
|
15 | |||
16 |
|
16 | |||
17 | def decode(s, encoding=None): |
|
17 | def decode(s, encoding=None): | |
18 | encoding = encoding or DEFAULT_ENCODING |
|
18 | encoding = encoding or DEFAULT_ENCODING | |
19 | return s.decode(encoding, "replace") |
|
19 | return s.decode(encoding, "replace") | |
20 |
|
20 | |||
21 | def encode(u, encoding=None): |
|
21 | def encode(u, encoding=None): | |
22 | encoding = encoding or DEFAULT_ENCODING |
|
22 | encoding = encoding or DEFAULT_ENCODING | |
23 | return u.encode(encoding, "replace") |
|
23 | return u.encode(encoding, "replace") | |
24 |
|
24 | |||
25 |
|
25 | |||
26 | def cast_unicode(s, encoding=None): |
|
26 | def cast_unicode(s, encoding=None): | |
27 | if isinstance(s, bytes): |
|
27 | if isinstance(s, bytes): | |
28 | return decode(s, encoding) |
|
28 | return decode(s, encoding) | |
29 | return s |
|
29 | return s | |
30 |
|
30 | |||
31 | def cast_bytes(s, encoding=None): |
|
31 | def cast_bytes(s, encoding=None): | |
32 | if not isinstance(s, bytes): |
|
32 | if not isinstance(s, bytes): | |
33 | return encode(s, encoding) |
|
33 | return encode(s, encoding) | |
34 | return s |
|
34 | return s | |
35 |
|
35 | |||
36 | def buffer_to_bytes(buf): |
|
36 | def buffer_to_bytes(buf): | |
37 | """Cast a buffer object to bytes""" |
|
37 | """Cast a buffer object to bytes""" | |
38 | if not isinstance(buf, bytes): |
|
38 | if not isinstance(buf, bytes): | |
39 | buf = bytes(buf) |
|
39 | buf = bytes(buf) | |
40 | return buf |
|
40 | return buf | |
41 |
|
41 | |||
42 | def _modify_str_or_docstring(str_change_func): |
|
|||
43 | @functools.wraps(str_change_func) |
|
|||
44 | def wrapper(func_or_str): |
|
|||
45 | if isinstance(func_or_str, (str,)): |
|
|||
46 | func = None |
|
|||
47 | doc = func_or_str |
|
|||
48 | else: |
|
|||
49 | func = func_or_str |
|
|||
50 | doc = func.__doc__ |
|
|||
51 |
|
||||
52 | # PYTHONOPTIMIZE=2 strips docstrings, so they can disappear unexpectedly |
|
|||
53 | if doc is not None: |
|
|||
54 | doc = str_change_func(doc) |
|
|||
55 |
|
||||
56 | if func: |
|
|||
57 | func.__doc__ = doc |
|
|||
58 | return func |
|
|||
59 | return doc |
|
|||
60 | return wrapper |
|
|||
61 |
|
||||
62 | def safe_unicode(e): |
|
42 | def safe_unicode(e): | |
63 | """unicode(e) with various fallbacks. Used for exceptions, which may not be |
|
43 | """unicode(e) with various fallbacks. Used for exceptions, which may not be | |
64 | safe to call unicode() on. |
|
44 | safe to call unicode() on. | |
65 | """ |
|
45 | """ | |
66 | try: |
|
46 | try: | |
67 | return str(e) |
|
47 | return str(e) | |
68 | except UnicodeError: |
|
48 | except UnicodeError: | |
69 | pass |
|
49 | pass | |
70 |
|
50 | |||
71 | try: |
|
51 | try: | |
72 | return repr(e) |
|
52 | return repr(e) | |
73 | except UnicodeError: |
|
53 | except UnicodeError: | |
74 | pass |
|
54 | pass | |
75 |
|
55 | |||
76 | return u'Unrecoverably corrupt evalue' |
|
56 | return u'Unrecoverably corrupt evalue' | |
77 |
|
57 | |||
78 | # shutil.which from Python 3.4 |
|
58 | # shutil.which from Python 3.4 | |
79 | def _shutil_which(cmd, mode=os.F_OK | os.X_OK, path=None): |
|
59 | def _shutil_which(cmd, mode=os.F_OK | os.X_OK, path=None): | |
80 | """Given a command, mode, and a PATH string, return the path which |
|
60 | """Given a command, mode, and a PATH string, return the path which | |
81 | conforms to the given mode on the PATH, or None if there is no such |
|
61 | conforms to the given mode on the PATH, or None if there is no such | |
82 | file. |
|
62 | file. | |
83 |
|
63 | |||
84 | `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result |
|
64 | `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result | |
85 | of os.environ.get("PATH"), or can be overridden with a custom search |
|
65 | of os.environ.get("PATH"), or can be overridden with a custom search | |
86 | path. |
|
66 | path. | |
87 |
|
67 | |||
88 | This is a backport of shutil.which from Python 3.4 |
|
68 | This is a backport of shutil.which from Python 3.4 | |
89 | """ |
|
69 | """ | |
90 | # Check that a given file can be accessed with the correct mode. |
|
70 | # Check that a given file can be accessed with the correct mode. | |
91 | # Additionally check that `file` is not a directory, as on Windows |
|
71 | # Additionally check that `file` is not a directory, as on Windows | |
92 | # directories pass the os.access check. |
|
72 | # directories pass the os.access check. | |
93 | def _access_check(fn, mode): |
|
73 | def _access_check(fn, mode): | |
94 | return (os.path.exists(fn) and os.access(fn, mode) |
|
74 | return (os.path.exists(fn) and os.access(fn, mode) | |
95 | and not os.path.isdir(fn)) |
|
75 | and not os.path.isdir(fn)) | |
96 |
|
76 | |||
97 | # If we're given a path with a directory part, look it up directly rather |
|
77 | # If we're given a path with a directory part, look it up directly rather | |
98 | # than referring to PATH directories. This includes checking relative to the |
|
78 | # than referring to PATH directories. This includes checking relative to the | |
99 | # current directory, e.g. ./script |
|
79 | # current directory, e.g. ./script | |
100 | if os.path.dirname(cmd): |
|
80 | if os.path.dirname(cmd): | |
101 | if _access_check(cmd, mode): |
|
81 | if _access_check(cmd, mode): | |
102 | return cmd |
|
82 | return cmd | |
103 | return None |
|
83 | return None | |
104 |
|
84 | |||
105 | if path is None: |
|
85 | if path is None: | |
106 | path = os.environ.get("PATH", os.defpath) |
|
86 | path = os.environ.get("PATH", os.defpath) | |
107 | if not path: |
|
87 | if not path: | |
108 | return None |
|
88 | return None | |
109 | path = path.split(os.pathsep) |
|
89 | path = path.split(os.pathsep) | |
110 |
|
90 | |||
111 | if sys.platform == "win32": |
|
91 | if sys.platform == "win32": | |
112 | # The current directory takes precedence on Windows. |
|
92 | # The current directory takes precedence on Windows. | |
113 | if not os.curdir in path: |
|
93 | if not os.curdir in path: | |
114 | path.insert(0, os.curdir) |
|
94 | path.insert(0, os.curdir) | |
115 |
|
95 | |||
116 | # PATHEXT is necessary to check on Windows. |
|
96 | # PATHEXT is necessary to check on Windows. | |
117 | pathext = os.environ.get("PATHEXT", "").split(os.pathsep) |
|
97 | pathext = os.environ.get("PATHEXT", "").split(os.pathsep) | |
118 | # See if the given file matches any of the expected path extensions. |
|
98 | # See if the given file matches any of the expected path extensions. | |
119 | # This will allow us to short circuit when given "python.exe". |
|
99 | # This will allow us to short circuit when given "python.exe". | |
120 | # If it does match, only test that one, otherwise we have to try |
|
100 | # If it does match, only test that one, otherwise we have to try | |
121 | # others. |
|
101 | # others. | |
122 | if any(cmd.lower().endswith(ext.lower()) for ext in pathext): |
|
102 | if any(cmd.lower().endswith(ext.lower()) for ext in pathext): | |
123 | files = [cmd] |
|
103 | files = [cmd] | |
124 | else: |
|
104 | else: | |
125 | files = [cmd + ext for ext in pathext] |
|
105 | files = [cmd + ext for ext in pathext] | |
126 | else: |
|
106 | else: | |
127 | # On other platforms you don't have things like PATHEXT to tell you |
|
107 | # On other platforms you don't have things like PATHEXT to tell you | |
128 | # what file suffixes are executable, so just pass on cmd as-is. |
|
108 | # what file suffixes are executable, so just pass on cmd as-is. | |
129 | files = [cmd] |
|
109 | files = [cmd] | |
130 |
|
110 | |||
131 | seen = set() |
|
111 | seen = set() | |
132 | for dir in path: |
|
112 | for dir in path: | |
133 | normdir = os.path.normcase(dir) |
|
113 | normdir = os.path.normcase(dir) | |
134 | if not normdir in seen: |
|
114 | if not normdir in seen: | |
135 | seen.add(normdir) |
|
115 | seen.add(normdir) | |
136 | for thefile in files: |
|
116 | for thefile in files: | |
137 | name = os.path.join(dir, thefile) |
|
117 | name = os.path.join(dir, thefile) | |
138 | if _access_check(name, mode): |
|
118 | if _access_check(name, mode): | |
139 | return name |
|
119 | return name | |
140 | return None |
|
120 | return None | |
141 |
|
121 | |||
142 | PY3 = True |
|
122 | PY3 = True | |
143 |
|
123 | |||
144 | # keep reference to builtin_mod because the kernel overrides that value |
|
124 | # keep reference to builtin_mod because the kernel overrides that value | |
145 | # to forward requests to a frontend. |
|
125 | # to forward requests to a frontend. | |
146 | def input(prompt=''): |
|
126 | def input(prompt=''): | |
147 | return builtin_mod.input(prompt) |
|
127 | return builtin_mod.input(prompt) | |
148 |
|
128 | |||
149 | builtin_mod_name = "builtins" |
|
129 | builtin_mod_name = "builtins" | |
150 | import builtins as builtin_mod |
|
130 | import builtins as builtin_mod | |
151 |
|
131 | |||
152 |
|
132 | |||
153 | which = shutil.which |
|
133 | which = shutil.which | |
154 |
|
134 | |||
155 | def isidentifier(s, dotted=False): |
|
135 | def isidentifier(s, dotted=False): | |
156 | if dotted: |
|
136 | if dotted: | |
157 | return all(isidentifier(a) for a in s.split(".")) |
|
137 | return all(isidentifier(a) for a in s.split(".")) | |
158 | return s.isidentifier() |
|
138 | return s.isidentifier() | |
159 |
|
139 | |||
160 | getcwd = os.getcwd |
|
140 | getcwd = os.getcwd | |
161 |
|
141 | |||
162 | MethodType = types.MethodType |
|
142 | MethodType = types.MethodType | |
163 |
|
143 | |||
164 | def execfile(fname, glob, loc=None, compiler=None): |
|
144 | def execfile(fname, glob, loc=None, compiler=None): | |
165 | loc = loc if (loc is not None) else glob |
|
145 | loc = loc if (loc is not None) else glob | |
166 | with open(fname, 'rb') as f: |
|
146 | with open(fname, 'rb') as f: | |
167 | compiler = compiler or compile |
|
147 | compiler = compiler or compile | |
168 | exec(compiler(f.read(), fname, 'exec'), glob, loc) |
|
148 | exec(compiler(f.read(), fname, 'exec'), glob, loc) | |
169 |
|
149 | |||
170 | # Refactor print statements in doctests. |
|
|||
171 | _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE) |
|
|||
172 |
|
||||
173 | # Abstract u'abc' syntax: |
|
|||
174 | @_modify_str_or_docstring |
|
|||
175 | def u_format(s): |
|
|||
176 | """"{u}'abc'" --> "'abc'" (Python 3) |
|
|||
177 |
|
||||
178 | Accepts a string or a function, so it can be used as a decorator.""" |
|
|||
179 | return s.format(u='') |
|
|||
180 |
|
||||
181 |
|
||||
182 | PY2 = not PY3 |
|
150 | PY2 = not PY3 | |
183 | PYPY = platform.python_implementation() == "PyPy" |
|
151 | PYPY = platform.python_implementation() == "PyPy" | |
184 |
|
152 | |||
185 | # Cython still rely on that as a Dec 28 2019 |
|
153 | # Cython still rely on that as a Dec 28 2019 | |
186 | # See https://github.com/cython/cython/pull/3291 and |
|
154 | # See https://github.com/cython/cython/pull/3291 and | |
187 | # https://github.com/ipython/ipython/issues/12068 |
|
155 | # https://github.com/ipython/ipython/issues/12068 | |
188 | def no_code(x, encoding=None): |
|
156 | def no_code(x, encoding=None): | |
189 | return x |
|
157 | return x | |
190 | unicode_to_str = cast_bytes_py2 = no_code |
|
158 | unicode_to_str = cast_bytes_py2 = no_code | |
191 |
|
159 |
General Comments 0
You need to be logged in to leave comments.
Login now