https://github.com/python/cpython/commit/22cf28953908840a803851f1b1b0e51f54fa5838
commit: 22cf28953908840a803851f1b1b0e51f54fa5838
branch: 3.13
author: Tan Long <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-06-13T20:40:24+03:00
summary:
[3.13] gh-133439: Fix dot commands with trailing spaces are mistaken for
multi-line sqlite statements in the sqlite3 command-line interface (GH-133440)
(GH-133765)
(cherry picked from commit ebd4881db2e8448b238d8ca2f6fcf331826132dd)
files:
A Misc/NEWS.d/next/Library/2025-05-05-22-11-24.gh-issue-133439.LpmyFz.rst
M Lib/sqlite3/__main__.py
M Lib/test/test_sqlite3/test_cli.py
diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py
index b93b84384a0925..87a80a6f952505 100644
--- a/Lib/sqlite3/__main__.py
+++ b/Lib/sqlite3/__main__.py
@@ -48,17 +48,25 @@ def runsource(self, source, filename="<input>",
symbol="single"):
Return True if more input is needed; buffering is done automatically.
Return False is input is a complete statement ready for execution.
"""
- match source:
- case ".version":
- print(f"{sqlite3.sqlite_version}")
- case ".help":
- print("Enter SQL code and press enter.")
- case ".quit":
- sys.exit(0)
- case _:
- if not sqlite3.complete_statement(source):
- return True
- execute(self._cur, source)
+ if not source or source.isspace():
+ return False
+ if source[0] == ".":
+ match source[1:].strip():
+ case "version":
+ print(f"{sqlite3.sqlite_version}")
+ case "help":
+ print("Enter SQL code and press enter.")
+ case "quit":
+ sys.exit(0)
+ case "":
+ pass
+ case _ as unknown:
+ self.write("Error: unknown command or invalid arguments:"
+ f' "{unknown}".\n')
+ else:
+ if not sqlite3.complete_statement(source):
+ return True
+ execute(self._cur, source)
return False
diff --git a/Lib/test/test_sqlite3/test_cli.py
b/Lib/test/test_sqlite3/test_cli.py
index 303f9e03b5383f..a461328b4ecd05 100644
--- a/Lib/test/test_sqlite3/test_cli.py
+++ b/Lib/test/test_sqlite3/test_cli.py
@@ -4,6 +4,7 @@
from sqlite3.__main__ import main as cli
from test.support.os_helper import TESTFN, unlink
+from test.support.testcase import ExtraAssertions
from test.support import captured_stdout, captured_stderr, captured_stdin
@@ -61,7 +62,7 @@ def test_cli_on_disk_db(self):
self.assertIn("(0,)", out)
-class InteractiveSession(unittest.TestCase):
+class InteractiveSession(unittest.TestCase, ExtraAssertions):
MEMORY_DB_MSG = "Connected to a transient in-memory database"
PS1 = "sqlite> "
PS2 = "... "
@@ -108,6 +109,38 @@ def test_interact_version(self):
self.assertEqual(out.count(self.PS2), 0)
self.assertIn(sqlite3.sqlite_version, out)
+ def test_interact_empty_source(self):
+ out, err = self.run_cli(commands=("", " "))
+ self.assertIn(self.MEMORY_DB_MSG, err)
+ self.assertEndsWith(out, self.PS1)
+ self.assertEqual(out.count(self.PS1), 3)
+ self.assertEqual(out.count(self.PS2), 0)
+
+ def test_interact_dot_commands_unknown(self):
+ out, err = self.run_cli(commands=(".unknown_command", ))
+ self.assertIn(self.MEMORY_DB_MSG, err)
+ self.assertEndsWith(out, self.PS1)
+ self.assertEqual(out.count(self.PS1), 2)
+ self.assertEqual(out.count(self.PS2), 0)
+ self.assertIn("Error", err)
+ # test "unknown_command" is pointed out in the error message
+ self.assertIn("unknown_command", err)
+
+ def test_interact_dot_commands_empty(self):
+ out, err = self.run_cli(commands=("."))
+ self.assertIn(self.MEMORY_DB_MSG, err)
+ self.assertEndsWith(out, self.PS1)
+ self.assertEqual(out.count(self.PS1), 2)
+ self.assertEqual(out.count(self.PS2), 0)
+
+ def test_interact_dot_commands_with_whitespaces(self):
+ out, err = self.run_cli(commands=(".version ", ". version"))
+ self.assertIn(self.MEMORY_DB_MSG, err)
+ self.assertEqual(out.count(sqlite3.sqlite_version + "\n"), 2)
+ self.assertEndsWith(out, self.PS1)
+ self.assertEqual(out.count(self.PS1), 3)
+ self.assertEqual(out.count(self.PS2), 0)
+
def test_interact_valid_sql(self):
out, err = self.run_cli(commands=("SELECT 1;",))
self.assertIn(self.MEMORY_DB_MSG, err)
diff --git
a/Misc/NEWS.d/next/Library/2025-05-05-22-11-24.gh-issue-133439.LpmyFz.rst
b/Misc/NEWS.d/next/Library/2025-05-05-22-11-24.gh-issue-133439.LpmyFz.rst
new file mode 100644
index 00000000000000..e0a3ce98bf7158
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-05-05-22-11-24.gh-issue-133439.LpmyFz.rst
@@ -0,0 +1,2 @@
+Fix dot commands with trailing spaces are mistaken for multi-line SQL
+statements in the sqlite3 command-line interface.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]