##// END OF EJS Templates
Update history.py to use pathlib...
Jakub Klus -
Show More
@@ -6,7 +6,7 b''
6
6
7 import atexit
7 import atexit
8 import datetime
8 import datetime
9 import os
9 from pathlib import Path
10 import re
10 import re
11 import sqlite3
11 import sqlite3
12 import threading
12 import threading
@@ -16,8 +16,8 b' from decorator import decorator'
16 from IPython.utils.decorators import undoc
16 from IPython.utils.decorators import undoc
17 from IPython.paths import locate_profile
17 from IPython.paths import locate_profile
18 from traitlets import (
18 from traitlets import (
19 Any, Bool, Dict, Instance, Integer, List, Unicode, TraitError,
19 Any, Bool, Dict, Instance, Integer, List, Unicode, Union, TraitError,
20 default, observe,
20 default, observe
21 )
21 )
22
22
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
@@ -27,17 +27,17 b' from traitlets import ('
27 @undoc
27 @undoc
28 class DummyDB(object):
28 class DummyDB(object):
29 """Dummy DB that will act as a black hole for history.
29 """Dummy DB that will act as a black hole for history.
30
30
31 Only used in the absence of sqlite"""
31 Only used in the absence of sqlite"""
32 def execute(*args, **kwargs):
32 def execute(*args, **kwargs):
33 return []
33 return []
34
34
35 def commit(self, *args, **kwargs):
35 def commit(self, *args, **kwargs):
36 pass
36 pass
37
37
38 def __enter__(self, *args, **kwargs):
38 def __enter__(self, *args, **kwargs):
39 pass
39 pass
40
40
41 def __exit__(self, *args, **kwargs):
41 def __exit__(self, *args, **kwargs):
42 pass
42 pass
43
43
@@ -73,17 +73,18 b' def catch_corrupt_db(f, self, *a, **kw):'
73 if self._corrupt_db_counter > self._corrupt_db_limit:
73 if self._corrupt_db_counter > self._corrupt_db_limit:
74 self.hist_file = ':memory:'
74 self.hist_file = ':memory:'
75 self.log.error("Failed to load history too many times, history will not be saved.")
75 self.log.error("Failed to load history too many times, history will not be saved.")
76 elif os.path.isfile(self.hist_file):
76 elif self.hist_file.is_file():
77 # move the file out of the way
77 # move the file out of the way
78 base, ext = os.path.splitext(self.hist_file)
78 base = str(self.hist_file.parent / self.hist_file.stem)
79 size = os.stat(self.hist_file).st_size
79 ext = self.hist_file.suffix
80 size = self.hist_file.stat().st_size
80 if size >= _SAVE_DB_SIZE:
81 if size >= _SAVE_DB_SIZE:
81 # if there's significant content, avoid clobbering
82 # if there's significant content, avoid clobbering
82 now = datetime.datetime.now().isoformat().replace(':', '.')
83 now = datetime.datetime.now().isoformat().replace(':', '.')
83 newpath = base + '-corrupt-' + now + ext
84 newpath = base + '-corrupt-' + now + ext
84 # don't clobber previous corrupt backups
85 # don't clobber previous corrupt backups
85 for i in range(100):
86 for i in range(100):
86 if not os.path.isfile(newpath):
87 if not Path(newpath).exists():
87 break
88 break
88 else:
89 else:
89 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
90 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
@@ -91,14 +92,14 b' def catch_corrupt_db(f, self, *a, **kw):'
91 # not much content, possibly empty; don't worry about clobbering
92 # not much content, possibly empty; don't worry about clobbering
92 # maybe we should just delete it?
93 # maybe we should just delete it?
93 newpath = base + '-corrupt' + ext
94 newpath = base + '-corrupt' + ext
94 os.rename(self.hist_file, newpath)
95 self.hist_file.rename(newpath)
95 self.log.error("History file was moved to %s and a new file created.", newpath)
96 self.log.error("History file was moved to %s and a new file created.", newpath)
96 self.init_db()
97 self.init_db()
97 return []
98 return []
98 else:
99 else:
99 # Failed with :memory:, something serious is wrong
100 # Failed with :memory:, something serious is wrong
100 raise
101 raise
101
102
102 class HistoryAccessorBase(LoggingConfigurable):
103 class HistoryAccessorBase(LoggingConfigurable):
103 """An abstract class for History Accessors """
104 """An abstract class for History Accessors """
104
105
@@ -118,7 +119,7 b' class HistoryAccessorBase(LoggingConfigurable):'
118
119
119 class HistoryAccessor(HistoryAccessorBase):
120 class HistoryAccessor(HistoryAccessorBase):
120 """Access the history database without adding to it.
121 """Access the history database without adding to it.
121
122
122 This is intended for use by standalone history tools. IPython shells use
123 This is intended for use by standalone history tools. IPython shells use
123 HistoryManager, below, which is a subclass of this."""
124 HistoryManager, below, which is a subclass of this."""
124
125
@@ -128,37 +129,38 b' class HistoryAccessor(HistoryAccessorBase):'
128 _corrupt_db_limit = 2
129 _corrupt_db_limit = 2
129
130
130 # String holding the path to the history file
131 # String holding the path to the history file
131 hist_file = Unicode(
132 hist_file = Union([Instance(Path), Unicode()],
132 help="""Path to file to use for SQLite history database.
133 help="""Path to file to use for SQLite history database.
133
134
134 By default, IPython will put the history database in the IPython
135 By default, IPython will put the history database in the IPython
135 profile directory. If you would rather share one history among
136 profile directory. If you would rather share one history among
136 profiles, you can set this value in each, so that they are consistent.
137 profiles, you can set this value in each, so that they are consistent.
137
138
138 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
139 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
139 mounts. If you see IPython hanging, try setting this to something on a
140 mounts. If you see IPython hanging, try setting this to something on a
140 local disk, e.g::
141 local disk, e.g::
141
142
142 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
143 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
143
144
144 you can also use the specific value `:memory:` (including the colon
145 you can also use the specific value `:memory:` (including the colon
145 at both end but not the back ticks), to avoid creating an history file.
146 at both end but not the back ticks), to avoid creating an history file.
146
147
147 """).tag(config=True)
148 """
148
149 ).tag(config=True)
150
149 enabled = Bool(True,
151 enabled = Bool(True,
150 help="""enable the SQLite history
152 help="""enable the SQLite history
151
153
152 set enabled=False to disable the SQLite history,
154 set enabled=False to disable the SQLite history,
153 in which case there will be no stored history, no SQLite connection,
155 in which case there will be no stored history, no SQLite connection,
154 and no background saving thread. This may be necessary in some
156 and no background saving thread. This may be necessary in some
155 threaded environments where IPython is embedded.
157 threaded environments where IPython is embedded.
156 """
158 """
157 ).tag(config=True)
159 ).tag(config=True)
158
160
159 connection_options = Dict(
161 connection_options = Dict(
160 help="""Options for configuring the SQLite connection
162 help="""Options for configuring the SQLite connection
161
163
162 These options are passed as keyword args to sqlite3.connect
164 These options are passed as keyword args to sqlite3.connect
163 when establishing database connections.
165 when establishing database connections.
164 """
166 """
@@ -175,10 +177,10 b' class HistoryAccessor(HistoryAccessorBase):'
175 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
177 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
176 (self.__class__.__name__, new)
178 (self.__class__.__name__, new)
177 raise TraitError(msg)
179 raise TraitError(msg)
178
180
179 def __init__(self, profile='default', hist_file=u'', **traits):
181 def __init__(self, profile='default', hist_file="", **traits):
180 """Create a new history accessor.
182 """Create a new history accessor.
181
183
182 Parameters
184 Parameters
183 ----------
185 ----------
184 profile : str
186 profile : str
@@ -196,33 +198,35 b' class HistoryAccessor(HistoryAccessorBase):'
196 # set by config
198 # set by config
197 if hist_file:
199 if hist_file:
198 self.hist_file = hist_file
200 self.hist_file = hist_file
199
201
200 if self.hist_file == u'':
202 try:
203 self.hist_file
204 except TraitError:
201 # No one has set the hist_file, yet.
205 # No one has set the hist_file, yet.
202 self.hist_file = self._get_hist_file_name(profile)
206 self.hist_file = self._get_hist_file_name(profile)
203
207
204 self.init_db()
208 self.init_db()
205
209
206 def _get_hist_file_name(self, profile='default'):
210 def _get_hist_file_name(self, profile='default'):
207 """Find the history file for the given profile name.
211 """Find the history file for the given profile name.
208
212
209 This is overridden by the HistoryManager subclass, to use the shell's
213 This is overridden by the HistoryManager subclass, to use the shell's
210 active profile.
214 active profile.
211
215
212 Parameters
216 Parameters
213 ----------
217 ----------
214 profile : str
218 profile : str
215 The name of a profile which has a history file.
219 The name of a profile which has a history file.
216 """
220 """
217 return os.path.join(locate_profile(profile), 'history.sqlite')
221 return Path(locate_profile(profile)) / 'history.sqlite'
218
222
219 @catch_corrupt_db
223 @catch_corrupt_db
220 def init_db(self):
224 def init_db(self):
221 """Connect to the database, and create tables if necessary."""
225 """Connect to the database, and create tables if necessary."""
222 if not self.enabled:
226 if not self.enabled:
223 self.db = DummyDB()
227 self.db = DummyDB()
224 return
228 return
225
229
226 # use detect_types so that timestamps return datetime objects
230 # use detect_types so that timestamps return datetime objects
227 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
231 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
228 kwargs.update(self.connection_options)
232 kwargs.update(self.connection_options)
@@ -290,7 +294,7 b' class HistoryAccessor(HistoryAccessorBase):'
290
294
291 Returns
295 Returns
292 -------
296 -------
293
297
294 session_id : int
298 session_id : int
295 Session ID number
299 Session ID number
296 start : datetime
300 start : datetime
@@ -308,7 +312,7 b' class HistoryAccessor(HistoryAccessorBase):'
308 @catch_corrupt_db
312 @catch_corrupt_db
309 def get_last_session_id(self):
313 def get_last_session_id(self):
310 """Get the last session ID currently in the database.
314 """Get the last session ID currently in the database.
311
315
312 Within IPython, this should be the same as the value stored in
316 Within IPython, this should be the same as the value stored in
313 :attr:`HistoryManager.session_number`.
317 :attr:`HistoryManager.session_number`.
314 """
318 """
@@ -384,7 +388,7 b' class HistoryAccessor(HistoryAccessorBase):'
384 if n is not None:
388 if n is not None:
385 return reversed(list(cur))
389 return reversed(list(cur))
386 return cur
390 return cur
387
391
388 @catch_corrupt_db
392 @catch_corrupt_db
389 def get_range(self, session, start=1, stop=None, raw=True,output=False):
393 def get_range(self, session, start=1, stop=None, raw=True,output=False):
390 """Retrieve input by session.
394 """Retrieve input by session.
@@ -461,7 +465,7 b' class HistoryManager(HistoryAccessor):'
461 @default('dir_hist')
465 @default('dir_hist')
462 def _dir_hist_default(self):
466 def _dir_hist_default(self):
463 try:
467 try:
464 return [os.getcwd()]
468 return [Path.cwd()]
465 except OSError:
469 except OSError:
466 return []
470 return []
467
471
@@ -473,7 +477,7 b' class HistoryManager(HistoryAccessor):'
473
477
474 # The number of the current session in the history database
478 # The number of the current session in the history database
475 session_number = Integer()
479 session_number = Integer()
476
480
477 db_log_output = Bool(False,
481 db_log_output = Bool(False,
478 help="Should the history database include output? (default: no)"
482 help="Should the history database include output? (default: no)"
479 ).tag(config=True)
483 ).tag(config=True)
@@ -484,12 +488,12 b' class HistoryManager(HistoryAccessor):'
484 # The input and output caches
488 # The input and output caches
485 db_input_cache = List()
489 db_input_cache = List()
486 db_output_cache = List()
490 db_output_cache = List()
487
491
488 # History saving in separate thread
492 # History saving in separate thread
489 save_thread = Instance('IPython.core.history.HistorySavingThread',
493 save_thread = Instance('IPython.core.history.HistorySavingThread',
490 allow_none=True)
494 allow_none=True)
491 save_flag = Instance(threading.Event, allow_none=True)
495 save_flag = Instance(threading.Event, allow_none=True)
492
496
493 # Private interface
497 # Private interface
494 # Variables used to store the three last inputs from the user. On each new
498 # Variables used to store the three last inputs from the user. On each new
495 # history update, we populate the user's namespace with these, shifted as
499 # history update, we populate the user's namespace with these, shifted as
@@ -513,37 +517,37 b' class HistoryManager(HistoryAccessor):'
513 self.save_flag = threading.Event()
517 self.save_flag = threading.Event()
514 self.db_input_cache_lock = threading.Lock()
518 self.db_input_cache_lock = threading.Lock()
515 self.db_output_cache_lock = threading.Lock()
519 self.db_output_cache_lock = threading.Lock()
516
520
517 try:
521 try:
518 self.new_session()
522 self.new_session()
519 except sqlite3.OperationalError:
523 except sqlite3.OperationalError:
520 self.log.error("Failed to create history session in %s. History will not be saved.",
524 self.log.error("Failed to create history session in %s. History will not be saved.",
521 self.hist_file, exc_info=True)
525 self.hist_file, exc_info=True)
522 self.hist_file = ':memory:'
526 self.hist_file = ':memory:'
523
527
524 if self.enabled and self.hist_file != ':memory:':
528 if self.enabled and self.hist_file != ':memory:':
525 self.save_thread = HistorySavingThread(self)
529 self.save_thread = HistorySavingThread(self)
526 self.save_thread.start()
530 self.save_thread.start()
527
531
528 def _get_hist_file_name(self, profile=None):
532 def _get_hist_file_name(self, profile=None):
529 """Get default history file name based on the Shell's profile.
533 """Get default history file name based on the Shell's profile.
530
534
531 The profile parameter is ignored, but must exist for compatibility with
535 The profile parameter is ignored, but must exist for compatibility with
532 the parent class."""
536 the parent class."""
533 profile_dir = self.shell.profile_dir.location
537 profile_dir = self.shell.profile_dir.location
534 return os.path.join(profile_dir, 'history.sqlite')
538 return Path(profile_dir)/'history.sqlite'
535
539
536 @only_when_enabled
540 @only_when_enabled
537 def new_session(self, conn=None):
541 def new_session(self, conn=None):
538 """Get a new session number."""
542 """Get a new session number."""
539 if conn is None:
543 if conn is None:
540 conn = self.db
544 conn = self.db
541
545
542 with conn:
546 with conn:
543 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
547 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
544 NULL, "") """, (datetime.datetime.now(),))
548 NULL, "") """, (datetime.datetime.now(),))
545 self.session_number = cur.lastrowid
549 self.session_number = cur.lastrowid
546
550
547 def end_session(self):
551 def end_session(self):
548 """Close the database session, filling in the end time and line count."""
552 """Close the database session, filling in the end time and line count."""
549 self.writeout_cache()
553 self.writeout_cache()
@@ -552,20 +556,20 b' class HistoryManager(HistoryAccessor):'
552 session==?""", (datetime.datetime.now(),
556 session==?""", (datetime.datetime.now(),
553 len(self.input_hist_parsed)-1, self.session_number))
557 len(self.input_hist_parsed)-1, self.session_number))
554 self.session_number = 0
558 self.session_number = 0
555
559
556 def name_session(self, name):
560 def name_session(self, name):
557 """Give the current session a name in the history database."""
561 """Give the current session a name in the history database."""
558 with self.db:
562 with self.db:
559 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
563 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
560 (name, self.session_number))
564 (name, self.session_number))
561
565
562 def reset(self, new_session=True):
566 def reset(self, new_session=True):
563 """Clear the session history, releasing all object references, and
567 """Clear the session history, releasing all object references, and
564 optionally open a new session."""
568 optionally open a new session."""
565 self.output_hist.clear()
569 self.output_hist.clear()
566 # The directory history can't be completely empty
570 # The directory history can't be completely empty
567 self.dir_hist[:] = [os.getcwd()]
571 self.dir_hist[:] = [Path.cwd()]
568
572
569 if new_session:
573 if new_session:
570 if self.session_number:
574 if self.session_number:
571 self.end_session()
575 self.end_session()
@@ -588,7 +592,7 b' class HistoryManager(HistoryAccessor):'
588
592
589 Returns
593 Returns
590 -------
594 -------
591
595
592 session_id : int
596 session_id : int
593 Session ID number
597 Session ID number
594 start : datetime
598 start : datetime
@@ -609,7 +613,7 b' class HistoryManager(HistoryAccessor):'
609 """Get input and output history from the current session. Called by
613 """Get input and output history from the current session. Called by
610 get_range, and takes similar parameters."""
614 get_range, and takes similar parameters."""
611 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
615 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
612
616
613 n = len(input_hist)
617 n = len(input_hist)
614 if start < 0:
618 if start < 0:
615 start += n
619 start += n
@@ -617,17 +621,17 b' class HistoryManager(HistoryAccessor):'
617 stop = n
621 stop = n
618 elif stop < 0:
622 elif stop < 0:
619 stop += n
623 stop += n
620
624
621 for i in range(start, stop):
625 for i in range(start, stop):
622 if output:
626 if output:
623 line = (input_hist[i], self.output_hist_reprs.get(i))
627 line = (input_hist[i], self.output_hist_reprs.get(i))
624 else:
628 else:
625 line = input_hist[i]
629 line = input_hist[i]
626 yield (0, i, line)
630 yield (0, i, line)
627
631
628 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
632 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
629 """Retrieve input by session.
633 """Retrieve input by session.
630
634
631 Parameters
635 Parameters
632 ----------
636 ----------
633 session : int
637 session : int
@@ -645,7 +649,7 b' class HistoryManager(HistoryAccessor):'
645 objects for the current session, or text reprs from previous
649 objects for the current session, or text reprs from previous
646 sessions if db_log_output was enabled at the time. Where no output
650 sessions if db_log_output was enabled at the time. Where no output
647 is found, None is used.
651 is found, None is used.
648
652
649 Returns
653 Returns
650 -------
654 -------
651 entries
655 entries
@@ -709,7 +713,7 b' class HistoryManager(HistoryAccessor):'
709 '_ii': self._ii,
713 '_ii': self._ii,
710 '_iii': self._iii,
714 '_iii': self._iii,
711 new_i : self._i00 }
715 new_i : self._i00 }
712
716
713 if self.shell is not None:
717 if self.shell is not None:
714 self.shell.push(to_main, interactive=False)
718 self.shell.push(to_main, interactive=False)
715
719
@@ -7,7 +7,7 b''
7
7
8 # stdlib
8 # stdlib
9 import io
9 import io
10 import os
10 from pathlib import Path
11 import sys
11 import sys
12 import tempfile
12 import tempfile
13 from datetime import datetime
13 from datetime import datetime
@@ -29,8 +29,9 b' def test_proper_default_encoding():'
29 def test_history():
29 def test_history():
30 ip = get_ipython()
30 ip = get_ipython()
31 with TemporaryDirectory() as tmpdir:
31 with TemporaryDirectory() as tmpdir:
32 tmp_path = Path(tmpdir)
32 hist_manager_ori = ip.history_manager
33 hist_manager_ori = ip.history_manager
33 hist_file = os.path.join(tmpdir, 'history.sqlite')
34 hist_file = tmp_path / 'history.sqlite'
34 try:
35 try:
35 ip.history_manager = HistoryManager(shell=ip, hist_file=hist_file)
36 ip.history_manager = HistoryManager(shell=ip, hist_file=hist_file)
36 hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"]
37 hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='€Æ¾÷ß'"]
@@ -55,10 +56,10 b' def test_history():'
55 ip.magic('%hist 2-500')
56 ip.magic('%hist 2-500')
56
57
57 # Check that we can write non-ascii characters to a file
58 # Check that we can write non-ascii characters to a file
58 ip.magic("%%hist -f %s" % os.path.join(tmpdir, "test1"))
59 ip.magic("%%hist -f %s" % (tmp_path / "test1"))
59 ip.magic("%%hist -pf %s" % os.path.join(tmpdir, "test2"))
60 ip.magic("%%hist -pf %s" % (tmp_path / "test2"))
60 ip.magic("%%hist -nf %s" % os.path.join(tmpdir, "test3"))
61 ip.magic("%%hist -nf %s" % (tmp_path / "test3"))
61 ip.magic("%%save %s 1-10" % os.path.join(tmpdir, "test4"))
62 ip.magic("%%save %s 1-10" % (tmp_path / "test4"))
62
63
63 # New session
64 # New session
64 ip.history_manager.reset()
65 ip.history_manager.reset()
@@ -126,8 +127,8 b' def test_history():'
126 nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
127 nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
127
128
128 # Cross testing: check that magic %save can get previous session.
129 # Cross testing: check that magic %save can get previous session.
129 testfilename = os.path.realpath(os.path.join(tmpdir, "test.py"))
130 testfilename = (tmp_path /"test.py").resolve()
130 ip.magic("save " + testfilename + " ~1/1-3")
131 ip.magic("save " + str(testfilename) + " ~1/1-3")
131 with io.open(testfilename, encoding='utf-8') as testfile:
132 with io.open(testfilename, encoding='utf-8') as testfile:
132 nt.assert_equal(testfile.read(),
133 nt.assert_equal(testfile.read(),
133 u"# coding: utf-8\n" + u"\n".join(hist)+u"\n")
134 u"# coding: utf-8\n" + u"\n".join(hist)+u"\n")
@@ -176,13 +177,13 b' def test_timestamp_type():'
176 def test_hist_file_config():
177 def test_hist_file_config():
177 cfg = Config()
178 cfg = Config()
178 tfile = tempfile.NamedTemporaryFile(delete=False)
179 tfile = tempfile.NamedTemporaryFile(delete=False)
179 cfg.HistoryManager.hist_file = tfile.name
180 cfg.HistoryManager.hist_file = Path(tfile.name)
180 try:
181 try:
181 hm = HistoryManager(shell=get_ipython(), config=cfg)
182 hm = HistoryManager(shell=get_ipython(), config=cfg)
182 nt.assert_equal(hm.hist_file, cfg.HistoryManager.hist_file)
183 nt.assert_equal(hm.hist_file, cfg.HistoryManager.hist_file)
183 finally:
184 finally:
184 try:
185 try:
185 os.remove(tfile.name)
186 Path(tfile.name).unlink()
186 except OSError:
187 except OSError:
187 # same catch as in testing.tools.TempFileMixin
188 # same catch as in testing.tools.TempFileMixin
188 # On Windows, even though we close the file, we still can't
189 # On Windows, even though we close the file, we still can't
@@ -197,7 +198,7 b' def test_histmanager_disabled():'
197 ip = get_ipython()
198 ip = get_ipython()
198 with TemporaryDirectory() as tmpdir:
199 with TemporaryDirectory() as tmpdir:
199 hist_manager_ori = ip.history_manager
200 hist_manager_ori = ip.history_manager
200 hist_file = os.path.join(tmpdir, 'history.sqlite')
201 hist_file = Path(tmpdir) / 'history.sqlite'
201 cfg.HistoryManager.hist_file = hist_file
202 cfg.HistoryManager.hist_file = hist_file
202 try:
203 try:
203 ip.history_manager = HistoryManager(shell=ip, config=cfg)
204 ip.history_manager = HistoryManager(shell=ip, config=cfg)
@@ -211,4 +212,4 b' def test_histmanager_disabled():'
211 ip.history_manager = hist_manager_ori
212 ip.history_manager = hist_manager_ori
212
213
213 # hist_file should not be created
214 # hist_file should not be created
214 nt.assert_false(os.path.exists(hist_file))
215 nt.assert_false(hist_file.exists())
@@ -10,6 +10,7 b' Authors'
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11
11
12 import os
12 import os
13 from pathlib import Path
13 import re
14 import re
14 import sys
15 import sys
15 import tempfile
16 import tempfile
@@ -142,7 +143,7 b' def default_config():'
142 config.TerminalTerminalInteractiveShell.term_title = False,
143 config.TerminalTerminalInteractiveShell.term_title = False,
143 config.TerminalInteractiveShell.autocall = 0
144 config.TerminalInteractiveShell.autocall = 0
144 f = tempfile.NamedTemporaryFile(suffix=u'test_hist.sqlite', delete=False)
145 f = tempfile.NamedTemporaryFile(suffix=u'test_hist.sqlite', delete=False)
145 config.HistoryManager.hist_file = f.name
146 config.HistoryManager.hist_file = Path(f.name)
146 f.close()
147 f.close()
147 config.HistoryManager.db_cache_size = 10000
148 config.HistoryManager.db_cache_size = 10000
148 return config
149 return config
General Comments 0
You need to be logged in to leave comments. Login now