Assorted self-contained bug fixes (history sqlite handles on Windows, …)#15255
Merged
Conversation
sqlite3.Connection used as a context manager only commits or rolls back, it does not close the connection. `ipython history trim/clear` therefore still had open handles on history.sqlite when unlinking and renaming it, which fails with PermissionError on Windows and leaves history.sqlite.new* files behind. Wrap both connections in contextlib.closing so they are closed before any file shuffling, and add a regression test running the trim and clear subcommands in a subprocess. Fixes #15241 https://claude.ai/code/session_01AtmUVnQwZfjDBuUzF7TdGh
The test created a HistoryManager backed by a real file but never stopped its HistorySavingThread. The thread briefly holds a strong reference to the manager inside its polling loop, so the instance could survive the gc.collect() in the hmmax fixture teardown, making the instance-leak assertion fail intermittently. Stop the saving thread and close the database like the other tests in this file do, and drop the unreachable `HistoryManager.__max_inst` assignment that name-mangling never applied anyway. Fixes #15161 https://claude.ai/code/session_01AtmUVnQwZfjDBuUzF7TdGh
Honor PEP 263 coding cookies when reading module sources for the autoreload diffing logic, the way the import system does, instead of assuming utf-8. Sources that declare another encoding were read as empty (the UnicodeDecodeError is caught and logged), disabling hot-patching for those modules, and the logged traceback was noisy on the first %load_ext autoreload. The regression test fails with the previous explicit utf-8 reading. Closes #15193 (the original cp1252 crash reported there was already fixed by reading with an explicit encoding, this handles the remaining non-utf-8 sources). https://claude.ai/code/session_01AtmUVnQwZfjDBuUzF7TdGh
inspect_object is not called anywhere in IPython anymore, so registering handlers on it has no effect, and a search of public repositories found no external users (unlike complete_object, which pyflyby, riptable and maiev register completers on, and which is unchanged). Emit a DeprecationWarning through a module __getattr__ so that simply importing the name warns, which also covers consumers that only call .register(). First step towards #15068. https://claude.ai/code/session_01AtmUVnQwZfjDBuUzF7TdGh
xml.etree.ElementTree.ParseError is a SyntaxError subclass that leaves .text set to None; IPython 9.6.0 raised an AssertionError in ListTB._format_exception_only when rendering it. The guard was added as part of #15012, but without a test; this locks the behavior in. The test fails if the None check in _format_exception_only is removed. Closes #15024 https://claude.ai/code/session_01AtmUVnQwZfjDBuUzF7TdGh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A series of independent, self-contained fixes — one issue per commit, pushed separately so every commit gets its own complete
test.ymlrun and is easy to review (and cherry-pick) individually.Commits
Close sqlite connections before replacing history database — fixes history clear/trim fails on Windows: PermissionError on history.sqlite (open SQLite handle blocks unlink) #15241.
sqlite3.Connectionused as a context manager only commits/rolls back, it does not close.ipython history trim/cleartherefore still had open handles onhistory.sqlitewhile unlinking/renaming it, which fails withPermissionErroron Windows and leaveshistory.sqlite.new*debris behind. Both connections are now wrapped incontextlib.closing, and a regression test runs thetrimandclearsubcommands in a subprocess (exercised on Windows CI). (all workflows green on this SHA)Make
test_hist_file_configteardown deterministic — fixes Flaky test - teardown in test_hist_file_config #15161.The test created a
HistoryManagerbacked by a real file but never stopped itsHistorySavingThread; the thread briefly holds a strong reference to the manager inside its polling loop, so the instance could survive thegc.collect()in thehmmaxfixture teardown and trip the instance-leak assertion intermittently (~3/10 Fedora builds). The test now stops the thread and closes the db like the other tests in the file. (all workflows green on this SHA)Use
tokenize.opento read source files in deduperreload — closesUnicodeDecodeErrorindeduperreloadon Windows (first %load_ext autoreload) #15193.Honor PEP 263 coding cookies when reading module sources for the autoreload diffing logic, the way the import system does. (The original cp1252
UnicodeDecodeErrorcrash in that issue was already fixed by reading with an explicit utf-8 encoding; this handles the remaining non-utf-8 sources, which were silently treated as unpatchable with a noisy logged traceback.) The regression test fails with the previous explicit-utf-8 reading.Deprecate
IPython.utils.generics.inspect_object— first step towards deprecated and remove IPython/utils/generics.py #15068.inspect_objectis not called anywhere in IPython anymore and no public external users were found (unlikecomplete_object, which pyflyby/riptable/maiev register completers on, and which is unchanged). TheDeprecationWarningis emitted through a module__getattr__, so simply importing the name warns — covering consumers that only call.register().Add regression test for SyntaxError subclasses without
text— closes AssertionError while rendering traceback in ipython 9.6.0 #15024.xml.etree.ElementTree.ParseErrorleaves.textasNone; 9.6.0 raised anAssertionErrorrendering it. The guard landed with Fix #15011, Exception.text may be None #15012 but had no test; this locks the behavior in (the test fails if theNonecheck inListTB._format_exception_onlyis removed).Notes from triage
_repr_pretty_) could not be reproduced on currentmain: the MRO walk inRepresentationPrinter.prettyfinds parent-class_repr_pretty_(also covered bytest_callability_checkingintests/test_pretty.py). That issue can probably be closed.-P/safe_path drops CWD fromsys.path): analysis done, needs a maintainer decision.sys.flags.safe_pathis currently a hard override inInteractiveShellApp.init_path— even an explicit--no-ignore-cwdcannot restore CWD. If the Fedora use case (-Pin shebangs meaning "keep the script dir off sys.path") should be supported, the minimal fix is to let an explicitly-setignore_cwd=Falsewin oversafe_path; happy to implement that in a follow-up if desired._) not restored as last expression result after deletion when first input is a string #15000, ipython turns all non-zero exit codes to 1 when script ran with "ipython -c script.py" uses sys.exit() #15132, _repr_mimebundle_ ignores NotImplementedError #15154, Can IPython print a warning if unable to open ipython_config.py? #14987, oinspect throws TypeError when parsing incomplete code line involving polars.expr.expr #15072 were considered but already have open PRs (Restore underscore tracking after deletion #15243, fix: preserve sys.exit() exit codes in non-interactive mode #15158, fix: only surface nested repr_mimebundle NotImplementedError #15168, Adding check if file not found and cleanups (#14987) #15032, Fix oinspect TypeError with generic __getattr__ objects; fix test path quoting #15237/Fix oinspect TypeError with generic __getattr__ objects; fix test path quoting #15246), so they are deliberately not duplicated here.https://claude.ai/code/session_01AtmUVnQwZfjDBuUzF7TdGh