Using:
* MySQL-python post-1.2.3 (current checkout [r645] of https://mysql-python.svn.sourceforge.net/svnroot/mysql-python/branches/MySQLdb-1.2/MySQLdb)
* Python 2.7 (vendor package)
* on Fedora 14
Interrupting a query with Ctrl-C should always result in a KeyboardInterrupt exception. But often, the program crashes instead with
"""
Traceback (most recent call last):
File "./kbd-interrupt-crash-manual.py", line 34, in <module>
cursor.close()
File "/home/scratch/src/mysql-python-1.2/MySQLdb/cursors.py", line 75, in close
while self.nextset(): pass
File "/home/scratch/src/mysql-python-1.2/MySQLdb/cursors.py", line 107, in nextset
nr = db.next_result()
_mysql_exceptions.ProgrammingError: (2014, "Commands out of sync; you can't run this command now")
Exception _mysql_exceptions.ProgrammingError: (2014, "Commands out of sync; you can't run this command now") in <bound method="" Cursor.__del__="" of="" <MySQLdb.cursors.Cursor="" object="" at="" 0x2731d10="">> ignored
"""
Sample code (assuming a connection already open):
"""
while True:
cursor = conn.cursor()
try:
cursor.execute("select 1")
cursor.fetchall()
finally:
cursor.close()
"""
Hit Ctrl-C while that loop is running, and odds are pretty good that the script will crash as shown above, rather than with the expected KeyboardInterrupt.
Also, it sometimes fails like this:
"""
Traceback (most recent call last):
File "./kbd-interrupt-crash-manual.py", line 27, in <module>
cursor = conn.cursor()
File "/home/scratch/src/mysql-python-1.2/MySQLdb/connections.py", line 243, in cursor
return (cursorclass or self.cursorclass)(self)
File "/home/scratch/src/mysql-python-1.2/MySQLdb/cursors.py", line 50, in init
def init(self, connection):
KeyboardInterrupt
Exception AttributeError: "'Cursor' object has no attribute 'connection'" in <bound method="" Cursor.__del__="" of="" <MySQLdb.cursors.Cursor="" object="" at="" 0x2233d10="">> ignored
"""
But I suspect that is a different bug.
I'll attach the complete script I'm using to reproduce this. Just run it, wait a second or so, and hit Ctrl-C. Repeat. On my system, I get the ProgrammingError, rather than the expected KeyboardInterrupt, roughly 50% of the time.
script to reproduce the bug manually
The patch I just attached is a naive, and probably inefficient, hack. The big problem is: where else in MySQLdb could be affected by a KeyboardInterrupt? Also, what is the cost of calling db.use_result() when we should just be tearing everything down and getting out as quickly as possible?
Thus, I don't think this is the right fix, but I had to try something.
another approach: defer KeyboardInterrupt exceptions