##// END OF EJS Templates
Merge pull request #12644 from deep-jkl/fix-pathlib-in-tests
Matthias Bussonnier -
r26187:4967ec2a merge
parent child Browse files
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,17 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,
20 default, observe,
20 Bool,
21 Dict,
22 Instance,
23 Integer,
24 List,
25 Unicode,
26 Union,
27 TraitError,
28 default,
29 observe,
21 )
30 )
22
31
23 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
@@ -27,17 +36,17 b' from traitlets import ('
27 @undoc
36 @undoc
28 class DummyDB(object):
37 class DummyDB(object):
29 """Dummy DB that will act as a black hole for history.
38 """Dummy DB that will act as a black hole for history.
30
39
31 Only used in the absence of sqlite"""
40 Only used in the absence of sqlite"""
32 def execute(*args, **kwargs):
41 def execute(*args, **kwargs):
33 return []
42 return []
34
43
35 def commit(self, *args, **kwargs):
44 def commit(self, *args, **kwargs):
36 pass
45 pass
37
46
38 def __enter__(self, *args, **kwargs):
47 def __enter__(self, *args, **kwargs):
39 pass
48 pass
40
49
41 def __exit__(self, *args, **kwargs):
50 def __exit__(self, *args, **kwargs):
42 pass
51 pass
43
52
@@ -73,17 +82,18 b' def catch_corrupt_db(f, self, *a, **kw):'
73 if self._corrupt_db_counter > self._corrupt_db_limit:
82 if self._corrupt_db_counter > self._corrupt_db_limit:
74 self.hist_file = ':memory:'
83 self.hist_file = ':memory:'
75 self.log.error("Failed to load history too many times, history will not be saved.")
84 self.log.error("Failed to load history too many times, history will not be saved.")
76 elif os.path.isfile(self.hist_file):
85 elif self.hist_file.is_file():
77 # move the file out of the way
86 # move the file out of the way
78 base, ext = os.path.splitext(self.hist_file)
87 base = str(self.hist_file.parent / self.hist_file.stem)
79 size = os.stat(self.hist_file).st_size
88 ext = self.hist_file.suffix
89 size = self.hist_file.stat().st_size
80 if size >= _SAVE_DB_SIZE:
90 if size >= _SAVE_DB_SIZE:
81 # if there's significant content, avoid clobbering
91 # if there's significant content, avoid clobbering
82 now = datetime.datetime.now().isoformat().replace(':', '.')
92 now = datetime.datetime.now().isoformat().replace(':', '.')
83 newpath = base + '-corrupt-' + now + ext
93 newpath = base + '-corrupt-' + now + ext
84 # don't clobber previous corrupt backups
94 # don't clobber previous corrupt backups
85 for i in range(100):
95 for i in range(100):
86 if not os.path.isfile(newpath):
96 if not Path(newpath).exists():
87 break
97 break
88 else:
98 else:
89 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
99 newpath = base + '-corrupt-' + now + (u'-%i' % i) + ext
@@ -91,14 +101,15 b' def catch_corrupt_db(f, self, *a, **kw):'
91 # not much content, possibly empty; don't worry about clobbering
101 # not much content, possibly empty; don't worry about clobbering
92 # maybe we should just delete it?
102 # maybe we should just delete it?
93 newpath = base + '-corrupt' + ext
103 newpath = base + '-corrupt' + ext
94 os.rename(self.hist_file, newpath)
104 self.hist_file.rename(newpath)
95 self.log.error("History file was moved to %s and a new file created.", newpath)
105 self.log.error("History file was moved to %s and a new file created.", newpath)
96 self.init_db()
106 self.init_db()
97 return []
107 return []
98 else:
108 else:
99 # Failed with :memory:, something serious is wrong
109 # Failed with :memory:, something serious is wrong
100 raise
110 raise
101
111
112
102 class HistoryAccessorBase(LoggingConfigurable):
113 class HistoryAccessorBase(LoggingConfigurable):
103 """An abstract class for History Accessors """
114 """An abstract class for History Accessors """
104
115
@@ -118,7 +129,7 b' class HistoryAccessorBase(LoggingConfigurable):'
118
129
119 class HistoryAccessor(HistoryAccessorBase):
130 class HistoryAccessor(HistoryAccessorBase):
120 """Access the history database without adding to it.
131 """Access the history database without adding to it.
121
132
122 This is intended for use by standalone history tools. IPython shells use
133 This is intended for use by standalone history tools. IPython shells use
123 HistoryManager, below, which is a subclass of this."""
134 HistoryManager, below, which is a subclass of this."""
124
135
@@ -128,37 +139,39 b' class HistoryAccessor(HistoryAccessorBase):'
128 _corrupt_db_limit = 2
139 _corrupt_db_limit = 2
129
140
130 # String holding the path to the history file
141 # String holding the path to the history file
131 hist_file = Unicode(
142 hist_file = Union(
143 [Instance(Path), Unicode()],
132 help="""Path to file to use for SQLite history database.
144 help="""Path to file to use for SQLite history database.
133
145
134 By default, IPython will put the history database in the IPython
146 By default, IPython will put the history database in the IPython
135 profile directory. If you would rather share one history among
147 profile directory. If you would rather share one history among
136 profiles, you can set this value in each, so that they are consistent.
148 profiles, you can set this value in each, so that they are consistent.
137
149
138 Due to an issue with fcntl, SQLite is known to misbehave on some NFS
150 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
151 mounts. If you see IPython hanging, try setting this to something on a
140 local disk, e.g::
152 local disk, e.g::
141
153
142 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
154 ipython --HistoryManager.hist_file=/tmp/ipython_hist.sqlite
143
155
144 you can also use the specific value `:memory:` (including the colon
156 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.
157 at both end but not the back ticks), to avoid creating an history file.
146
158
147 """).tag(config=True)
159 """,
148
160 ).tag(config=True)
161
149 enabled = Bool(True,
162 enabled = Bool(True,
150 help="""enable the SQLite history
163 help="""enable the SQLite history
151
164
152 set enabled=False to disable the SQLite history,
165 set enabled=False to disable the SQLite history,
153 in which case there will be no stored history, no SQLite connection,
166 in which case there will be no stored history, no SQLite connection,
154 and no background saving thread. This may be necessary in some
167 and no background saving thread. This may be necessary in some
155 threaded environments where IPython is embedded.
168 threaded environments where IPython is embedded.
156 """
169 """
157 ).tag(config=True)
170 ).tag(config=True)
158
171
159 connection_options = Dict(
172 connection_options = Dict(
160 help="""Options for configuring the SQLite connection
173 help="""Options for configuring the SQLite connection
161
174
162 These options are passed as keyword args to sqlite3.connect
175 These options are passed as keyword args to sqlite3.connect
163 when establishing database connections.
176 when establishing database connections.
164 """
177 """
@@ -175,10 +188,10 b' class HistoryAccessor(HistoryAccessorBase):'
175 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
188 msg = "%s.db must be sqlite3 Connection or DummyDB, not %r" % \
176 (self.__class__.__name__, new)
189 (self.__class__.__name__, new)
177 raise TraitError(msg)
190 raise TraitError(msg)
178
191
179 def __init__(self, profile='default', hist_file=u'', **traits):
192 def __init__(self, profile="default", hist_file="", **traits):
180 """Create a new history accessor.
193 """Create a new history accessor.
181
194
182 Parameters
195 Parameters
183 ----------
196 ----------
184 profile : str
197 profile : str
@@ -196,37 +209,39 b' class HistoryAccessor(HistoryAccessorBase):'
196 # set by config
209 # set by config
197 if hist_file:
210 if hist_file:
198 self.hist_file = hist_file
211 self.hist_file = hist_file
199
212
200 if self.hist_file == u'':
213 try:
214 self.hist_file
215 except TraitError:
201 # No one has set the hist_file, yet.
216 # No one has set the hist_file, yet.
202 self.hist_file = self._get_hist_file_name(profile)
217 self.hist_file = self._get_hist_file_name(profile)
203
218
204 self.init_db()
219 self.init_db()
205
220
206 def _get_hist_file_name(self, profile='default'):
221 def _get_hist_file_name(self, profile='default'):
207 """Find the history file for the given profile name.
222 """Find the history file for the given profile name.
208
223
209 This is overridden by the HistoryManager subclass, to use the shell's
224 This is overridden by the HistoryManager subclass, to use the shell's
210 active profile.
225 active profile.
211
226
212 Parameters
227 Parameters
213 ----------
228 ----------
214 profile : str
229 profile : str
215 The name of a profile which has a history file.
230 The name of a profile which has a history file.
216 """
231 """
217 return os.path.join(locate_profile(profile), 'history.sqlite')
232 return Path(locate_profile(profile)) / "history.sqlite"
218
233
219 @catch_corrupt_db
234 @catch_corrupt_db
220 def init_db(self):
235 def init_db(self):
221 """Connect to the database, and create tables if necessary."""
236 """Connect to the database, and create tables if necessary."""
222 if not self.enabled:
237 if not self.enabled:
223 self.db = DummyDB()
238 self.db = DummyDB()
224 return
239 return
225
240
226 # use detect_types so that timestamps return datetime objects
241 # use detect_types so that timestamps return datetime objects
227 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
242 kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
228 kwargs.update(self.connection_options)
243 kwargs.update(self.connection_options)
229 self.db = sqlite3.connect(self.hist_file, **kwargs)
244 self.db = sqlite3.connect(str(self.hist_file), **kwargs)
230 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
245 self.db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
231 primary key autoincrement, start timestamp,
246 primary key autoincrement, start timestamp,
232 end timestamp, num_cmds integer, remark text)""")
247 end timestamp, num_cmds integer, remark text)""")
@@ -290,7 +305,7 b' class HistoryAccessor(HistoryAccessorBase):'
290
305
291 Returns
306 Returns
292 -------
307 -------
293
308
294 session_id : int
309 session_id : int
295 Session ID number
310 Session ID number
296 start : datetime
311 start : datetime
@@ -308,7 +323,7 b' class HistoryAccessor(HistoryAccessorBase):'
308 @catch_corrupt_db
323 @catch_corrupt_db
309 def get_last_session_id(self):
324 def get_last_session_id(self):
310 """Get the last session ID currently in the database.
325 """Get the last session ID currently in the database.
311
326
312 Within IPython, this should be the same as the value stored in
327 Within IPython, this should be the same as the value stored in
313 :attr:`HistoryManager.session_number`.
328 :attr:`HistoryManager.session_number`.
314 """
329 """
@@ -384,7 +399,7 b' class HistoryAccessor(HistoryAccessorBase):'
384 if n is not None:
399 if n is not None:
385 return reversed(list(cur))
400 return reversed(list(cur))
386 return cur
401 return cur
387
402
388 @catch_corrupt_db
403 @catch_corrupt_db
389 def get_range(self, session, start=1, stop=None, raw=True,output=False):
404 def get_range(self, session, start=1, stop=None, raw=True,output=False):
390 """Retrieve input by session.
405 """Retrieve input by session.
@@ -461,7 +476,7 b' class HistoryManager(HistoryAccessor):'
461 @default('dir_hist')
476 @default('dir_hist')
462 def _dir_hist_default(self):
477 def _dir_hist_default(self):
463 try:
478 try:
464 return [os.getcwd()]
479 return [Path.cwd()]
465 except OSError:
480 except OSError:
466 return []
481 return []
467
482
@@ -473,7 +488,7 b' class HistoryManager(HistoryAccessor):'
473
488
474 # The number of the current session in the history database
489 # The number of the current session in the history database
475 session_number = Integer()
490 session_number = Integer()
476
491
477 db_log_output = Bool(False,
492 db_log_output = Bool(False,
478 help="Should the history database include output? (default: no)"
493 help="Should the history database include output? (default: no)"
479 ).tag(config=True)
494 ).tag(config=True)
@@ -484,12 +499,12 b' class HistoryManager(HistoryAccessor):'
484 # The input and output caches
499 # The input and output caches
485 db_input_cache = List()
500 db_input_cache = List()
486 db_output_cache = List()
501 db_output_cache = List()
487
502
488 # History saving in separate thread
503 # History saving in separate thread
489 save_thread = Instance('IPython.core.history.HistorySavingThread',
504 save_thread = Instance('IPython.core.history.HistorySavingThread',
490 allow_none=True)
505 allow_none=True)
491 save_flag = Instance(threading.Event, allow_none=True)
506 save_flag = Instance(threading.Event, allow_none=True)
492
507
493 # Private interface
508 # Private interface
494 # Variables used to store the three last inputs from the user. On each new
509 # 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
510 # history update, we populate the user's namespace with these, shifted as
@@ -513,37 +528,37 b' class HistoryManager(HistoryAccessor):'
513 self.save_flag = threading.Event()
528 self.save_flag = threading.Event()
514 self.db_input_cache_lock = threading.Lock()
529 self.db_input_cache_lock = threading.Lock()
515 self.db_output_cache_lock = threading.Lock()
530 self.db_output_cache_lock = threading.Lock()
516
531
517 try:
532 try:
518 self.new_session()
533 self.new_session()
519 except sqlite3.OperationalError:
534 except sqlite3.OperationalError:
520 self.log.error("Failed to create history session in %s. History will not be saved.",
535 self.log.error("Failed to create history session in %s. History will not be saved.",
521 self.hist_file, exc_info=True)
536 self.hist_file, exc_info=True)
522 self.hist_file = ':memory:'
537 self.hist_file = ':memory:'
523
538
524 if self.enabled and self.hist_file != ':memory:':
539 if self.enabled and self.hist_file != ':memory:':
525 self.save_thread = HistorySavingThread(self)
540 self.save_thread = HistorySavingThread(self)
526 self.save_thread.start()
541 self.save_thread.start()
527
542
528 def _get_hist_file_name(self, profile=None):
543 def _get_hist_file_name(self, profile=None):
529 """Get default history file name based on the Shell's profile.
544 """Get default history file name based on the Shell's profile.
530
545
531 The profile parameter is ignored, but must exist for compatibility with
546 The profile parameter is ignored, but must exist for compatibility with
532 the parent class."""
547 the parent class."""
533 profile_dir = self.shell.profile_dir.location
548 profile_dir = self.shell.profile_dir.location
534 return os.path.join(profile_dir, 'history.sqlite')
549 return Path(profile_dir) / "history.sqlite"
535
550
536 @only_when_enabled
551 @only_when_enabled
537 def new_session(self, conn=None):
552 def new_session(self, conn=None):
538 """Get a new session number."""
553 """Get a new session number."""
539 if conn is None:
554 if conn is None:
540 conn = self.db
555 conn = self.db
541
556
542 with conn:
557 with conn:
543 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
558 cur = conn.execute("""INSERT INTO sessions VALUES (NULL, ?, NULL,
544 NULL, "") """, (datetime.datetime.now(),))
559 NULL, "") """, (datetime.datetime.now(),))
545 self.session_number = cur.lastrowid
560 self.session_number = cur.lastrowid
546
561
547 def end_session(self):
562 def end_session(self):
548 """Close the database session, filling in the end time and line count."""
563 """Close the database session, filling in the end time and line count."""
549 self.writeout_cache()
564 self.writeout_cache()
@@ -552,20 +567,20 b' class HistoryManager(HistoryAccessor):'
552 session==?""", (datetime.datetime.now(),
567 session==?""", (datetime.datetime.now(),
553 len(self.input_hist_parsed)-1, self.session_number))
568 len(self.input_hist_parsed)-1, self.session_number))
554 self.session_number = 0
569 self.session_number = 0
555
570
556 def name_session(self, name):
571 def name_session(self, name):
557 """Give the current session a name in the history database."""
572 """Give the current session a name in the history database."""
558 with self.db:
573 with self.db:
559 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
574 self.db.execute("UPDATE sessions SET remark=? WHERE session==?",
560 (name, self.session_number))
575 (name, self.session_number))
561
576
562 def reset(self, new_session=True):
577 def reset(self, new_session=True):
563 """Clear the session history, releasing all object references, and
578 """Clear the session history, releasing all object references, and
564 optionally open a new session."""
579 optionally open a new session."""
565 self.output_hist.clear()
580 self.output_hist.clear()
566 # The directory history can't be completely empty
581 # The directory history can't be completely empty
567 self.dir_hist[:] = [os.getcwd()]
582 self.dir_hist[:] = [Path.cwd()]
568
583
569 if new_session:
584 if new_session:
570 if self.session_number:
585 if self.session_number:
571 self.end_session()
586 self.end_session()
@@ -588,7 +603,7 b' class HistoryManager(HistoryAccessor):'
588
603
589 Returns
604 Returns
590 -------
605 -------
591
606
592 session_id : int
607 session_id : int
593 Session ID number
608 Session ID number
594 start : datetime
609 start : datetime
@@ -609,7 +624,7 b' class HistoryManager(HistoryAccessor):'
609 """Get input and output history from the current session. Called by
624 """Get input and output history from the current session. Called by
610 get_range, and takes similar parameters."""
625 get_range, and takes similar parameters."""
611 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
626 input_hist = self.input_hist_raw if raw else self.input_hist_parsed
612
627
613 n = len(input_hist)
628 n = len(input_hist)
614 if start < 0:
629 if start < 0:
615 start += n
630 start += n
@@ -617,17 +632,17 b' class HistoryManager(HistoryAccessor):'
617 stop = n
632 stop = n
618 elif stop < 0:
633 elif stop < 0:
619 stop += n
634 stop += n
620
635
621 for i in range(start, stop):
636 for i in range(start, stop):
622 if output:
637 if output:
623 line = (input_hist[i], self.output_hist_reprs.get(i))
638 line = (input_hist[i], self.output_hist_reprs.get(i))
624 else:
639 else:
625 line = input_hist[i]
640 line = input_hist[i]
626 yield (0, i, line)
641 yield (0, i, line)
627
642
628 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
643 def get_range(self, session=0, start=1, stop=None, raw=True,output=False):
629 """Retrieve input by session.
644 """Retrieve input by session.
630
645
631 Parameters
646 Parameters
632 ----------
647 ----------
633 session : int
648 session : int
@@ -645,7 +660,7 b' class HistoryManager(HistoryAccessor):'
645 objects for the current session, or text reprs from previous
660 objects for the current session, or text reprs from previous
646 sessions if db_log_output was enabled at the time. Where no output
661 sessions if db_log_output was enabled at the time. Where no output
647 is found, None is used.
662 is found, None is used.
648
663
649 Returns
664 Returns
650 -------
665 -------
651 entries
666 entries
@@ -709,7 +724,7 b' class HistoryManager(HistoryAccessor):'
709 '_ii': self._ii,
724 '_ii': self._ii,
710 '_iii': self._iii,
725 '_iii': self._iii,
711 new_i : self._i00 }
726 new_i : self._i00 }
712
727
713 if self.shell is not None:
728 if self.shell is not None:
714 self.shell.push(to_main, interactive=False)
729 self.shell.push(to_main, interactive=False)
715
730
@@ -797,8 +812,9 b' class HistorySavingThread(threading.Thread):'
797 def run(self):
812 def run(self):
798 # We need a separate db connection per thread:
813 # We need a separate db connection per thread:
799 try:
814 try:
800 self.db = sqlite3.connect(self.history_manager.hist_file,
815 self.db = sqlite3.connect(
801 **self.history_manager.connection_options
816 str(self.history_manager.hist_file),
817 **self.history_manager.connection_options
802 )
818 )
803 while True:
819 while True:
804 self.history_manager.save_flag.wait()
820 self.history_manager.save_flag.wait()
@@ -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