Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-PyMySQL for openSUSE:Factory 
checked in at 2025-09-30 17:41:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-PyMySQL (Old)
 and      /work/SRC/openSUSE:Factory/.python-PyMySQL.new.11973 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-PyMySQL"

Tue Sep 30 17:41:28 2025 rev:24 rq:1308066 version:1.1.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-PyMySQL/python-PyMySQL.changes    
2025-04-29 16:42:47.812279924 +0200
+++ /work/SRC/openSUSE:Factory/.python-PyMySQL.new.11973/python-PyMySQL.changes 
2025-09-30 17:43:23.387788270 +0200
@@ -1,0 +2,16 @@
+Mon Sep 29 21:06:17 UTC 2025 - Dirk Müller <[email protected]>
+
+- update to 1.1.2:
+  * Prevent UnboundLocalError in very rare situation.
+  * Close underlying `SocketIO` soon when Connection is closed
+    for PyPy.
+  * Fix importing PyMySQL fail on CPython 3.13 when
+    `getpass.getuser()` raises OSEError.
+  * Make charset name "utf8" case insensitive.
+  * `Connection.kill()` uses `KILL` query instead of
+    `COM_KILL`command to support MySQL 8.4.
+  * Fix SSL error on CPython 3.13 caused by strict TLS default
+    setting. https://github.com/PyMySQL/PyMySQL/pull/1198
+  * Fix auth switch request handling.
+
+-------------------------------------------------------------------

Old:
----
  PyMySQL-1.1.1.tar.gz

New:
----
  PyMySQL-1.1.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-PyMySQL.spec ++++++
--- /var/tmp/diff_new_pack.AWsu6s/_old  2025-09-30 17:43:24.407831855 +0200
+++ /var/tmp/diff_new_pack.AWsu6s/_new  2025-09-30 17:43:24.407831855 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-PyMySQL
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -25,7 +25,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-PyMySQL
-Version:        1.1.1
+Version:        1.1.2
 Release:        0
 Summary:        Pure Python MySQL Driver
 License:        MIT

++++++ PyMySQL-1.1.1.tar.gz -> PyMySQL-1.1.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/.coveragerc 
new/PyMySQL-1.1.2/.coveragerc
--- old/PyMySQL-1.1.1/.coveragerc       2024-05-21 13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/.coveragerc       2025-08-24 14:53:42.000000000 +0200
@@ -2,6 +2,7 @@
 branch = True
 source =
     pymysql
