Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7d934cb

Browse files
mroeschkeCarreau
authored andcommitted
Use weakref finalize to close sqlite.conenctions
1 parent adbfa57 commit 7d934cb

3 files changed

Lines changed: 45 additions & 46 deletions

File tree

IPython/core/history.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import datetime
1111
import os
1212
import re
13+
import weakref
1314

1415

1516
import threading
@@ -322,12 +323,14 @@ def init_db(self) -> None:
322323
"""Connect to the database, and create tables if necessary."""
323324
if not self.enabled:
324325
self.db = DummyDB()
326+
self._finalizer = weakref.finalize(self, lambda db: db.close(), self.db)
325327
return
326328

327329
# use detect_types so that timestamps return datetime objects
328330
kwargs = dict(detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
329331
kwargs.update(self.connection_options)
330332
self.db = sqlite3.connect(str(self.hist_file), **kwargs) # type: ignore [call-overload]
333+
self._finalizer = weakref.finalize(self, lambda db: db.close(), self.db)
331334
with self.db:
332335
self.db.execute(
333336
"""CREATE TABLE IF NOT EXISTS sessions (session integer
@@ -349,10 +352,6 @@ def init_db(self) -> None:
349352
# success! reset corrupt db count
350353
self._corrupt_db_counter = 0
351354

352-
def __del__(self) -> None:
353-
if hasattr(self, "db"):
354-
self.db.close()
355-
356355
def writeout_cache(self) -> None:
357356
"""Overridden by HistoryManager to dump the cache before certain
358357
database lookups."""
@@ -721,7 +720,6 @@ def __init__(
721720
def __del__(self) -> None:
722721
if self.save_thread is not None:
723722
self.save_thread.stop()
724-
HistoryAccessor.__del__(self)
725723

726724
@classmethod
727725
def _stop_thread(cls) -> None:

IPython/core/historyapp.py

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -50,27 +50,26 @@ class HistoryTrim(BaseIPythonApplication):
5050
def start(self):
5151
profile_dir = Path(self.profile_dir.location)
5252
hist_file = profile_dir / "history.sqlite"
53-
con = sqlite3.connect(hist_file)
54-
55-
# Grab the recent history from the current database.
56-
inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
57-
'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
58-
if len(inputs) <= self.keep:
59-
print("There are already at most %d entries in the history database." % self.keep)
60-
print("Not doing anything. Use --keep= argument to keep fewer entries")
61-
return
62-
63-
print("Trimming history to the most recent %d entries." % self.keep)
64-
65-
inputs.pop() # Remove the extra element we got to check the length.
66-
inputs.reverse()
67-
if inputs:
68-
first_session = inputs[0][0]
69-
outputs = list(con.execute('SELECT session, line, output FROM '
70-
'output_history WHERE session >= ?', (first_session,)))
71-
sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
72-
'sessions WHERE session >= ?', (first_session,)))
73-
con.close()
53+
with sqlite3.connect(hist_file) as con:
54+
55+
# Grab the recent history from the current database.
56+
inputs = list(con.execute('SELECT session, line, source, source_raw FROM '
57+
'history ORDER BY session DESC, line DESC LIMIT ?', (self.keep+1,)))
58+
if len(inputs) <= self.keep:
59+
print("There are already at most %d entries in the history database." % self.keep)
60+
print("Not doing anything. Use --keep= argument to keep fewer entries")
61+
return
62+
63+
print("Trimming history to the most recent %d entries." % self.keep)
64+
65+
inputs.pop() # Remove the extra element we got to check the length.
66+
inputs.reverse()
67+
if inputs:
68+
first_session = inputs[0][0]
69+
outputs = list(con.execute('SELECT session, line, output FROM '
70+
'output_history WHERE session >= ?', (first_session,)))
71+
sessions = list(con.execute('SELECT session, start, end, num_cmds, remark FROM '
72+
'sessions WHERE session >= ?', (first_session,)))
7473

7574
# Create the new history database.
7675
new_hist_file = profile_dir / "history.sqlite.new"
@@ -79,26 +78,25 @@ def start(self):
7978
# Make sure we don't interfere with an existing file.
8079
i += 1
8180
new_hist_file = profile_dir / ("history.sqlite.new" + str(i))
82-
new_db = sqlite3.connect(new_hist_file)
83-
new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
84-
primary key autoincrement, start timestamp,
85-
end timestamp, num_cmds integer, remark text)""")
86-
new_db.execute("""CREATE TABLE IF NOT EXISTS history
87-
(session integer, line integer, source text, source_raw text,
88-
PRIMARY KEY (session, line))""")
89-
new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
90-
(session integer, line integer, output text,
91-
PRIMARY KEY (session, line))""")
92-
new_db.commit()
93-
94-
95-
if inputs:
96-
with new_db:
97-
# Add the recent history into the new database.
98-
new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
99-
new_db.executemany('insert into history values (?,?,?,?)', inputs)
100-
new_db.executemany('insert into output_history values (?,?,?)', outputs)
101-
new_db.close()
81+
with sqlite3.connect(new_hist_file) as new_db:
82+
new_db.execute("""CREATE TABLE IF NOT EXISTS sessions (session integer
83+
primary key autoincrement, start timestamp,
84+
end timestamp, num_cmds integer, remark text)""")
85+
new_db.execute("""CREATE TABLE IF NOT EXISTS history
86+
(session integer, line integer, source text, source_raw text,
87+
PRIMARY KEY (session, line))""")
88+
new_db.execute("""CREATE TABLE IF NOT EXISTS output_history
89+
(session integer, line integer, output text,
90+
PRIMARY KEY (session, line))""")
91+
new_db.commit()
92+
93+
94+
if inputs:
95+
with new_db:
96+
# Add the recent history into the new database.
97+
new_db.executemany('insert into sessions values (?,?,?,?,?)', sessions)
98+
new_db.executemany('insert into history values (?,?,?,?)', inputs)
99+
new_db.executemany('insert into output_history values (?,?,?)', outputs)
102100

103101
if self.backup:
104102
i = 1

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,9 @@ ipdoctest_optionflags = [
379379
"ELLIPSIS"
380380
]
381381
asyncio_mode = "strict"
382+
filterwarnings = [
383+
"error::ResourceWarning",
384+
]
382385

383386
[tool.pyright]
384387
pythonPlatform="All"

0 commit comments

Comments
 (0)