Skip to content

Commit 23321f2

Browse files
fix #465 and add IPython-style py3compat cast functions
1 parent 2d9039c commit 23321f2

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

bpython/_py3compat.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,23 @@
3535
"""
3636

3737
import sys
38+
import locale
3839

3940
py3 = (sys.version_info[0] == 3)
4041

4142
if py3:
4243
from pygments.lexers import Python3Lexer as PythonLexer
4344
else:
4445
from pygments.lexers import PythonLexer
46+
47+
48+
def cast_unicode(s, encoding=locale.getpreferredencoding()):
49+
if isinstance(s, bytes):
50+
return s.decode(encoding)
51+
return s
52+
53+
54+
def cast_bytes(s, encoding=locale.getpreferredencoding()):
55+
if not isinstance(s, bytes):
56+
return s.encode(encoding)
57+
return s

bpython/curtsiesfrontend/repl.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import unicodedata
1515

1616
from pygments import format
17-
from bpython._py3compat import PythonLexer
17+
from bpython._py3compat import PythonLexer, cast_unicode, cast_bytes
1818
from pygments.formatters import TerminalFormatter
1919

2020
import blessings
@@ -1362,6 +1362,9 @@ def focus_on_subprocess(self, args):
13621362
signal.signal(signal.SIGWINCH, prev_sigwinch_handler)
13631363

13641364
def pager(self, text):
1365+
"""Runs an external pager on text
1366+
1367+
text must be a bytestring, ie not yet encoded"""
13651368
command = get_pager_command()
13661369
with tempfile.NamedTemporaryFile() as tmp:
13671370
tmp.write(text)
@@ -1375,12 +1378,14 @@ def show_source(self):
13751378
self.status_bar.message(str(e))
13761379
else:
13771380
if self.config.highlight_show_source:
1378-
source = format(PythonLexer().get_tokens(source),
1379-
TerminalFormatter())
1381+
source = cast_bytes(format(PythonLexer().get_tokens(source),
1382+
TerminalFormatter()))
1383+
else:
1384+
source = cast_bytes(source)
13801385
self.pager(source)
13811386

13821387
def help_text(self):
1383-
return (self.version_help_text() + '\n' + self.key_help_text()).encode('utf8')
1388+
return cast_bytes(self.version_help_text() + '\n' + self.key_help_text())
13841389

13851390
def version_help_text(self):
13861391
return (('bpython-curtsies version %s' % bpython.__version__) + ' ' +

bpython/repl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ def get_args(self):
468468
def get_source_of_current_name(self):
469469
"""Return the source code of the object which is bound to the
470470
current name in the current input line. Throw `SourceNotFound` if the
471-
source cannot be found."""
471+
source cannot be found. Returns bytestring in py2, unicode in py3."""
472472
obj = self.current_func
473473
try:
474474
if obj is None:

bpython/test/test_curtsies_repl.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ def captured_output():
206206
sys.stdout, sys.stderr = old_out, old_err
207207

208208
def create_repl(**kwargs):
209-
config = setup_config({'editor':'true'})
209+
config = setup_config({'editor': 'true'})
210210
repl = curtsiesrepl.Repl(config=config, **kwargs)
211211
os.environ['PAGER'] = 'true'
212212
repl.width = 50
@@ -264,6 +264,27 @@ def test_variable_is_cleared(self):
264264
self.repl.undo()
265265
self.assertNotIn('b', self.repl.interp.locals)
266266

267+
class TestCurtsiesPagerText(unittest.TestCase):
268+
269+
def setUp(self):
270+
self.repl = create_repl()
271+
self.repl.pager = self.assert_pager_gets_bytes
272+
273+
def assert_pager_gets_bytes(self, text):
274+
self.assertIsInstance(text, type(b''))
275+
276+
def test_help(self):
277+
self.repl.pager(self.repl.help_text())
278+
279+
def test_show_source_not_formatted(self):
280+
self.repl.config.highlight_show_source = False
281+
self.repl.get_source_of_current_name = lambda: 'source code å∂߃åß∂ƒ'
282+
self.repl.show_source()
283+
284+
def test_show_source_formatted(self):
285+
self.repl.config.highlight_show_source = True
286+
self.repl.get_source_of_current_name = lambda: 'source code å∂߃åß∂ƒ'
287+
self.repl.show_source()
267288

268289
if __name__ == '__main__':
269290
unittest.main()

0 commit comments

Comments
 (0)