Description:
MySQLCursor.execute silently ignores params that are neither list, tuple or dict instead of raising a TypeError, which would be the proper behaviour at this point.
In addition, duck typing or using the abstract base classes in the collections module in favour of explicit type checks would allow direct use of other objects implementing either the sequence or mapping protocol instead of only lists, tuples and dicts.
How to repeat:
Invoke execute with params not being a tuple, list or dict:
cursor.execute('SELECT * FROM my_table WHERE my_table.my_column = %s', SomeObject())
Will raise a ProgrammingError because of the not interpolated '%s'.
Suggested fix:
Raise a TypeError in cursor.py in the else branch of isinstance(params, dict) in line 499.
Replace
isinstance(params, dict)
by
isinstance(params, collections.Sequence)
and
isinstance(params, (list, tuple))
by
isinstance(params, collections.Mapping)
to support user defined sequences and mappings.