From 01440833e1b1068e6e607afe0cd1ba0978b3787d 2013-12-27 19:43:43 From: Min RK Date: 2013-12-27 19:43:43 Subject: [PATCH] Merge pull request #4713 from takluyver/kernel-history-py2 Fix saving kernel history in Python 2 --- diff --git a/IPython/kernel/tests/test_kernel.py b/IPython/kernel/tests/test_kernel.py index 1f1096b..5c3272f 100644 --- a/IPython/kernel/tests/test_kernel.py +++ b/IPython/kernel/tests/test_kernel.py @@ -1,3 +1,4 @@ +# coding: utf-8 """test the IPython Kernel""" #------------------------------------------------------------------------------- @@ -11,6 +12,8 @@ # Imports #------------------------------------------------------------------------------- +import io +import os.path import sys import nose.tools as nt @@ -18,8 +21,10 @@ import nose.tools as nt from IPython.testing import decorators as dec, tools as tt from IPython.utils import py3compat from IPython.utils.path import locate_profile +from IPython.utils.tempdir import TemporaryDirectory -from .utils import new_kernel, kernel, TIMEOUT, assemble_output, execute, flush_channels +from .utils import (new_kernel, kernel, TIMEOUT, assemble_output, execute, + flush_channels, wait_for_idle) #------------------------------------------------------------------------------- # Tests @@ -180,6 +185,22 @@ def test_eval_input(): nt.assert_equal(stdout, "2\n") +def test_save_history(): + # Saving history from the kernel with %hist -f was failing because of + # unicode problems on Python 2. + with kernel() as kc, TemporaryDirectory() as td: + file = os.path.join(td, 'hist.out') + execute(u'a=1', kc=kc) + wait_for_idle(kc) + execute(u'b=u"abcþ"', kc=kc) + wait_for_idle(kc) + _, reply = execute("%hist -f " + file, kc=kc) + nt.assert_equal(reply['status'], 'ok') + with io.open(file, encoding='utf-8') as f: + content = f.read() + nt.assert_in(u'a=1', content) + nt.assert_in(u'b=u"abcþ"', content) + def test_help_output(): """ipython kernel --help-all works""" tt.help_all_output_test('kernel') diff --git a/IPython/kernel/tests/utils.py b/IPython/kernel/tests/utils.py index 0577c6a..1f257ad 100644 --- a/IPython/kernel/tests/utils.py +++ b/IPython/kernel/tests/utils.py @@ -170,5 +170,10 @@ def assemble_output(iopub): pass return stdout, stderr - - +def wait_for_idle(kc): + while True: + msg = kc.iopub_channel.get_msg(block=True, timeout=1) + msg_type = msg['msg_type'] + content = msg['content'] + if msg_type == 'status' and content['execution_state'] == 'idle': + break diff --git a/IPython/kernel/zmq/ipkernel.py b/IPython/kernel/zmq/ipkernel.py index 15840bb..8fc4063 100755 --- a/IPython/kernel/zmq/ipkernel.py +++ b/IPython/kernel/zmq/ipkernel.py @@ -341,7 +341,7 @@ class Kernel(Configurable): try: content = parent[u'content'] - code = content[u'code'] + code = py3compat.cast_unicode_py2(content[u'code']) silent = content[u'silent'] store_history = content.get(u'store_history', not silent) except: diff --git a/IPython/utils/py3compat.py b/IPython/utils/py3compat.py index edd7b7d..822dad3 100644 --- a/IPython/utils/py3compat.py +++ b/IPython/utils/py3compat.py @@ -83,6 +83,7 @@ if sys.version_info[0] >= 3: str_to_bytes = encode bytes_to_str = decode cast_bytes_py2 = no_code + cast_unicode_py2 = no_code string_types = (str,) unicode_type = str @@ -139,6 +140,7 @@ else: str_to_bytes = no_code bytes_to_str = no_code cast_bytes_py2 = cast_bytes + cast_unicode_py2 = cast_unicode string_types = (str, unicode) unicode_type = unicode