While trying to troubleshoot a problem in OpenStack, I ran across a bug in MySQLdb. In some cases, an error can be returned for a query and MySQLdb doesn't raise an exception.
The attached test case shows it off (make sure to change the credentials, and it might be necessary to uncomment the lines to set the lock timeout, or set it in your my.cnf depending how your mysqld was built).
In the good case (without any arguments), it raise an OperationalError after the lock wait timeout exceeded. In the bad case (with any argument), no exception is raised, and the result has missing data (including missing description which ends up confusing SQLAlchemy).
With the attached patch applied, it correctly raises an OperationalError in both cases.
The problem is ultimately that MySQLdb doesn't check if an error occurred if mysql_store_result returns NULL. A NULL result isn't always an error depending on the type of query made, so it's required to check the number of fields. See the documentation for mysql_store_result for more information.
Example test case
Patch to fix bug
I should add that this was tested with a hand-built 1.2.3.
I went to see if this was fixed already, but I couldn't find a repository with more recent code.
The problem with your patch is, you can't just return the exception in that context: The return value has to be an int. However I think it's basically sound (and actually would effectively work most of the time as is) and I've committed a variant of it in rev 655.