Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
30 changes: 19 additions & 11 deletions 30 Lib/sqlite3/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 if 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] == ".":
Comment thread
serhiy-storchaka marked this conversation as resolved.
match source[1:].strip():
Comment thread
serhiy-storchaka marked this conversation as resolved.
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:"
Comment thread
erlend-aasland marked this conversation as resolved.
f' "{unknown}".\n')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error messages do not end with a '.' e.g.:

Python 3.15.0a0 (heads/main:c81fa2b9cd1, May  8 2025, 16:38:25) [GCC 15.1.1 20250425 (Red Hat 15.1.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> test
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    test
NameError: name 'test' is not defined

else:
if not sqlite3.complete_statement(source):
return True
execute(self._cur, source)
return False


Expand Down
32 changes: 32 additions & 0 deletions 32 Lib/test/test_sqlite3/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix dot commands with trailing spaces are mistaken for multi-line SQL
statements in the sqlite3 command-line interface.
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.