##// END OF EJS Templates
Fix getting unicode lines in IPython.core.debugger.
Thomas Kluyver -
Show More
@@ -0,0 +1,38 b''
1 """Wrapper around linecache which decodes files to unicode according to PEP 263.
2
3 This is only needed for Python 2 - linecache in Python 3 does the same thing
4 itself.
5 """
6 import functools
7 import linecache
8
9 from IPython.utils import py3compat
10 from IPython.utils import openpy
11
12 if py3compat.PY3:
13 getline = linecache.getline
14
15 # getlines has to be looked up at runtime, because doctests monkeypatch it.
16 @functools.wraps(linecache.getlines)
17 def getlines(filename, module_globals=None):
18 return linecache.getlines(filename, module_globals=module_globals)
19
20 else:
21 def getlines(filename, module_globals=None):
22 """Get the lines (as unicode) for a file from the cache.
23 Update the cache if it doesn't contain an entry for this file already."""
24 linesb = linecache.getlines(filename, module_globals=module_globals)
25 readline = openpy._list_readline(linesb)
26 try:
27 encoding, _ = openpy.detect_encoding(readline)
28 except SyntaxError:
29 encoding = 'ascii'
30 return [l.decode(encoding, 'replace') for l in linesb]
31
32 # This is a straight copy of linecache.getline
33 def getline(filename, lineno, module_globals=None):
34 lines = getlines(filename, module_globals)
35 if 1 <= lineno <= len(lines):
36 return lines[lineno-1]
37 else:
38 return ''
@@ -30,7 +30,7 b' import bdb'
30 30 import linecache
31 31 import sys
32 32
33 from IPython.utils import PyColorize, py3compat
33 from IPython.utils import PyColorize, ulinecache
34 34 from IPython.core import ipapi
35 35 from IPython.utils import coloransi, io, openpy
36 36 from IPython.core.excolors import exception_colors
@@ -179,22 +179,6 b' def _file_lines(fname):'
179 179 return out
180 180
181 181
182 def _readline(x):
183 """helper to pop elements off list of string
184
185 call with list of strings, return readline function that will pop
186 one line off the beginning of a copy of the list with each call.
187 raise StopIteration when empty or on third call
188 """
189 x = x[:2]
190 def readline():
191 if x:
192 return x.pop(0)
193 else:
194 raise StopIteration
195 return readline
196
197
198 182 class Pdb(OldPdb):
199 183 """Modified Pdb class, does not load readline."""
200 184
@@ -320,7 +304,7 b' class Pdb(OldPdb):'
320 304 # vds: <<
321 305
322 306 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
323 import linecache, repr
307 import repr
324 308
325 309 ret = []
326 310
@@ -367,11 +351,7 b' class Pdb(OldPdb):'
367 351 ret.append('%s(%s)%s\n' % (link,lineno,call))
368 352
369 353 start = lineno - 1 - context//2
370 lines = linecache.getlines(filename)
371 try:
372 encoding, _ = openpy.detect_encoding(_readline(lines))
373 except SyntaxError:
374 encoding = "ascii"
354 lines = ulinecache.getlines(filename)
375 355 start = max(start, 0)
376 356 start = min(start, len(lines) - context)
377 357 lines = lines[start : start + context]
@@ -382,7 +362,7 b' class Pdb(OldPdb):'
382 362 and tpl_line_em \
383 363 or tpl_line
384 364 ret.append(self.__format_line(linetpl, filename,
385 start + 1 + i, py3compat.cast_unicode(line),
365 start + 1 + i, line,
386 366 arrow = show_arrow) )
387 367 return ''.join(ret)
388 368
@@ -442,18 +422,10 b' class Pdb(OldPdb):'
442 422 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
443 423 src = []
444 424 if filename == "<string>" and hasattr(self, "_exec_filename"):
445 lines = list(open(self._exec_filename))
446 else:
447 lines = linecache.getlines(filename)
448 try:
449 encoding, _ = openpy.detect_encoding(_readline(lines))
450 except SyntaxError:
451 encoding = "ascii"
452 if not lines:
453 print >>io.stdout, "No src could be located using filename: %r"%filename
454 return #Bailing out, there is nothing to see here
425 filename = self._exec_filename
426
455 427 for lineno in range(first, last+1):
456 line = py3compat.cast_unicode(lines[lineno])
428 ulinecache.getline(filename, lineno)
457 429 if not line:
458 430 break
459 431
@@ -208,3 +208,12 b" def read_py_url(url, errors='replace', skip_encoding_cookie=True):"
208 208 response = urllib.urlopen(url)
209 209 buffer = io.BytesIO(response.read())
210 210 return source_to_unicode(buffer, errors, skip_encoding_cookie)
211
212 def _list_readline(x):
213 """Given a list, returns a readline() function that returns the next element
214 with each call.
215 """
216 x = iter(x)
217 def readline():
218 return next(x)
219 return readline
General Comments 0
You need to be logged in to leave comments. Login now