Почему диспетчер контекста MySQLdb Connection не закрывает курсор?

MySQLdbConnections есть элементарный менеджер контекста, который создает курсор навойтилибо откатывается, либо фиксируется навыходи неявно не подавляет исключения. ОтИсточник подключения:

def __enter__(self):
    if self.get_autocommit():
        self.query("BEGIN")
    return self.cursor()

def __exit__(self, exc, value, tb):
    if exc:
        self.rollback()
    else:
        self.commit()

Итак, кто-нибудь знаетЗачем курсор не закрывается при выходе?

Сначала я предположил, что это потому, что закрытие курсора ничего не делает, и что у курсоров есть только метод close в сравнении сPython DB API (см. комментарии кэтот ответ). Однако факт заключается в том, что закрытие курсора прожигает оставшиеся наборы результатов, если таковые имеются, и отключает курсор. Отисточник курсора:

def close(self):
    """Close the cursor. No further queries will be possible."""
    if not self.connection: return
    while self.nextset(): pass
    self.connection = None

Было бы так просто закрыть курсор при выходе, поэтому я должен предположить, что это не было сделано специально. С другой стороны, мы можем видеть, что когда курсор удаляется, он все равно закрывается, поэтому я предполагаю, что сборщик мусора в конечном итоге дойдет до него. Я не знаю много о сборке мусора в Python.

def __del__(self):
    self.close()
    self.errorhandler = None
    self._result = None

Другое предположение состоит в том, что может возникнуть ситуация, когда вы захотите повторно использовать курсор послеwith блок. Но я не могу придумать причину, по которой вам нужно это сделать. Разве вы не можете всегда использовать курсор внутри его контекста и просто использовать отдельный контекст для следующей транзакции?

Чтобы быть очень ясным, этот пример, очевидно, не имеет смысла:

with conn as cursor:
    cursor.execute(select_stmt)

rows = cursor.fetchall()

Так должно быть:

with conn as cursor:
    cursor.execute(select_stmt)
    rows = cursor.fetchall()

Этот пример также не имеет смысла:

# first transaction
with conn as cursor:
    cursor.execute(update_stmt_1)

# second transaction, reusing cursor
try:
    cursor.execute(update_stmt_2)
except:
    conn.rollback()
else:
    conn.commit()

Это должно быть просто:

# first transaction
with conn as cursor:
    cursor.execute(update_stmt_1)

# second transaction, new cursor
with conn as cursor:
    cursor.execute(update_stmt_2)

Опять же, что может быть вредом при закрытии курсора при выходе и какие преимущества дает его не закрывать?

Ответы на вопрос(1)

Ваш ответ на вопрос