From c48d7c3874b6224d19c64870b09d8c51a1d989b5 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 15 Sep 2026 18:10:18 +0200 Subject: [PATCH 1/4] [mysqlclient] Update to 2.3.* Closes: #16390 --- stubs/mysqlclient/METADATA.toml | 2 +- stubs/mysqlclient/MySQLdb/_mysql.pyi | 10 ++++- stubs/mysqlclient/MySQLdb/connections.pyi | 5 ++- stubs/mysqlclient/MySQLdb/cursors.pyi | 54 ++++++++++++----------- 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/stubs/mysqlclient/METADATA.toml b/stubs/mysqlclient/METADATA.toml index 0d734f1277b1..b242844fd810 100644 --- a/stubs/mysqlclient/METADATA.toml +++ b/stubs/mysqlclient/METADATA.toml @@ -1,4 +1,4 @@ -version = "2.2.*" +version = "2.3.*" upstream-repository = "https://github.com/PyMySQL/mysqlclient" [tool.stubtest] diff --git a/stubs/mysqlclient/MySQLdb/_mysql.pyi b/stubs/mysqlclient/MySQLdb/_mysql.pyi index 2ee0b9493565..ca52343a48f7 100644 --- a/stubs/mysqlclient/MySQLdb/_mysql.pyi +++ b/stubs/mysqlclient/MySQLdb/_mysql.pyi @@ -1,6 +1,7 @@ import builtins from _typeshed import Incomplete -from typing_extensions import disjoint_base +from typing import overload +from typing_extensions import deprecated, disjoint_base import MySQLdb._exceptions @@ -48,8 +49,13 @@ class connection: def info(self): ... def insert_id(self): ... def kill(self, *args, **kwargs): ... + def more_results(self) -> bool: ... def next_result(self): ... - def ping(self): ... + @overload + @deprecated("The reconnect parameter of ping() is deprecated.") + def ping(self, reconnect: bool) -> None: ... + @overload + def ping(self) -> None: ... def query(self, query): ... def read_query_result(self): ... def rollback(self): ... diff --git a/stubs/mysqlclient/MySQLdb/connections.pyi b/stubs/mysqlclient/MySQLdb/connections.pyi index c35ccd31689e..2a565269d180 100644 --- a/stubs/mysqlclient/MySQLdb/connections.pyi +++ b/stubs/mysqlclient/MySQLdb/connections.pyi @@ -1,7 +1,7 @@ from _typeshed import Incomplete from re import Pattern from types import TracebackType -from typing import Any, TypeAlias +from typing import Any, Literal, TypeAlias from typing_extensions import LiteralString, Self from . import _mysql, cursors @@ -29,11 +29,12 @@ def numeric_part(s): ... class Connection(_mysql.connection): default_cursor: type[cursors.Cursor] + executemany_fallback: Literal["loop", "multi"] cursorclass: type[cursors.BaseCursor] encoders: Incomplete encoding: str messages: Incomplete - def __init__(self, *args, **kwargs) -> None: ... + def __init__(self, *args, executemany_fallback: Literal["loop", "multi"], **kwargs) -> None: ... def __enter__(self) -> Self: ... def __exit__( self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None diff --git a/stubs/mysqlclient/MySQLdb/cursors.pyi b/stubs/mysqlclient/MySQLdb/cursors.pyi index f0dd10ea95d8..d821ff032f0e 100644 --- a/stubs/mysqlclient/MySQLdb/cursors.pyi +++ b/stubs/mysqlclient/MySQLdb/cursors.pyi @@ -1,7 +1,7 @@ from _typeshed import Incomplete from collections.abc import Iterable from re import Pattern -from typing import TypeAlias +from typing import Literal, Self, TypeAlias from typing_extensions import LiteralString from .connections import _Literal @@ -11,28 +11,20 @@ _Arguments: TypeAlias = dict[str, _Literal] | dict[bytes, _Literal] | Iterable[_ RE_INSERT_VALUES: Pattern[str] class BaseCursor: - from ._exceptions import ( - DatabaseError as DatabaseError, - DataError as DataError, - Error as Error, - IntegrityError as IntegrityError, - InterfaceError as InterfaceError, - InternalError as InternalError, - MySQLError as MySQLError, - NotSupportedError as NotSupportedError, - OperationalError as OperationalError, - ProgrammingError as ProgrammingError, - Warning as Warning, - ) - - max_stmt_length: Incomplete + max_stmt_length: int + max_multi_stmt_length: int + max_multi_stmt_count: int + executemany_fallback: Literal["loop", "multi"] | None connection: Incomplete - description: Incomplete - description_flags: Incomplete + + warning_count: int + description: Incomplete | None + description_flags: Incomplete | None rowcount: int arraysize: int - lastrowid: Incomplete - rownumber: Incomplete + lastrowid: Incomplete | None + rownumber: Incomplete | None + def __init__(self, connection) -> None: ... def close(self) -> None: ... def __enter__(self): ... @@ -44,7 +36,23 @@ class BaseCursor: def mogrify(self, query: str | bytes, args: _Arguments | None = None) -> str: ... def executemany(self, query: LiteralString, args: Iterable[_Arguments]) -> int | None: ... def callproc(self, procname, args=()): ... - def __iter__(self): ... + def __iter__(self) -> Self: ... + def __next__(self): ... + + # These are all deprecated. + from ._exceptions import ( + DatabaseError as DatabaseError, + DataError as DataError, + Error as Error, + IntegrityError as IntegrityError, + InterfaceError as InterfaceError, + InternalError as InternalError, + MySQLError as MySQLError, + NotSupportedError as NotSupportedError, + OperationalError as OperationalError, + ProgrammingError as ProgrammingError, + Warning as Warning, + ) class CursorStoreResultMixIn: rownumber: Incomplete @@ -52,16 +60,12 @@ class CursorStoreResultMixIn: def fetchmany(self, size=None): ... def fetchall(self): ... def scroll(self, value, mode: str = "relative") -> None: ... - def __iter__(self): ... class CursorUseResultMixIn: rownumber: Incomplete def fetchone(self): ... def fetchmany(self, size=None): ... def fetchall(self): ... - def __iter__(self): ... - def next(self): ... - __next__ = next class CursorTupleRowsMixIn: ... class CursorDictRowsMixIn: ... From 986afcec2872624b28a2fd0128f33573beeb8508 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 16:12:52 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stubs/mysqlclient/MySQLdb/_mysql.pyi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stubs/mysqlclient/MySQLdb/_mysql.pyi b/stubs/mysqlclient/MySQLdb/_mysql.pyi index ca52343a48f7..1de55ce47508 100644 --- a/stubs/mysqlclient/MySQLdb/_mysql.pyi +++ b/stubs/mysqlclient/MySQLdb/_mysql.pyi @@ -51,11 +51,13 @@ class connection: def kill(self, *args, **kwargs): ... def more_results(self) -> bool: ... def next_result(self): ... + @overload @deprecated("The reconnect parameter of ping() is deprecated.") def ping(self, reconnect: bool) -> None: ... @overload def ping(self) -> None: ... + def query(self, query): ... def read_query_result(self): ... def rollback(self): ... From afbc743a298bda2bb93f3dd86e57192509311515 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 15 Sep 2026 18:12:41 +0200 Subject: [PATCH 3/4] Add a stubtext allowlist --- stubs/mysqlclient/@tests/stubtest_allowlist.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 stubs/mysqlclient/@tests/stubtest_allowlist.txt diff --git a/stubs/mysqlclient/@tests/stubtest_allowlist.txt b/stubs/mysqlclient/@tests/stubtest_allowlist.txt new file mode 100644 index 000000000000..c22d30fb9a56 --- /dev/null +++ b/stubs/mysqlclient/@tests/stubtest_allowlist.txt @@ -0,0 +1,12 @@ +# Deprecated reexports that are added via __getattr__(). +MySQLdb.cursors.BaseCursor.DataError +MySQLdb.cursors.BaseCursor.DatabaseError +MySQLdb.cursors.BaseCursor.Error +MySQLdb.cursors.BaseCursor.IntegrityError +MySQLdb.cursors.BaseCursor.InterfaceError +MySQLdb.cursors.BaseCursor.InternalError +MySQLdb.cursors.BaseCursor.MySQLError +MySQLdb.cursors.BaseCursor.NotSupportedError +MySQLdb.cursors.BaseCursor.OperationalError +MySQLdb.cursors.BaseCursor.ProgrammingError +MySQLdb.cursors.BaseCursor.Warning From bd676e66b2167d96c6fc0be8edffeafc5e8bec5d Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 15 Sep 2026 18:13:06 +0200 Subject: [PATCH 4/4] Import Self from typing_extensions --- stubs/mysqlclient/MySQLdb/cursors.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stubs/mysqlclient/MySQLdb/cursors.pyi b/stubs/mysqlclient/MySQLdb/cursors.pyi index d821ff032f0e..64f01642bc37 100644 --- a/stubs/mysqlclient/MySQLdb/cursors.pyi +++ b/stubs/mysqlclient/MySQLdb/cursors.pyi @@ -1,8 +1,8 @@ from _typeshed import Incomplete from collections.abc import Iterable from re import Pattern -from typing import Literal, Self, TypeAlias -from typing_extensions import LiteralString +from typing import Literal, TypeAlias +from typing_extensions import LiteralString, Self from .connections import _Literal