+    tests
 omit = pymysql/tests/*
        pymysql/tests/thirdparty/test_MySQLdb/*
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/.github/workflows/codeql-analysis.yml 
new/PyMySQL-1.1.2/.github/workflows/codeql-analysis.yml
--- old/PyMySQL-1.1.1/.github/workflows/codeql-analysis.yml     2024-05-21 
13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/.github/workflows/codeql-analysis.yml     1970-01-01 
01:00:00.000000000 +0100
@@ -1,62 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL"
-
-on:
-  push:
-    branches: [ main ]
-  pull_request:
-    # The branches below must be a subset of the branches above
-    branches: [ main ]
-  schedule:
-    - cron: '34 7 * * 2'
-
-jobs:
-  analyze:
-    name: Analyze
-    runs-on: ubuntu-latest
-
-    strategy:
-      fail-fast: false
-
-    steps:
-    - name: Checkout repository
-      uses: actions/checkout@v4
-
-    # Initializes the CodeQL tools for scanning.
-    - name: Initialize CodeQL
-      uses: github/codeql-action/init@v3
-      with:
-        languages: "python"
-        # If you wish to specify custom queries, you can do so here or in a 
config file.
-        # By default, queries listed here will override any specified in a 
config file.
-        # Prefix the list here with "+" to use these queries and those in the 
config file.
-        # queries: ./path/to/local/query, your-org/your-repo/queries@main
-
-    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
-    # If this step fails, then you should remove it and run the build manually 
(see below)
-    - name: Autobuild
-      uses: github/codeql-action/autobuild@v3
-
-    # ℹ️ Command-line programs to run using the OS shell.
-    # 📚 https://git.io/JvXDl
-
-    # ✏️ If the Autobuild fails above, remove it and uncomment the following 
three lines
-    #    and modify them (or add more) to build your code if your project
-    #    uses a compiled language
-
-    #- run: |
-    #   make bootstrap
-    #   make release
-
-    - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/PyMySQL-1.1.1/.github/workflows/codesee-arch-diagram.yml 
new/PyMySQL-1.1.2/.github/workflows/codesee-arch-diagram.yml
--- old/PyMySQL-1.1.1/.github/workflows/codesee-arch-diagram.yml        
2024-05-21 13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/.github/workflows/codesee-arch-diagram.yml        
1970-01-01 01:00:00.000000000 +0100
@@ -1,23 +0,0 @@
-# This workflow was added by CodeSee. Learn more at https://codesee.io/
-# This is v2.0 of this workflow file
-on:
-  push:
-    branches:
-      - main
-  pull_request_target:
-    types: [opened, synchronize, reopened]
-
-name: CodeSee
-
-permissions: read-all
-
-jobs:
-  codesee:
-    runs-on: ubuntu-latest
-    continue-on-error: true
-    name: Analyze the repo with CodeSee
-    steps:
-      - uses: Codesee-io/codesee-action@v2
-        with:
-          codesee-token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }}
-          codesee-url: https://app.codesee.io
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/.github/workflows/lint.yaml 
new/PyMySQL-1.1.2/.github/workflows/lint.yaml
--- old/PyMySQL-1.1.1/.github/workflows/lint.yaml       2024-05-21 
13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/.github/workflows/lint.yaml       2025-08-24 
14:53:42.000000000 +0200
@@ -13,13 +13,12 @@
   lint:
     runs-on: ubuntu-latest
     steps:
-      - name: checkout
-        uses: actions/checkout@v4
+      - uses: actions/checkout@v4
 
-      - name: lint
-        uses: chartboost/ruff-action@v1
+      - uses: astral-sh/ruff-action@v3
+
+      - name: format
+        run: ruff format --diff
 
-      - name: check format
-        uses: chartboost/ruff-action@v1
-        with:
-          args: "format --diff"
+      - name: lint
+        run: ruff check --diff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/.github/workflows/lock.yml 
new/PyMySQL-1.1.2/.github/workflows/lock.yml
--- old/PyMySQL-1.1.1/.github/workflows/lock.yml        2024-05-21 
13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/.github/workflows/lock.yml        1970-01-01 
01:00:00.000000000 +0100
@@ -1,17 +0,0 @@
-name: 'Lock Threads'
-
-on:
-  schedule:
-    - cron: '30 9 * * 1'
-
-permissions:
-  issues: write
-  pull-requests: write
-
-jobs:
-  lock-threads:
-    if: github.repository == 'PyMySQL/PyMySQL'
-    runs-on: ubuntu-latest
-    steps:
-      - uses: dessant/lock-threads@v5
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/.github/workflows/test.yaml 
new/PyMySQL-1.1.2/.github/workflows/test.yaml
--- old/PyMySQL-1.1.1/.github/workflows/test.yaml       2024-05-21 
13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/.github/workflows/test.yaml       2025-08-24 
14:53:42.000000000 +0200
@@ -18,30 +18,37 @@
       fail-fast: false
       matrix:
         include:
-          - db: "mariadb:10.4"
-            py: "3.8"
+          - db: "mariadb:12"  # rolling release
+            py: "3.13"
+            # pynacl 1.5 doesn't support Python 3.14 yet.
+            # 
https://github.com/pyca/pynacl/commit/d33028e43b814615a33e231925eaddb0f679fa2b
 
-          - db: "mariadb:10.5"
-            py: "3.7"
+          - db: "mariadb:11.8"
+            py: "3.12"
 
-          - db: "mariadb:10.6"
+          - db: "mariadb:11.4"
             py: "3.11"
 
-          - db: "mariadb:10.6"
-            py: "3.12"
+          - db: "mariadb:10.11"
+            py: "3.10"
 
-          - db: "mariadb:lts"
+          - db: "mariadb:10.6"
             py: "3.9"
 
-          - db: "mysql:5.7"
-            py: "pypy-3.8"
-
           - db: "mysql:8.0"
+            py: "pypy3.11"
+            mysql_auth: true
+
+          - db: "mysql:9"
+            py: "3.14"
+            mysql_auth: true
+
+          - db: "mysql:8.4"
             py: "3.9"
             mysql_auth: true
 
-          - db: "mysql:8.0"
-            py: "3.10"
+          - db: "mysql:5.7"
+            py: "3.9"
 
     services:
       mysql:
@@ -56,7 +63,7 @@
           - /run/mysqld:/run/mysqld
 
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
 
       - name: Workaround MySQL container permissions
         if: startsWith(matrix.db, 'mysql')
@@ -106,4 +113,4 @@
 
       - name: Upload coverage reports to Codecov
         if: github.repository == 'PyMySQL/PyMySQL'
-        uses: codecov/codecov-action@v4
+        uses: codecov/codecov-action@v5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/CHANGELOG.md 
new/PyMySQL-1.1.2/CHANGELOG.md
--- old/PyMySQL-1.1.1/CHANGELOG.md      2024-05-21 13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/CHANGELOG.md      2025-08-24 14:53:42.000000000 +0200
@@ -7,6 +7,19 @@
 * `db` and `passwd` will emit DeprecationWarning in v1.2. See #933.
 * `Connection.ping(reconnect)` change the default to not reconnect.
 
+## v1.1.2
+
+Release date: 2025-08-24
+
+* Prevent UnboundLocalError in very rare situation. 
https://github.com/PyMySQL/PyMySQL/pull/1174
+* Close underlying `SocketIO` soon when Connection is closed for PyPy. 
https://github.com/PyMySQL/PyMySQL/issues/1183
+* Fix importing PyMySQL fail on CPython 3.13 when `getpass.getuser()` raises 
OSEError. https://github.com/PyMySQL/PyMySQL/pull/1190
+* Make charset name "utf8" case insensitive. 
https://github.com/PyMySQL/PyMySQL/pull/1195
+* `Connection.kill()` uses `KILL` query instead of `COM_KILL`command to 
support MySQL 8.4. https://github.com/PyMySQL/PyMySQL/pull/1197
+* Fix SSL error on CPython 3.13 caused by strict TLS default setting. 
https://github.com/PyMySQL/PyMySQL/pull/1198
+* Fix auth switch request handling. 
https://github.com/PyMySQL/PyMySQL/pull/1200
+
+
 ## v1.1.1
 
 Release date: 2024-05-21
@@ -21,6 +34,7 @@
 
 * Prohibit dict parameter for `Cursor.execute()`. It didn't produce valid SQL
   and might cause SQL injection. (CVE-2024-36039)
+* Added ssl_key_password param. #1145
 
 ## v1.1.0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/README.md new/PyMySQL-1.1.2/README.md
--- old/PyMySQL-1.1.1/README.md 2024-05-21 13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/README.md 2025-08-24 14:53:42.000000000 +0200
@@ -1,19 +1,20 @@
 [![Documentation 
Status](https://readthedocs.org/projects/pymysql/badge/?version=latest)](https://pymysql.readthedocs.io/)
 
[![codecov](https://codecov.io/gh/PyMySQL/PyMySQL/branch/main/graph/badge.svg?token=ppEuaNXBW4)](https://codecov.io/gh/PyMySQL/PyMySQL)
+[![Ask 
DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/PyMySQL/PyMySQL)
 
 # PyMySQL
 
-This package contains a pure-Python MySQL client library, based on [PEP
-249](https://www.python.org/dev/peps/pep-0249/).
+This package contains a pure-Python MySQL and MariaDB client library, based on
+[PEP 249](https://www.python.org/dev/peps/pep-0249/).
 
 ## Requirements
 
 - Python -- one of the following:
-  - [CPython](https://www.python.org/) : 3.7 and newer
+  - [CPython](https://www.python.org/) : 3.9 and newer
   - [PyPy](https://pypy.org/) : Latest 3.x version
 - MySQL Server -- one of the following:
-  - [MySQL](https://www.mysql.com/) \>= 5.7
-  - [MariaDB](https://mariadb.org/) \>= 10.4
+  - [MySQL](https://www.mysql.com/) LTS versions
+  - [MariaDB](https://mariadb.org/) LTS versions
 
 ## Installation
 
@@ -92,6 +93,7 @@
 
 - DB-API 2.0: <https://www.python.org/dev/peps/pep-0249/>
 - MySQL Reference Manuals: <https://dev.mysql.com/doc/>
+- Getting Help With MariaDB 
<https://mariadb.com/kb/en/getting-help-with-mariadb/>
 - MySQL client/server protocol:
   <https://dev.mysql.com/doc/internals/en/client-server-protocol.html>
 - "Connector" channel in MySQL Community Slack:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/docs/requirements.txt 
new/PyMySQL-1.1.2/docs/requirements.txt
--- old/PyMySQL-1.1.1/docs/requirements.txt     2024-05-21 13:02:25.000000000 
+0200
+++ new/PyMySQL-1.1.2/docs/requirements.txt     2025-08-24 14:53:42.000000000 
+0200
@@ -1,2 +1,2 @@
-sphinx~=7.2
-sphinx-rtd-theme~=2.0.0
+sphinx~=8.0
+sphinx-rtd-theme~=3.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/docs/source/user/development.rst 
new/PyMySQL-1.1.2/docs/source/user/development.rst
--- old/PyMySQL-1.1.1/docs/source/user/development.rst  2024-05-21 
13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/docs/source/user/development.rst  2025-08-24 
14:53:42.000000000 +0200
@@ -28,7 +28,7 @@
     $ cp ci/database.json pymysql/tests/databases.json
     $ $EDITOR pymysql/tests/databases.json
 
-To run all the tests, execute the script ``runtests.py``::
+To run all the tests, you can use pytest::
 
-    $ pip install pytest
+    $ pip install -r requirements-dev.txt
     $ pytest -v pymysql
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/pymysql/__init__.py 
new/PyMySQL-1.1.2/pymysql/__init__.py
--- old/PyMySQL-1.1.1/pymysql/__init__.py       2024-05-21 13:02:25.000000000 
+0200
+++ new/PyMySQL-1.1.2/pymysql/__init__.py       2025-08-24 14:53:42.000000000 
+0200
@@ -49,8 +49,8 @@
 
 # PyMySQL version.
 # Used by setuptools and connection_attrs
-VERSION = (1, 1, 1, "final", 1)
-VERSION_STRING = "1.1.1"
+VERSION = (1, 1, 2, "final")
+VERSION_STRING = "1.1.2"
 
 ### for mysqlclient compatibility
 ### Django checks mysqlclient version.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/pymysql/_auth.py 
new/PyMySQL-1.1.2/pymysql/_auth.py
--- old/PyMySQL-1.1.1/pymysql/_auth.py  2024-05-21 13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/pymysql/_auth.py  2025-08-24 14:53:42.000000000 +0200
@@ -166,6 +166,8 @@
 
     if pkt.is_auth_switch_request():
         conn.salt = pkt.read_all()
+        if conn.salt.endswith(b"\0"):
+            conn.salt = conn.salt[:-1]
         if not conn.server_public_key and conn.password:
             # Request server public key
             if DEBUG:
@@ -215,9 +217,11 @@
 
     if pkt.is_auth_switch_request():
         # Try from fast auth
-        if DEBUG:
-            print("caching sha2: Trying fast path")
         conn.salt = pkt.read_all()
+        if conn.salt.endswith(b"\0"):  # str.removesuffix is available in 3.9
+            conn.salt = conn.salt[:-1]
+        if DEBUG:
+            print(f"caching sha2: Trying fast path. salt={conn.salt.hex()!r}")
         scrambled = scramble_caching_sha2(conn.password, conn.salt)
         pkt = _roundtrip(conn, scrambled)
     # else: fast auth is tried in initial handshake
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/pymysql/charset.py 
new/PyMySQL-1.1.2/pymysql/charset.py
--- old/PyMySQL-1.1.1/pymysql/charset.py        2024-05-21 13:02:25.000000000 
+0200
+++ new/PyMySQL-1.1.2/pymysql/charset.py        2025-08-24 14:53:42.000000000 
+0200
@@ -45,9 +45,10 @@
         return self._by_id[id]
 
     def by_name(self, name):
+        name = name.lower()
         if name == "utf8":
             name = "utf8mb4"
-        return self._by_name.get(name.lower())
+        return self._by_name.get(name)
 
 
 _charsets = Charsets()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/pymysql/connections.py 
new/PyMySQL-1.1.2/pymysql/connections.py
--- old/PyMySQL-1.1.1/pymysql/connections.py    2024-05-21 13:02:25.000000000 
+0200
+++ new/PyMySQL-1.1.2/pymysql/connections.py    2025-08-24 14:53:42.000000000 
+0200
@@ -40,11 +40,14 @@
 
     DEFAULT_USER = getpass.getuser()
     del getpass
-except (ImportError, KeyError):
-    # KeyError occurs when there's no entry in OS database for a current user.
+except (ImportError, KeyError, OSError):
+    # When there's no entry in OS database for a current user:
+    # KeyError is raised in Python 3.12 and below.
+    # OSError is raised in Python 3.13+
     DEFAULT_USER = None
 
 DEBUG = False
+_DEFAULT_AUTH_PLUGIN = None  # if this is not None, use it instead of server's 
default.
 
 TEXT_TYPES = {
     FIELD_TYPE.BIT,
@@ -161,6 +164,7 @@
     """
 
     _sock = None
+    _rfile = None
     _auth_plugin_name = ""
     _closed = False
     _secure = False
@@ -374,6 +378,12 @@
         capath = sslp.get("capath")
         hasnoca = ca is None and capath is None
         ctx = ssl.create_default_context(cafile=ca, capath=capath)
+
+        # Python 3.13 enables VERIFY_X509_STRICT by default.
+        # But self signed certificates that are generated by MySQL 
automatically
+        # doesn't pass the verification.
+        ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT
+
         ctx.check_hostname = not hasnoca and sslp.get("check_hostname", True)
         verify_mode_value = sslp.get("verify_mode")
         if verify_mode_value is None:
@@ -430,6 +440,8 @@
 
     def _force_close(self):
         """Close connection without QUIT message."""
+        if self._rfile:
+            self._rfile.close()
         if self._sock:
             try:
                 self._sock.close()
@@ -571,9 +583,9 @@
         return self._affected_rows
 
     def kill(self, thread_id):
-        arg = struct.pack("<I", thread_id)
-        self._execute_command(COMMAND.COM_PROCESS_KILL, arg)
-        return self._read_ok_packet()
+        if not isinstance(thread_id, int):
+            raise TypeError("thread_id must be an integer")
+        self.query(f"KILL {thread_id:d}")
 
     def ping(self, reconnect=True):
         """
@@ -696,12 +708,7 @@
             if self.autocommit_mode is not None:
                 self.autocommit(self.autocommit_mode)
         except BaseException as e:
-            self._rfile = None
-            if sock is not None:
-                try:
-                    sock.close()
-                except:  # noqa
-                    pass
+            self._force_close()
 
             if isinstance(e, (OSError, IOError)):
                 exc = err.OperationalError(
@@ -812,16 +819,10 @@
 
     def _read_query_result(self, unbuffered=False):
         self._result = None
+        result = MySQLResult(self)
         if unbuffered:
-            try:
-                result = MySQLResult(self)
-                result.init_unbuffered_query()
-            except:
-                result.unbuffered_active = False
-                result.connection = None
-                raise
+            result.init_unbuffered_query()
         else:
-            result = MySQLResult(self)
             result.read()
         self._result = result
         if result.server_status is not None:
@@ -1158,6 +1159,9 @@
             else:
                 self._auth_plugin_name = data[i:server_end].decode("utf-8")
 
+        if _DEFAULT_AUTH_PLUGIN is not None:  # for tests
+            self._auth_plugin_name = _DEFAULT_AUTH_PLUGIN
+
     def get_server_info(self):
         return self.server_version
 
@@ -1212,17 +1216,16 @@
         :raise OperationalError: If the connection to the MySQL server is lost.
         :raise InternalError:
         """
-        self.unbuffered_active = True
         first_packet = self.connection._read_packet()
 
         if first_packet.is_ok_packet():
-            self._read_ok_packet(first_packet)
-            self.unbuffered_active = False
             self.connection = None
+            self._read_ok_packet(first_packet)
         elif first_packet.is_load_local_packet():
-            self._read_load_local_packet(first_packet)
-            self.unbuffered_active = False
-            self.connection = None
+            try:
+                self._read_load_local_packet(first_packet)
+            finally:
+                self.connection = None
         else:
             self.field_count = first_packet.read_length_encoded_integer()
             self._get_descriptions()
@@ -1231,6 +1234,7 @@
             # value of a 64bit unsigned integer. Since we're emulating MySQLdb,
             # we set it to this instead of None, which would be preferred.
             self.affected_rows = 18446744073709551615
+            self.unbuffered_active = True
 
     def _read_ok_packet(self, first_packet):
         ok_packet = OKPacketWrapper(first_packet)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/pymysql/tests/test_charset.py 
new/PyMySQL-1.1.2/pymysql/tests/test_charset.py
--- old/PyMySQL-1.1.1/pymysql/tests/test_charset.py     2024-05-21 
13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/pymysql/tests/test_charset.py     2025-08-24 
14:53:42.000000000 +0200
@@ -21,5 +21,24 @@
     )
 
     # utf8 is alias of utf8mb4 since MySQL 8.0, and PyMySQL v1.1.
-    utf8 = pymysql.charset.charset_by_name("utf8")
-    assert utf8 == utf8mb4
+    lowercase_utf8 = pymysql.charset.charset_by_name("utf8")
+    assert lowercase_utf8 == utf8mb4
+
+    # Regardless of case, UTF8 (which is special cased) should resolve to the 
same thing
+    uppercase_utf8 = pymysql.charset.charset_by_name("UTF8")
+    mixedcase_utf8 = pymysql.charset.charset_by_name("UtF8")
+    assert uppercase_utf8 == lowercase_utf8
+    assert mixedcase_utf8 == lowercase_utf8
+
+
+def test_case_sensitivity():
+    lowercase_latin1 = pymysql.charset.charset_by_name("latin1")
+    assert lowercase_latin1 is not None
+
+    # lowercase and uppercase should resolve to the same charset
+    uppercase_latin1 = pymysql.charset.charset_by_name("LATIN1")
+    assert uppercase_latin1 == lowercase_latin1
+
+    # lowercase and mixed case should resolve to the same charset
+    mixedcase_latin1 = pymysql.charset.charset_by_name("LaTiN1")
+    assert mixedcase_latin1 == lowercase_latin1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/pymysql/tests/test_connection.py 
new/PyMySQL-1.1.2/pymysql/tests/test_connection.py
--- old/PyMySQL-1.1.1/pymysql/tests/test_connection.py  2024-05-21 
13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/pymysql/tests/test_connection.py  2025-08-24 
14:53:42.000000000 +0200
@@ -558,8 +558,8 @@
         sock.close()
 
     def test_ssl_connect(self):
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
@@ -570,6 +570,7 @@
                     "key": "key",
                     "cipher": "cipher",
                 },
+                defer_connect=True,
             )
             assert create_default_context.called
             assert dummy_ssl_context.check_hostname
@@ -581,8 +582,8 @@
             )
             dummy_ssl_context.set_ciphers.assert_called_with("cipher")
 
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
@@ -592,6 +593,7 @@
                     "cert": "cert",
                     "key": "key",
                 },
+                defer_connect=True,
             )
             assert create_default_context.called
             assert dummy_ssl_context.check_hostname
@@ -603,8 +605,8 @@
             )
             dummy_ssl_context.set_ciphers.assert_not_called
 
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
@@ -615,6 +617,7 @@
                     "key": "key",
                     "password": "password",
                 },
+                defer_connect=True,
             )
             assert create_default_context.called
             assert dummy_ssl_context.check_hostname
@@ -626,13 +629,14 @@
             )
             dummy_ssl_context.set_ciphers.assert_not_called
 
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
             pymysql.connect(
                 ssl_ca="ca",
+                defer_connect=True,
             )
             assert create_default_context.called
             assert not dummy_ssl_context.check_hostname
@@ -640,8 +644,8 @@
             dummy_ssl_context.load_cert_chain.assert_not_called
             dummy_ssl_context.set_ciphers.assert_not_called
 
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
@@ -649,6 +653,7 @@
                 ssl_ca="ca",
                 ssl_cert="cert",
                 ssl_key="key",
+                defer_connect=True,
             )
             assert create_default_context.called
             assert not dummy_ssl_context.check_hostname
@@ -661,8 +666,8 @@
             dummy_ssl_context.set_ciphers.assert_not_called
 
         for ssl_verify_cert in (True, "1", "yes", "true"):
-            dummy_ssl_context = mock.Mock(options=0)
-            with mock.patch("pymysql.connections.Connection.connect"), 
mock.patch(
+            dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+            with mock.patch(
                 "pymysql.connections.ssl.create_default_context",
                 new=mock.Mock(return_value=dummy_ssl_context),
             ) as create_default_context:
@@ -670,6 +675,7 @@
                     ssl_cert="cert",
                     ssl_key="key",
                     ssl_verify_cert=ssl_verify_cert,
+                    defer_connect=True,
                 )
                 assert create_default_context.called
                 assert not dummy_ssl_context.check_hostname
@@ -682,8 +688,8 @@
                 dummy_ssl_context.set_ciphers.assert_not_called
 
         for ssl_verify_cert in (None, False, "0", "no", "false"):
-            dummy_ssl_context = mock.Mock(options=0)
-            with mock.patch("pymysql.connections.Connection.connect"), 
mock.patch(
+            dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+            with mock.patch(
                 "pymysql.connections.ssl.create_default_context",
                 new=mock.Mock(return_value=dummy_ssl_context),
             ) as create_default_context:
@@ -691,6 +697,7 @@
                     ssl_cert="cert",
                     ssl_key="key",
                     ssl_verify_cert=ssl_verify_cert,
+                    defer_connect=True,
                 )
                 assert create_default_context.called
                 assert not dummy_ssl_context.check_hostname
@@ -704,8 +711,8 @@
 
         for ssl_ca in ("ca", None):
             for ssl_verify_cert in ("foo", "bar", ""):
-                dummy_ssl_context = mock.Mock(options=0)
-                with mock.patch("pymysql.connections.Connection.connect"), 
mock.patch(
+                dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+                with mock.patch(
                     "pymysql.connections.ssl.create_default_context",
                     new=mock.Mock(return_value=dummy_ssl_context),
                 ) as create_default_context:
@@ -714,6 +721,7 @@
                         ssl_cert="cert",
                         ssl_key="key",
                         ssl_verify_cert=ssl_verify_cert,
+                        defer_connect=True,
                     )
                     assert create_default_context.called
                     assert not dummy_ssl_context.check_hostname
@@ -727,8 +735,8 @@
                     )
                     dummy_ssl_context.set_ciphers.assert_not_called
 
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
@@ -737,6 +745,7 @@
                 ssl_cert="cert",
                 ssl_key="key",
                 ssl_verify_identity=True,
+                defer_connect=True,
             )
             assert create_default_context.called
             assert dummy_ssl_context.check_hostname
@@ -748,8 +757,8 @@
             )
             dummy_ssl_context.set_ciphers.assert_not_called
 
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
@@ -759,6 +768,7 @@
                 ssl_key="key",
                 ssl_key_password="password",
                 ssl_verify_identity=True,
+                defer_connect=True,
             )
             assert create_default_context.called
             assert dummy_ssl_context.check_hostname
@@ -770,8 +780,8 @@
             )
             dummy_ssl_context.set_ciphers.assert_not_called
 
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
@@ -782,11 +792,12 @@
                     "cert": "cert",
                     "key": "key",
                 },
+                defer_connect=True,
             )
             assert not create_default_context.called
 
-        dummy_ssl_context = mock.Mock(options=0)
-        with mock.patch("pymysql.connections.Connection.connect"), mock.patch(
+        dummy_ssl_context = mock.Mock(options=0, verify_flags=0)
+        with mock.patch(
             "pymysql.connections.ssl.create_default_context",
             new=mock.Mock(return_value=dummy_ssl_context),
         ) as create_default_context:
@@ -795,6 +806,7 @@
                 ssl_ca="ca",
                 ssl_cert="cert",
                 ssl_key="key",
+                defer_connect=True,
             )
             assert not create_default_context.called
 
@@ -854,7 +866,7 @@
 
         mapping = con.encoders.copy()
         mapping[Foo] = escape_foo
-        #self.assertEqual(con.escape({"foo": Foo()}, mapping), {"foo": "bar"})
+        # self.assertEqual(con.escape({"foo": Foo()}, mapping), {"foo": "bar"})
         with self.assertRaises(TypeError):
             con.escape({"foo": Foo()})
 
@@ -883,3 +895,40 @@
         con.commit()
         cur.execute("SELECT 3")
         self.assertEqual(cur.fetchone()[0], 3)
+
+    def test_force_close_closes_socketio(self):
+        con = self.connect()
+        sock = con._sock
+        fileno = sock.fileno()
+        rfile = con._rfile
+
+        con._force_close()
+        assert rfile.closed
+        assert sock._closed
+        assert sock.fileno() != fileno  # should be set to -1
+
+    def test_socket_closed_on_exception_in_connect(self):
+        con = self.connect(defer_connect=True)
+        sock = None
+        rfile = None
+        fileno = -1
+
+        def _request_authentication():
+            nonlocal sock, rfile, fileno
+            sock = con._sock
+            assert sock is not None
+            fileno = sock.fileno()
+            rfile = con._rfile
+            assert rfile is not None
+            raise TypeError
+
+        con._request_authentication = _request_authentication
+
+        with pytest.raises(TypeError):
+            con.connect()
+        assert not con.open
+        assert con._rfile is None
+        assert con._sock is None
+        assert rfile.closed
+        assert sock._closed
+        assert sock.fileno() != fileno  # should be set to -1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/pyproject.toml 
new/PyMySQL-1.1.2/pyproject.toml
--- old/PyMySQL-1.1.1/pyproject.toml    2024-05-21 13:02:25.000000000 +0200
+++ new/PyMySQL-1.1.2/pyproject.toml    2025-08-24 14:53:42.000000000 +0200
@@ -7,23 +7,15 @@
 ]
 dependencies = []
 
-requires-python = ">=3.7"
+requires-python = ">=3.8"
 readme = "README.md"
-license = {text = "MIT License"}
+license = "MIT"
 keywords = ["MySQL"]
 classifiers = [
     "Development Status :: 5 - Production/Stable",
-    "Programming Language :: Python :: 3",
-    "Programming Language :: Python :: 3.7",
-    "Programming Language :: Python :: 3.8",
-    "Programming Language :: Python :: 3.9",
-    "Programming Language :: Python :: 3.10",
-    "Programming Language :: Python :: 3.11",
-    "Programming Language :: Python :: 3.12",
     "Programming Language :: Python :: Implementation :: CPython",
     "Programming Language :: Python :: Implementation :: PyPy",
     "Intended Audience :: Developers",
-    "License :: OSI Approved :: MIT License",
     "Topic :: Database",
 ]
 dynamic = ["version"]
@@ -39,9 +31,10 @@
 [project.urls]
 "Project" = "https://github.com/PyMySQL/PyMySQL";
 "Documentation" = "https://pymysql.readthedocs.io/";
+"Changelog" = "https://github.com/PyMySQL/PyMySQL/blob/main/CHANGELOG.md";
 
 [build-system]
-requires = ["setuptools>=61"]
+requires = ["setuptools>=77"]
 build-backend = "setuptools.build_meta"
 
 [tool.setuptools.packages.find]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyMySQL-1.1.1/tests/test_auth.py 
new/PyMySQL-1.1.2/tests/test_auth.py
--- old/PyMySQL-1.1.1/tests/test_auth.py        2024-05-21 13:02:25.000000000 
+0200
+++ new/PyMySQL-1.1.2/tests/test_auth.py        2025-08-24 14:53:42.000000000 
+0200
@@ -71,6 +71,19 @@
     con.query("FLUSH PRIVILEGES")
     con.close()
 
+    # Fast path after auth_switch_request
+    pymysql.connections._DEFAULT_AUTH_PLUGIN = "mysql_native_password"
+    con = pymysql.connect(
+        user="user_caching_sha2",
+        password=pass_caching_sha2,
+        host=host,
+        port=port,
+        ssl=ssl,
+    )
+    con.query("FLUSH PRIVILEGES")
+    con.close()
+    pymysql.connections._DEFAULT_AUTH_PLUGIN = None
+
 
 def test_caching_sha2_password_ssl():
     con = pymysql.connect(
@@ -88,7 +101,20 @@
         password=pass_caching_sha2,
         host=host,
         port=port,
-        ssl=None,
+        ssl=ssl,
+    )
+    con.query("FLUSH PRIVILEGES")
+    con.close()
+
+    # Fast path after auth_switch_request
+    pymysql.connections._DEFAULT_AUTH_PLUGIN = "mysql_native_password"
+    con = pymysql.connect(
+        user="user_caching_sha2",
+        password=pass_caching_sha2,
+        host=host,
+        port=port,
+        ssl=ssl,
     )
     con.query("FLUSH PRIVILEGES")
     con.close()
+    pymysql.connections._DEFAULT_AUTH_PLUGIN = None

Reply via email to