Skip to content

Commit

Permalink
IPython/core/history.py: Handle RuntimeError on Thread.start (#14318)
Browse files Browse the repository at this point in the history
On the emscripten (Pyodide), `HistorySavingThread.start` raises
`RuntimeError`.
We handle this exception here.

It also reveals a misplaced `atexit` call, which we also fix here.
  • Loading branch information
Carreau committed Feb 6, 2024
2 parents ce22aa2 + 047ab6e commit 0a3cf8f
Showing 1 changed file with 17 additions and 7 deletions.
24 changes: 17 additions & 7 deletions IPython/core/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,29 @@

import atexit
import datetime
from pathlib import Path
import re
import sqlite3
import threading
from pathlib import Path

from traitlets.config.configurable import LoggingConfigurable
from decorator import decorator
from IPython.utils.decorators import undoc
from IPython.paths import locate_profile
from traitlets import (
Any,
Bool,
Dict,
Instance,
Integer,
List,
TraitError,
Unicode,
Union,
TraitError,
default,
observe,
)
from traitlets.config.configurable import LoggingConfigurable

from IPython.paths import locate_profile
from IPython.utils.decorators import undoc

#-----------------------------------------------------------------------------
# Classes and functions
Expand Down Expand Up @@ -554,7 +555,14 @@ def __init__(self, shell=None, config=None, **traits):

if self.enabled and self.hist_file != ':memory:':
self.save_thread = HistorySavingThread(self)
self.save_thread.start()
try:
self.save_thread.start()
except RuntimeError:
self.log.error(
"Failed to start history saving thread. History will not be saved.",
exc_info=True,
)
self.hist_file = ":memory:"

def _get_hist_file_name(self, profile=None):
"""Get default history file name based on the Shell's profile.
Expand Down Expand Up @@ -880,10 +888,10 @@ def __init__(self, history_manager):
super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread")
self.history_manager = history_manager
self.enabled = history_manager.enabled
atexit.register(self.stop)

@only_when_enabled
def run(self):
atexit.register(self.stop)
# We need a separate db connection per thread:
try:
self.db = sqlite3.connect(
Expand All @@ -900,6 +908,8 @@ def run(self):
except Exception as e:
print(("The history saving thread hit an unexpected error (%s)."
"History will not be written to the database.") % repr(e))
finally:
atexit.unregister(self.stop)

def stop(self):
"""This can be called from the main thread to safely stop this thread.
Expand Down

0 comments on commit 0a3cf8f

Please sign in to comment.