Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Saving non-ascii history #1377

merged 3 commits into from

3 participants


Non ascii history caused problems for the %hist command with the -f option to save to file (#1375). This adds a test and fixes it.


So has an encoding parameter, learned a new thing today :) Nice fix! Better/neater than the solution I had in mind too.


Yep, I discovered recently - it's essentially the open() function from Python 3, available in Python 2.6 and above.


Seems like we want to be using everywhere, is this true? Can you perhaps write up a simple policy note on that, either in dev docs, or your py3/unicode wiki page?


Yes, I expect it will be useful. I'll put it on the wiki page.

@minrk minrk merged commit fd42bee into ipython:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 13 additions and 5 deletions.
  1. +5 −4 IPython/core/
  2. +8 −1 IPython/core/tests/
9 IPython/core/
@@ -15,6 +15,7 @@
# Stdlib imports
import atexit
import datetime
+from io import open as io_open
import os
import re
@@ -808,7 +809,7 @@ def _format_lineno(session, line):
print("Overwriting file.")
- outfile = open(outfname,'w')
+ outfile = io_open(outfname, 'w', encoding='utf-8')
close_at_end = True
print_nums = 'n' in opts
@@ -851,10 +852,10 @@ def _format_lineno(session, line):
multiline = "\n" in inline
line_sep = '\n' if multiline else ' '
if print_nums:
- print('%s:%s' % (_format_lineno(session, lineno).rjust(width),
- line_sep), file=outfile, end='')
+ print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
+ line_sep), file=outfile, end=u'')
if pyprompts:
- print(">>> ", end="", file=outfile)
+ print(u">>> ", end=u"", file=outfile)
if multiline:
inline = "\n... ".join(inline.splitlines()) + "\n..."
print(inline, file=outfile)
9 IPython/core/tests/
@@ -7,6 +7,7 @@
# stdlib
import os
+import shutil
import sys
import tempfile
import unittest
@@ -31,7 +32,7 @@ def test_history():
hist_file = os.path.join(tmpdir, 'history.sqlite')
ip.history_manager = HistoryManager(shell=ip, hist_file=hist_file)
- hist = ['a=1', 'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"]
+ hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"]
for i, h in enumerate(hist, start=1):
ip.history_manager.store_inputs(i, h)
@@ -51,6 +52,12 @@ def test_history():
# Check whether specifying a range beyond the end of the current
# session results in an error (gh-804)
ip.magic('%hist 2-500')
+ # Check that we can write non-ascii characters to a file
+ ip.magic("%%hist -f %s" % os.path.join(tmpdir, "test1"))
+ ip.magic("%%hist -pf %s" % os.path.join(tmpdir, "test2"))
+ ip.magic("%%hist -nf %s" % os.path.join(tmpdir, "test3"))
+ ip.magic("%%save %s 1-10" % os.path.join(tmpdir, "test4"))
# New session
Something went wrong with that request. Please try again.