Bug #87815 MySQL Connector methods `fetchone` and `fetchmany` are not PEP 249 compliant
Submitted: 20 Sep 2017 9:36 Modified: 20 Sep 2017 14:40
Reporter: Géry Ogam Email Updates:
Status: Verified Impact on me:
None 
Category:Connector / Python Severity:S2 (Serious)
Version:2.1.6, 8.0.4 OS:Microsoft Windows (10)
Assigned to: CPU Architecture:Any
Tags: MySQL, mysql-connector, PEP, python

[20 Sep 2017 9:36] Géry Ogam
Description:
With [Python 3.6.2](https://www.python.org/downloads/) and [MySQL Connector 2.1.6](https://pypi.python.org/pypi/mysql-connector/2.1.6) package on Windows 10, not calling the `execute` method of a database cursor, or calling it on a *non* `SELECT` statement (`CREATE`, `DROP`, `INSERT`, `DELETE`, `UPDATE`, etc.) yields the following results:

    >>> import mysql.connector
    >>> session = mysql.connector.connect(user = "root", database = "mysql")
    >>> cursor = session.cursor()
    >>> cursor.fetchone()
    >>> cursor.fetchmany()
    []
    >>> cursor.fetchall()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Users\Maggyero\AppData\Local\Programs\Python\Python36-32\lib\site-packages\mysql\connector\cursor.py", line 891, in fetchall
        raise errors.InterfaceError("No result set to fetch from.")
    mysql.connector.errors.InterfaceError: No result set to fetch from.
    >>> cursor.execute("CREATE TABLE test (x INTEGER)")
    >>> cursor.fetchone()
    >>> cursor.fetchmany()
    []
    >>> cursor.fetchall()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Users\Maggyero\AppData\Local\Programs\Python\Python36-32\lib\site-packages\mysql\connector\cursor.py", line 891, in fetchall
        raise errors.InterfaceError("No result set to fetch from.")
    mysql.connector.errors.InterfaceError: No result set to fetch from.

[PEP 249](https://www.python.org/dev/peps/pep-0249/) explicitly states for the `fetchone`, `fetchmany` and `fetchall` methods:

> An Error (or subclass) exception is raised if the previous call to .execute*() did not produce any result set or no call was issued yet.

**So why don't `fetchone` and `fetchmany` raise an exception like `fetchall`?**

How to repeat:
See the description.
[20 Sep 2017 12:32] Umesh Shastry
Hello Géry Ogam,

Thank you for the report and feedback!

Thanks,
Umesh
[20 Sep 2017 14:40] Géry Ogam
Suggested fix:

Copying the first two lines (890 and 891) from the `fetchall` method body in the site-packages\mysql\connector\cursor.py file to the start of the `fetchone` and `fetchmany` methods bodies in the same file resolves the bug:

    def fetchone(self):
    +    if not self._have_unread_result():
    +        raise errors.InterfaceError("No result set to fetch from.")

    def fetchmany(self, size=None):
    +    if not self._have_unread_result():
    +        raise errors.InterfaceError("No result set to fetch from.")