##// END OF EJS Templates
Merge pull request #4295 from mgaitan/1093_boundary_load_magic...
Min RK -
r12838:9bfd8553 merge
parent child Browse files
Show More
@@ -18,6 +18,7 b' import io'
18 import os
18 import os
19 import re
19 import re
20 import sys
20 import sys
21 from itertools import chain
21
22
22 # Our own packages
23 # Our own packages
23 from IPython.core.error import TryNext, StdinNotImplementedError, UsageError
24 from IPython.core.error import TryNext, StdinNotImplementedError, UsageError
@@ -39,6 +40,43 b' class MacroToEdit(ValueError): pass'
39
40
40 ipython_input_pat = re.compile(r"<ipython\-input\-(\d+)-[a-z\d]+>$")
41 ipython_input_pat = re.compile(r"<ipython\-input\-(\d+)-[a-z\d]+>$")
41
42
43 # To match, e.g. 8-10 1:5 :10 3-
44 range_re = re.compile(r"""
45 (?P<start>\d+)?
46 ((?P<sep>[\-:])
47 (?P<end>\d+)?)?
48 $""", re.VERBOSE)
49
50
51 def extract_code_ranges(ranges_str):
52 """Turn a string of range for %%load into 2-tuples of (start, stop)
53 ready to use as a slice of the content splitted by lines.
54
55 Examples
56 --------
57 list(extract_input_ranges("5-10 2"))
58 [(4, 10), (1, 2)]
59 """
60 for range_str in ranges_str.split():
61 rmatch = range_re.match(range_str)
62 if not rmatch:
63 continue
64 sep = rmatch.group("sep")
65 start = rmatch.group("start")
66 end = rmatch.group("end")
67
68 if sep == '-':
69 start = int(start) - 1 if start else None
70 end = int(end) if end else None
71 elif sep == ':':
72 start = int(start) - 1 if start else None
73 end = int(end) - 1 if end else None
74 else:
75 end = int(start)
76 start = int(start) - 1
77 yield (start, end)
78
79
42 class InteractivelyDefined(Exception):
80 class InteractivelyDefined(Exception):
43 """Exception for interactively defined variable in magic_edit"""
81 """Exception for interactively defined variable in magic_edit"""
44 def __init__(self, index):
82 def __init__(self, index):
@@ -174,6 +212,11 b' class CodeMagics(Magics):'
174
212
175 Options:
213 Options:
176 --------
214 --------
215 -r <lines>: Specify lines or ranges of lines to load from the source.
216 Ranges could be specified as x-y (x..y) or in python-style x:y
217 (x..(y-1)). Both limits x and y can be left blank (meaning the
218 beginning and end of the file, respectively).
219
177 -y : Don't ask confirmation for loading source above 200 000 characters.
220 -y : Don't ask confirmation for loading source above 200 000 characters.
178
221
179 This magic command can either take a local filename, a URL, an history
222 This magic command can either take a local filename, a URL, an history
@@ -185,15 +228,27 b' class CodeMagics(Magics):'
185 %load 7-27
228 %load 7-27
186 %load myMacro
229 %load myMacro
187 %load http://www.example.com/myscript.py
230 %load http://www.example.com/myscript.py
231 %load -r 5-10 myscript.py
232 %load -r 10-20,30,40: foo.py
188 """
233 """
189 opts,args = self.parse_options(arg_s,'y')
234 opts,args = self.parse_options(arg_s,'yr:')
235
190 if not args:
236 if not args:
191 raise UsageError('Missing filename, URL, input history range, '
237 raise UsageError('Missing filename, URL, input history range, '
192 'or macro.')
238 'or macro.')
193
239
194 contents = self.shell.find_user_code(args)
240 contents = self.shell.find_user_code(args)
241
242 if 'r' in opts:
243 ranges = opts['r'].replace(',', ' ')
244 lines = contents.split('\n')
245 slices = extract_code_ranges(ranges)
246 contents = [lines[slice(*slc)] for slc in slices]
247 contents = '\n'.join(chain.from_iterable(contents))
248
195 l = len(contents)
249 l = len(contents)
196
250
251
197 # 200 000 is ~ 2500 full 80 caracter lines
252 # 200 000 is ~ 2500 full 80 caracter lines
198 # so in average, more than 5000 lines
253 # so in average, more than 5000 lines
199 if l > 200000 and 'y' not in opts:
254 if l > 200000 and 'y' not in opts:
@@ -45,6 +45,21 b' from IPython.utils.process import find_cmd'
45 @magic.magics_class
45 @magic.magics_class
46 class DummyMagics(magic.Magics): pass
46 class DummyMagics(magic.Magics): pass
47
47
48 def test_extract_code_ranges():
49 instr = "1 3 5-6 7-9 10:15 17: :10 10- -13 :"
50 expected = [(0, 1),
51 (2, 3),
52 (4, 6),
53 (6, 9),
54 (9, 14),
55 (16, None),
56 (None, 9),
57 (9, None),
58 (None, 13),
59 (None, None)]
60 actual = list(code.extract_code_ranges(instr))
61 nt.assert_equal(actual, expected)
62
48 def test_rehashx():
63 def test_rehashx():
49 # clear up everything
64 # clear up everything
50 _ip = get_ipython()
65 _ip = get_ipython()
General Comments 0
You need to be logged in to leave comments. Login now