Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-urllib3 for openSUSE:Factory checked in at 2026-01-14 16:19:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-urllib3 (Old) and /work/SRC/openSUSE:Factory/.python-urllib3.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-urllib3" Wed Jan 14 16:19:41 2026 rev:74 rq:1327014 version:2.6.3 Changes: -------- --- /work/SRC/openSUSE:Factory/python-urllib3/python-urllib3.changes 2026-01-09 17:02:53.122421463 +0100 +++ /work/SRC/openSUSE:Factory/.python-urllib3.new.1928/python-urllib3.changes 2026-01-14 16:20:00.713286331 +0100 @@ -1,0 +2,11 @@ +Tue Jan 13 09:40:54 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to 2.6.3 + * Fixed a high-severity security issue where decompression-bomb safeguards of + the streaming API were bypassed when HTTP redirects were followed. + (GHSA-38jv-5279-wg99) (bsc#1256331, CVE-2026-21441) + * Started treating ``Retry-After`` times greater than 6 hours as 6 hours by + default. (#3743) + * Fixed ``urllib3.connection.VerifiedHTTPSConnection`` on Emscripten. (#3752) + +------------------------------------------------------------------- Old: ---- urllib3-2.6.2.tar.gz New: ---- urllib3-2.6.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-urllib3.spec ++++++ --- /var/tmp/diff_new_pack.8TN7Av/_old 2026-01-14 16:20:01.429316123 +0100 +++ /var/tmp/diff_new_pack.8TN7Av/_new 2026-01-14 16:20:01.429316123 +0100 @@ -26,7 +26,7 @@ %endif %{?sle15_python_module_pythons} Name: python-urllib3%{psuffix} -Version: 2.6.2 +Version: 2.6.3 Release: 0 Summary: HTTP library with thread-safe connection pooling, file post, and more License: MIT ++++++ urllib3-2.6.2.tar.gz -> urllib3-2.6.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/CHANGES.rst new/urllib3-2.6.3/CHANGES.rst --- old/urllib3-2.6.2/CHANGES.rst 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/CHANGES.rst 2026-01-07 17:18:09.000000000 +0100 @@ -1,3 +1,15 @@ +2.6.3 (2026-01-07) +================== + +- Fixed a high-severity security issue where decompression-bomb safeguards of + the streaming API were bypassed when HTTP redirects were followed. + (`GHSA-38jv-5279-wg99 <https://github.com/urllib3/urllib3/security/advisories/GHSA-38jv-5279-wg99>`__) +- Started treating ``Retry-After`` times greater than 6 hours as 6 hours by + default. (`#3743 <https://github.com/urllib3/urllib3/issues/3743>`__) +- Fixed ``urllib3.connection.VerifiedHTTPSConnection`` on Emscripten. + (`#3752 <https://github.com/urllib3/urllib3/issues/3752>`__) + + 2.6.2 (2025-12-11) ================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/PKG-INFO new/urllib3-2.6.3/PKG-INFO --- old/urllib3-2.6.2/PKG-INFO 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/PKG-INFO 2026-01-07 17:18:09.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: urllib3 -Version: 2.6.2 +Version: 2.6.3 Summary: HTTP library with thread-safe connection pooling, file post, and more. Project-URL: Changelog, https://github.com/urllib3/urllib3/blob/main/CHANGES.rst Project-URL: Documentation, https://urllib3.readthedocs.io @@ -58,8 +58,7 @@ <a href="https://bestpractices.coreinfrastructure.org/projects/6227"><img alt="CII Best Practices" src="https://bestpractices.coreinfrastructure.org/projects/6227/badge" /></a> </p> -urllib3 is a powerful, *user-friendly* HTTP client for Python. Much of the -Python ecosystem already uses urllib3 and you should too. +urllib3 is a powerful, *user-friendly* HTTP client for Python. urllib3 brings many critical features that are missing from the Python standard libraries: @@ -72,16 +71,13 @@ - Proxy support for HTTP and SOCKS. - 100% test coverage. -urllib3 is powerful and easy to use: +... and many more features, but most importantly: Our maintainers have a 15+ +year track record of maintaining urllib3 with the highest code standards and +attention to security and safety. + +[Much of the Python ecosystem already uses urllib3](https://urllib3.readthedocs.io/en/stable/#who-uses) +and you should too. -```python3 ->>> import urllib3 ->>> resp = urllib3.request("GET", "http://httpbin.org/robots.txt") ->>> resp.status -200 ->>> resp.data -b"User-agent: *\nDisallow: /deny\n" -``` ## Installing @@ -99,8 +95,18 @@ $ pip install . ``` +## Getting Started -## Documentation +urllib3 is easy to use: + +```python3 +>>> import urllib3 +>>> resp = urllib3.request("GET", "http://httpbin.org/robots.txt") +>>> resp.status +200 +>>> resp.data +b"User-agent: *\nDisallow: /deny\n" +``` urllib3 has usage and reference documentation at [urllib3.readthedocs.io](https://urllib3.readthedocs.io). @@ -127,7 +133,9 @@ ## Maintainers -- Lead: [@illia-v](https://github.com/illia-v) (Illia Volochii) +Meet our maintainers since 2008: + +- Current Lead: [@illia-v](https://github.com/illia-v) (Illia Volochii) - [@sethmlarson](https://github.com/sethmlarson) (Seth M. Larson) - [@pquentin](https://github.com/pquentin) (Quentin Pradet) - [@theacodes](https://github.com/theacodes) (Thea Flowers) @@ -148,7 +156,7 @@ ## For Enterprise Professional support for urllib3 is available as part of the [Tidelift -Subscription][1]. Tidelift gives software development teams a single source for +Subscription][1]. Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/README.md new/urllib3-2.6.3/README.md --- old/urllib3-2.6.2/README.md 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/README.md 2026-01-07 17:18:09.000000000 +0100 @@ -16,8 +16,7 @@ <a href="https://bestpractices.coreinfrastructure.org/projects/6227"><img alt="CII Best Practices" src="https://bestpractices.coreinfrastructure.org/projects/6227/badge" /></a> </p> -urllib3 is a powerful, *user-friendly* HTTP client for Python. Much of the -Python ecosystem already uses urllib3 and you should too. +urllib3 is a powerful, *user-friendly* HTTP client for Python. urllib3 brings many critical features that are missing from the Python standard libraries: @@ -30,16 +29,13 @@ - Proxy support for HTTP and SOCKS. - 100% test coverage. -urllib3 is powerful and easy to use: +... and many more features, but most importantly: Our maintainers have a 15+ +year track record of maintaining urllib3 with the highest code standards and +attention to security and safety. + +[Much of the Python ecosystem already uses urllib3](https://urllib3.readthedocs.io/en/stable/#who-uses) +and you should too. -```python3 ->>> import urllib3 ->>> resp = urllib3.request("GET", "http://httpbin.org/robots.txt") ->>> resp.status -200 ->>> resp.data -b"User-agent: *\nDisallow: /deny\n" -``` ## Installing @@ -57,8 +53,18 @@ $ pip install . ``` +## Getting Started -## Documentation +urllib3 is easy to use: + +```python3 +>>> import urllib3 +>>> resp = urllib3.request("GET", "http://httpbin.org/robots.txt") +>>> resp.status +200 +>>> resp.data +b"User-agent: *\nDisallow: /deny\n" +``` urllib3 has usage and reference documentation at [urllib3.readthedocs.io](https://urllib3.readthedocs.io). @@ -85,7 +91,9 @@ ## Maintainers -- Lead: [@illia-v](https://github.com/illia-v) (Illia Volochii) +Meet our maintainers since 2008: + +- Current Lead: [@illia-v](https://github.com/illia-v) (Illia Volochii) - [@sethmlarson](https://github.com/sethmlarson) (Seth M. Larson) - [@pquentin](https://github.com/pquentin) (Quentin Pradet) - [@theacodes](https://github.com/theacodes) (Thea Flowers) @@ -106,7 +114,7 @@ ## For Enterprise Professional support for urllib3 is available as part of the [Tidelift -Subscription][1]. Tidelift gives software development teams a single source for +Subscription][1]. Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/docs/index.rst new/urllib3-2.6.3/docs/index.rst --- old/urllib3-2.6.2/docs/index.rst 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/docs/index.rst 2026-01-07 17:18:09.000000000 +0100 @@ -7,13 +7,13 @@ For Enterprise <https://tidelift.com/subscription/pkg/pypi-urllib3?utm_source=pypi-urllib3&utm_medium=referral&utm_campaign=docs> Community Discord <https://discord.gg/urllib3> - v2-migration-guide sponsors user-guide advanced-usage reference/index contributing changelog + v2-migration-guide urllib3 is a powerful, *user-friendly* HTTP client for Python. :ref:`Much of the Python ecosystem already uses <who-uses>` urllib3 and you should too. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/docs/v2-migration-guide.rst new/urllib3-2.6.3/docs/v2-migration-guide.rst --- old/urllib3-2.6.2/docs/v2-migration-guide.rst 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/docs/v2-migration-guide.rst 2026-01-07 17:18:09.000000000 +0100 @@ -1,4 +1,4 @@ -v2.0 Migration Guide +v2 Migration Guide ==================== **urllib3 2.x is now available!** Read below for how to get started and what is contained in the new major release. @@ -61,7 +61,7 @@ .. code-block:: text - ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips 26 Jan 2017'. + ImportError: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips 26 Jan 2017'. See: https://github.com/urllib3/urllib3/issues/2168 Remediation depends on your system: @@ -178,7 +178,7 @@ "urllib3>=1.26,<3" ] -Next you should try installing urllib3 v2.0 locally and run your test suite. +Next you should try installing urllib3 v2.x locally and run your test suite. .. code-block:: bash @@ -335,7 +335,7 @@ over the wire. If you still need to use TLS 1.0 or 1.1 in your application -you can still upgrade to v2.0, you'll only need to set +you can still upgrade to v2.x, you'll only need to set ``ssl_minimum_version`` to the proper value to continue using legacy TLS versions. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/dummyserver/app.py new/urllib3-2.6.3/dummyserver/app.py --- old/urllib3-2.6.2/dummyserver/app.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/dummyserver/app.py 2026-01-07 17:18:09.000000000 +0100 @@ -233,10 +233,16 @@ values = await request.values target = values.get("target", "/") status = values.get("status", "303 See Other") + compressed = values.get("compressed") == "true" status_code = status.split(" ")[0] headers = [("Location", target)] - return await make_response("", status_code, headers) + if compressed: + headers.append(("Content-Encoding", "gzip")) + data = gzip.compress(b"foo") + else: + data = b"" + return await make_response(data, status_code, headers) @hypercorn_app.route("/redirect_after") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/src/urllib3/_version.py new/urllib3-2.6.3/src/urllib3/_version.py --- old/urllib3-2.6.2/src/urllib3/_version.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/src/urllib3/_version.py 2026-01-07 17:18:09.000000000 +0100 @@ -28,7 +28,7 @@ commit_id: COMMIT_ID __commit_id__: COMMIT_ID -__version__ = version = '2.6.2' -__version_tuple__ = version_tuple = (2, 6, 2) +__version__ = version = '2.6.3' +__version_tuple__ = version_tuple = (2, 6, 3) __commit_id__ = commit_id = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/src/urllib3/contrib/emscripten/__init__.py new/urllib3-2.6.3/src/urllib3/contrib/emscripten/__init__.py --- old/urllib3-2.6.2/src/urllib3/contrib/emscripten/__init__.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/src/urllib3/contrib/emscripten/__init__.py 2026-01-07 17:18:09.000000000 +0100 @@ -14,3 +14,4 @@ HTTPSConnectionPool.ConnectionCls = EmscriptenHTTPSConnection urllib3.connection.HTTPConnection = EmscriptenHTTPConnection # type: ignore[misc,assignment] urllib3.connection.HTTPSConnection = EmscriptenHTTPSConnection # type: ignore[misc,assignment] + urllib3.connection.VerifiedHTTPSConnection = EmscriptenHTTPSConnection # type: ignore[assignment] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/src/urllib3/contrib/emscripten/connection.py new/urllib3-2.6.3/src/urllib3/contrib/emscripten/connection.py --- old/urllib3-2.6.2/src/urllib3/contrib/emscripten/connection.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/src/urllib3/contrib/emscripten/connection.py 2026-01-07 17:18:09.000000000 +0100 @@ -40,6 +40,7 @@ is_verified: bool = False proxy_is_verified: bool | None = None + response_class: type[BaseHTTPResponse] = EmscriptenHttpResponseWrapper _response: EmscriptenResponse | None def __init__( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/src/urllib3/http2/connection.py new/urllib3-2.6.3/src/urllib3/http2/connection.py --- old/urllib3-2.6.2/src/urllib3/http2/connection.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/src/urllib3/http2/connection.py 2026-01-07 17:18:09.000000000 +0100 @@ -6,9 +6,9 @@ import types import typing -import h2.config # type: ignore[import-untyped] -import h2.connection # type: ignore[import-untyped] -import h2.events # type: ignore[import-untyped] +import h2.config +import h2.connection +import h2.events from .._base_connection import _TYPE_BODY from .._collections import HTTPHeaderDict diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/src/urllib3/response.py new/urllib3-2.6.3/src/urllib3/response.py --- old/urllib3-2.6.2/src/urllib3/response.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/src/urllib3/response.py 2026-01-07 17:18:09.000000000 +0100 @@ -797,7 +797,11 @@ Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. """ try: - self.read() + self.read( + # Do not spend resources decoding the content unless + # decoding has already been initiated. + decode_content=self._has_decoded_content, + ) except (HTTPError, OSError, BaseSSLError, HTTPException): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/src/urllib3/util/retry.py new/urllib3-2.6.3/src/urllib3/util/retry.py --- old/urllib3-2.6.2/src/urllib3/util/retry.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/src/urllib3/util/retry.py 2026-01-07 17:18:09.000000000 +0100 @@ -178,6 +178,11 @@ Sequence of headers to remove from the request when a response indicating a redirect is returned before firing off the redirected request. + + :param int retry_after_max: Number of seconds to allow as the maximum for + Retry-After headers. Defaults to :attr:`Retry.DEFAULT_RETRY_AFTER_MAX`. + Any Retry-After headers larger than this value will be limited to this + value. """ #: Default methods to be used for ``allowed_methods`` @@ -196,6 +201,10 @@ #: Default maximum backoff time. DEFAULT_BACKOFF_MAX = 120 + # This is undocumented in the RFC. Setting to 6 hours matches other popular libraries. + #: Default maximum allowed value for Retry-After headers in seconds + DEFAULT_RETRY_AFTER_MAX: typing.Final[int] = 21600 + # Backward compatibility; assigned outside of the class. DEFAULT: typing.ClassVar[Retry] @@ -219,6 +228,7 @@ str ] = DEFAULT_REMOVE_HEADERS_ON_REDIRECT, backoff_jitter: float = 0.0, + retry_after_max: int = DEFAULT_RETRY_AFTER_MAX, ) -> None: self.total = total self.connect = connect @@ -235,6 +245,7 @@ self.allowed_methods = allowed_methods self.backoff_factor = backoff_factor self.backoff_max = backoff_max + self.retry_after_max = retry_after_max self.raise_on_redirect = raise_on_redirect self.raise_on_status = raise_on_status self.history = history or () @@ -256,6 +267,7 @@ status_forcelist=self.status_forcelist, backoff_factor=self.backoff_factor, backoff_max=self.backoff_max, + retry_after_max=self.retry_after_max, raise_on_redirect=self.raise_on_redirect, raise_on_status=self.raise_on_status, history=self.history, @@ -320,6 +332,10 @@ seconds = max(seconds, 0) + # Check the seconds do not exceed the specified maximum + if seconds > self.retry_after_max: + seconds = self.retry_after_max + return seconds def get_retry_after(self, response: BaseHTTPResponse) -> float | None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/test/contrib/emscripten/test_emscripten.py new/urllib3-2.6.3/test/contrib/emscripten/test_emscripten.py --- old/urllib3-2.6.2/test/contrib/emscripten/test_emscripten.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/test/contrib/emscripten/test_emscripten.py 2026-01-07 17:18:09.000000000 +0100 @@ -302,15 +302,20 @@ run_from_server.run_webworker(worker_code) [email protected]( + "connection_cls", ["HTTPSConnection", "VerifiedHTTPSConnection"] +) def test_index_https( - selenium_coverage: typing.Any, testserver_http: PyodideServerInfo + selenium_coverage: typing.Any, + testserver_http: PyodideServerInfo, + connection_cls: str, ) -> None: @run_in_pyodide # type: ignore[misc] - def pyodide_test(selenium_coverage, host: str, port: int) -> None: # type: ignore[no-untyped-def] - from urllib3.connection import HTTPSConnection + def pyodide_test(selenium_coverage, host: str, port: int, connection_cls: str) -> None: # type: ignore[no-untyped-def] + from urllib3 import connection from urllib3.response import BaseHTTPResponse - conn = HTTPSConnection(host, port) + conn = getattr(connection, connection_cls)(host, port) conn.request("GET", f"https://{host}:{port}/") response = conn.getresponse() assert isinstance(response, BaseHTTPResponse) @@ -318,7 +323,10 @@ assert data.decode("utf-8") == "Dummy server!" pyodide_test( - selenium_coverage, testserver_http.http_host, testserver_http.https_port + selenium_coverage, + testserver_http.http_host, + testserver_http.https_port, + connection_cls, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/test/test_http2_connection.py new/urllib3-2.6.3/test/test_http2_connection.py --- old/urllib3-2.6.2/test/test_http2_connection.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/test/test_http2_connection.py 2026-01-07 17:18:09.000000000 +0100 @@ -121,9 +121,9 @@ conn.sock = mock.MagicMock( sendall=mock.Mock(return_value=None), ) - conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"bar") - conn._h2_conn._obj.send_data = mock.Mock(return_value=None) - conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) + conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"bar") # type: ignore[method-assign] + conn._h2_conn._obj.send_data = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) # type: ignore[method-assign] conn.putrequest("GET", "/") conn.endheaders() @@ -138,9 +138,9 @@ conn.sock = mock.MagicMock( sendall=mock.Mock(return_value=None), ) - conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"bar") - conn._h2_conn._obj.send_data = mock.Mock(return_value=None) - conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) + conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"bar") # type: ignore[method-assign] + conn._h2_conn._obj.send_data = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) # type: ignore[method-assign] conn.putrequest("GET", "/") conn.endheaders(message_body=b"foo") @@ -155,10 +155,10 @@ conn.sock = mock.MagicMock( sendall=mock.Mock(return_value=None), ) - conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"baz") - conn._h2_conn._obj.send_data = mock.Mock(return_value=None) - conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) - conn._h2_conn._obj.end_stream = mock.Mock(return_value=None) + conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"baz") # type: ignore[method-assign] + conn._h2_conn._obj.send_data = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) # type: ignore[method-assign] + conn._h2_conn._obj.end_stream = mock.Mock(return_value=None) # type: ignore[method-assign] conn.putrequest("GET", "/") conn.endheaders(message_body=[b"foo", b"bar"]) @@ -191,10 +191,10 @@ conn.sock = mock.MagicMock( sendall=mock.Mock(return_value=None), ) - conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") - conn._h2_conn._obj.send_data = mock.Mock(return_value=None) - conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) - conn._h2_conn._obj.end_stream = mock.Mock(return_value=None) + conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") # type: ignore[method-assign] + conn._h2_conn._obj.send_data = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) # type: ignore[method-assign] + conn._h2_conn._obj.end_stream = mock.Mock(return_value=None) # type: ignore[method-assign] with open("foo") as body: conn.putrequest("GET", "/") @@ -215,10 +215,10 @@ conn.sock = mock.MagicMock( sendall=mock.Mock(return_value=None), ) - conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") - conn._h2_conn._obj.send_data = mock.Mock(return_value=None) - conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) - conn._h2_conn._obj.end_stream = mock.Mock(return_value=None) + conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") # type: ignore[method-assign] + conn._h2_conn._obj.send_data = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) # type: ignore[method-assign] + conn._h2_conn._obj.end_stream = mock.Mock(return_value=None) # type: ignore[method-assign] body = open("foo", "rb") conn.putrequest("GET", "/") @@ -244,11 +244,11 @@ sendall=mock.Mock(return_value=None), ) sendall = conn.sock.sendall - data_to_send = conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") - send_headers = conn._h2_conn._obj.send_headers = mock.Mock(return_value=None) - conn._h2_conn._obj.send_data = mock.Mock(return_value=None) - conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) - close_connection = conn._h2_conn._obj.close_connection = mock.Mock( + data_to_send = conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") # type: ignore[method-assign] + send_headers = conn._h2_conn._obj.send_headers = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.send_data = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) # type: ignore[method-assign] + close_connection = conn._h2_conn._obj.close_connection = mock.Mock( # type: ignore[method-assign] return_value=None ) @@ -277,11 +277,11 @@ sendall=mock.Mock(return_value=None), ) sendall = conn.sock.sendall - data_to_send = conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") - send_headers = conn._h2_conn._obj.send_headers = mock.Mock(return_value=None) - send_data = conn._h2_conn._obj.send_data = mock.Mock(return_value=None) - conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) - close_connection = conn._h2_conn._obj.close_connection = mock.Mock( + data_to_send = conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") # type: ignore[method-assign] + send_headers = conn._h2_conn._obj.send_headers = mock.Mock(return_value=None) # type: ignore[method-assign] + send_data = conn._h2_conn._obj.send_data = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) # type: ignore[method-assign] + close_connection = conn._h2_conn._obj.close_connection = mock.Mock( # type: ignore[method-assign] return_value=None ) @@ -310,8 +310,8 @@ sendall=mock.Mock(side_effect=Exception("foo")), ) sendall = conn.sock.sendall - data_to_send = conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") - close_connection = conn._h2_conn._obj.close_connection = mock.Mock( + data_to_send = conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") # type: ignore[method-assign] + close_connection = conn._h2_conn._obj.close_connection = mock.Mock( # type: ignore[method-assign] return_value=None ) @@ -332,11 +332,11 @@ sendall=mock.Mock(return_value=None), ) sendall = conn.sock.sendall - data_to_send = conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") - send_headers = conn._h2_conn._obj.send_headers = mock.Mock(return_value=None) - conn._h2_conn._obj.send_data = mock.Mock(return_value=None) - conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) - close_connection = conn._h2_conn._obj.close_connection = mock.Mock( + data_to_send = conn._h2_conn._obj.data_to_send = mock.Mock(return_value=b"foo") # type: ignore[method-assign] + send_headers = conn._h2_conn._obj.send_headers = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.send_data = mock.Mock(return_value=None) # type: ignore[method-assign] + conn._h2_conn._obj.get_next_available_stream_id = mock.Mock(return_value=1) # type: ignore[method-assign] + close_connection = conn._h2_conn._obj.close_connection = mock.Mock( # type: ignore[method-assign] return_value=None ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/test/test_retry.py new/urllib3-2.6.3/test/test_retry.py --- old/urllib3-2.6.2/test/test_retry.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/test/test_retry.py 2026-01-07 17:18:09.000000000 +0100 @@ -181,6 +181,18 @@ retry = retry.increment(method="GET") assert retry.get_backoff_time() == max_backoff + def test_configurable_retry_after_max(self) -> None: + """Configurable retry after is computed correctly""" + max_retry_after = Retry.DEFAULT_RETRY_AFTER_MAX + + retry = Retry() + assert retry.parse_retry_after(str(max_retry_after)) == max_retry_after + assert retry.parse_retry_after(str(max_retry_after + 1)) == max_retry_after + + retry = Retry(retry_after_max=1) + assert retry.parse_retry_after(str(1)) == 1 + assert retry.parse_retry_after(str(2)) == 1 + def test_backoff_jitter(self) -> None: """Backoff with jitter is computed correctly""" max_backoff = 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/test/with_dummyserver/test_connectionpool.py new/urllib3-2.6.3/test/with_dummyserver/test_connectionpool.py --- old/urllib3-2.6.2/test/with_dummyserver/test_connectionpool.py 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/test/with_dummyserver/test_connectionpool.py 2026-01-07 17:18:09.000000000 +0100 @@ -508,6 +508,25 @@ assert r.status == 200 assert r.data == b"Dummy server!" + @mock.patch("urllib3.response.GzipDecoder.decompress") + def test_no_decoding_with_redirect_when_preload_disabled( + self, gzip_decompress: mock.MagicMock + ) -> None: + """ + Test that urllib3 does not attempt to decode a gzipped redirect + response when `preload_content` is set to `False`. + """ + with HTTPConnectionPool(self.host, self.port) as pool: + # Three requests are expected: two redirects and one final / 200 OK. + response = pool.request( + "GET", + "/redirect", + fields={"target": "/redirect?compressed=true", "compressed": "true"}, + preload_content=False, + ) + assert response.status == 200 + gzip_decompress.assert_not_called() + def test_303_redirect_makes_request_lose_body(self) -> None: with HTTPConnectionPool(self.host, self.port) as pool: response = pool.request( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.6.2/uv.lock new/urllib3-2.6.3/uv.lock --- old/urllib3-2.6.2/uv.lock 2025-12-11 16:43:56.000000000 +0100 +++ new/urllib3-2.6.3/uv.lock 2026-01-07 17:18:09.000000000 +0100 @@ -2,7 +2,8 @@ revision = 3 requires-python = ">=3.9" resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", "python_full_version < '3.10'", ] @@ -45,7 +46,8 @@ version = "1.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210, upload-time = "2024-07-26T18:15:03.762Z" } @@ -573,7 +575,8 @@ version = "8.3.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] dependencies = [ @@ -724,7 +727,8 @@ version = "7.11.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/1c/38/ee22495420457259d2f3390309505ea98f98a5eed40901cf62196abad006/coverage-7.11.0.tar.gz", hash = "sha256:167bd504ac1ca2af7ff3b81d245dfea0292c5032ebef9d66cc08a7d28c1b8050", size = 811905, upload-time = "2025-10-15T15:15:08.542Z" } @@ -944,15 +948,16 @@ [[package]] name = "filelock" -version = "3.20.0" +version = "3.20.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] -sdist = { url = "https://files.pythonhosted.org/packages/58/46/0028a82567109b5ef6e4d2a1f04a583fb513e6cf9527fcdd09afd817deeb/filelock-3.20.0.tar.gz", hash = "sha256:711e943b4ec6be42e1d4e6690b48dc175c822967466bb31c0c293f34334c13f4", size = 18922, upload-time = "2025-10-08T18:03:50.056Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c1/e0/a75dbe4bca1e7d41307323dad5ea2efdd95408f74ab2de8bd7dba9b51a1a/filelock-3.20.2.tar.gz", hash = "sha256:a2241ff4ddde2a7cebddf78e39832509cb045d18ec1a09d7248d6bfc6bfbbe64", size = 19510, upload-time = "2026-01-02T15:33:32.582Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/91/7216b27286936c16f5b4d0c530087e4a54eead683e6b0b73dd0c64844af6/filelock-3.20.0-py3-none-any.whl", hash = "sha256:339b4732ffda5cd79b13f4e2711a31b0365ce445d95d243bb996273d072546a2", size = 16054, upload-time = "2025-10-08T18:03:48.35Z" }, + { url = "https://files.pythonhosted.org/packages/9a/30/ab407e2ec752aa541704ed8f93c11e2a5d92c168b8a755d818b74a3c5c2d/filelock-3.20.2-py3-none-any.whl", hash = "sha256:fbba7237d6ea277175a32c54bb71ef814a8546d8601269e1bfc388de333974e8", size = 16697, upload-time = "2026-01-02T15:33:31.133Z" }, ] [[package]] @@ -1006,6 +1011,8 @@ { url = "https://files.pythonhosted.org/packages/7f/91/ae2eb6b7979e2f9b035a9f612cf70f1bf54aad4e1d125129bef1eae96f19/greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d", size = 584358, upload-time = "2025-08-07T13:18:23.708Z" }, { url = "https://files.pythonhosted.org/packages/f7/85/433de0c9c0252b22b16d413c9407e6cb3b41df7389afc366ca204dbc1393/greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5", size = 1113550, upload-time = "2025-08-07T13:42:37.467Z" }, { url = "https://files.pythonhosted.org/packages/a1/8d/88f3ebd2bc96bf7747093696f4335a0a8a4c5acfcf1b757717c0d2474ba3/greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f", size = 1137126, upload-time = "2025-08-07T13:18:20.239Z" }, + { url = "https://files.pythonhosted.org/packages/f1/29/74242b7d72385e29bcc5563fba67dad94943d7cd03552bac320d597f29b2/greenlet-3.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f47617f698838ba98f4ff4189aef02e7343952df3a615f847bb575c3feb177a7", size = 1544904, upload-time = "2025-11-04T12:42:04.763Z" }, + { url = "https://files.pythonhosted.org/packages/c8/e2/1572b8eeab0f77df5f6729d6ab6b141e4a84ee8eb9bc8c1e7918f94eda6d/greenlet-3.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af41be48a4f60429d5cad9d22175217805098a9ef7c40bfef44f7669fb9d74d8", size = 1611228, upload-time = "2025-11-04T12:42:08.423Z" }, { url = "https://files.pythonhosted.org/packages/d6/6f/b60b0291d9623c496638c582297ead61f43c4b72eef5e9c926ef4565ec13/greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c", size = 298654, upload-time = "2025-08-07T13:50:00.469Z" }, { url = "https://files.pythonhosted.org/packages/a4/de/f28ced0a67749cac23fecb02b694f6473f47686dff6afaa211d186e2ef9c/greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2", size = 272305, upload-time = "2025-08-07T13:15:41.288Z" }, { url = "https://files.pythonhosted.org/packages/09/16/2c3792cba130000bf2a31c5272999113f4764fd9d874fb257ff588ac779a/greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246", size = 632472, upload-time = "2025-08-07T13:42:55.044Z" }, @@ -1015,6 +1022,8 @@ { url = "https://files.pythonhosted.org/packages/1f/8e/abdd3f14d735b2929290a018ecf133c901be4874b858dd1c604b9319f064/greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8", size = 587684, upload-time = "2025-08-07T13:18:25.164Z" }, { url = "https://files.pythonhosted.org/packages/5d/65/deb2a69c3e5996439b0176f6651e0052542bb6c8f8ec2e3fba97c9768805/greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52", size = 1116647, upload-time = "2025-08-07T13:42:38.655Z" }, { url = "https://files.pythonhosted.org/packages/3f/cc/b07000438a29ac5cfb2194bfc128151d52f333cee74dd7dfe3fb733fc16c/greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa", size = 1142073, upload-time = "2025-08-07T13:18:21.737Z" }, + { url = "https://files.pythonhosted.org/packages/67/24/28a5b2fa42d12b3d7e5614145f0bd89714c34c08be6aabe39c14dd52db34/greenlet-3.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9c6de1940a7d828635fbd254d69db79e54619f165ee7ce32fda763a9cb6a58c", size = 1548385, upload-time = "2025-11-04T12:42:11.067Z" }, + { url = "https://files.pythonhosted.org/packages/6a/05/03f2f0bdd0b0ff9a4f7b99333d57b53a7709c27723ec8123056b084e69cd/greenlet-3.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03c5136e7be905045160b1b9fdca93dd6727b180feeafda6818e6496434ed8c5", size = 1613329, upload-time = "2025-11-04T12:42:12.928Z" }, { url = "https://files.pythonhosted.org/packages/d8/0f/30aef242fcab550b0b3520b8e3561156857c94288f0332a79928c31a52cf/greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9", size = 299100, upload-time = "2025-08-07T13:44:12.287Z" }, { url = "https://files.pythonhosted.org/packages/44/69/9b804adb5fd0671f367781560eb5eb586c4d495277c93bde4307b9e28068/greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd", size = 274079, upload-time = "2025-08-07T13:15:45.033Z" }, { url = "https://files.pythonhosted.org/packages/46/e9/d2a80c99f19a153eff70bc451ab78615583b8dac0754cfb942223d2c1a0d/greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb", size = 640997, upload-time = "2025-08-07T13:42:56.234Z" }, @@ -1024,6 +1033,8 @@ { url = "https://files.pythonhosted.org/packages/19/0d/6660d55f7373b2ff8152401a83e02084956da23ae58cddbfb0b330978fe9/greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0", size = 607586, upload-time = "2025-08-07T13:18:28.544Z" }, { url = "https://files.pythonhosted.org/packages/8e/1a/c953fdedd22d81ee4629afbb38d2f9d71e37d23caace44775a3a969147d4/greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0", size = 1123281, upload-time = "2025-08-07T13:42:39.858Z" }, { url = "https://files.pythonhosted.org/packages/3f/c7/12381b18e21aef2c6bd3a636da1088b888b97b7a0362fac2e4de92405f97/greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f", size = 1151142, upload-time = "2025-08-07T13:18:22.981Z" }, + { url = "https://files.pythonhosted.org/packages/27/45/80935968b53cfd3f33cf99ea5f08227f2646e044568c9b1555b58ffd61c2/greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0", size = 1564846, upload-time = "2025-11-04T12:42:15.191Z" }, + { url = "https://files.pythonhosted.org/packages/69/02/b7c30e5e04752cb4db6202a3858b149c0710e5453b71a3b2aec5d78a1aab/greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d", size = 1633814, upload-time = "2025-11-04T12:42:17.175Z" }, { url = "https://files.pythonhosted.org/packages/e9/08/b0814846b79399e585f974bbeebf5580fbe59e258ea7be64d9dfb253c84f/greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02", size = 299899, upload-time = "2025-08-07T13:38:53.448Z" }, { url = "https://files.pythonhosted.org/packages/49/e8/58c7f85958bda41dafea50497cbd59738c5c43dbbea5ee83d651234398f4/greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31", size = 272814, upload-time = "2025-08-07T13:15:50.011Z" }, { url = "https://files.pythonhosted.org/packages/62/dd/b9f59862e9e257a16e4e610480cfffd29e3fae018a68c2332090b53aac3d/greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945", size = 641073, upload-time = "2025-08-07T13:42:57.23Z" }, @@ -1033,6 +1044,8 @@ { url = "https://files.pythonhosted.org/packages/ee/43/3cecdc0349359e1a527cbf2e3e28e5f8f06d3343aaf82ca13437a9aa290f/greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671", size = 610497, upload-time = "2025-08-07T13:18:31.636Z" }, { url = "https://files.pythonhosted.org/packages/b8/19/06b6cf5d604e2c382a6f31cafafd6f33d5dea706f4db7bdab184bad2b21d/greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b", size = 1121662, upload-time = "2025-08-07T13:42:41.117Z" }, { url = "https://files.pythonhosted.org/packages/a2/15/0d5e4e1a66fab130d98168fe984c509249c833c1a3c16806b90f253ce7b9/greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae", size = 1149210, upload-time = "2025-08-07T13:18:24.072Z" }, + { url = "https://files.pythonhosted.org/packages/1c/53/f9c440463b3057485b8594d7a638bed53ba531165ef0ca0e6c364b5cc807/greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b", size = 1564759, upload-time = "2025-11-04T12:42:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/3bb4240abdd0a8d23f4f88adec746a3099f0d86bfedb623f063b2e3b4df0/greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929", size = 1634288, upload-time = "2025-11-04T12:42:21.174Z" }, { url = "https://files.pythonhosted.org/packages/0b/55/2321e43595e6801e105fcfdee02b34c0f996eb71e6ddffca6b10b7e1d771/greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b", size = 299685, upload-time = "2025-08-07T13:24:38.824Z" }, { url = "https://files.pythonhosted.org/packages/22/5c/85273fd7cc388285632b0498dbbab97596e04b154933dfe0f3e68156c68c/greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0", size = 273586, upload-time = "2025-08-07T13:16:08.004Z" }, { url = "https://files.pythonhosted.org/packages/d1/75/10aeeaa3da9332c2e761e4c50d4c3556c21113ee3f0afa2cf5769946f7a3/greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f", size = 686346, upload-time = "2025-08-07T13:42:59.944Z" }, @@ -1040,6 +1053,8 @@ { url = "https://files.pythonhosted.org/packages/dc/8b/29aae55436521f1d6f8ff4e12fb676f3400de7fcf27fccd1d4d17fd8fecd/greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1", size = 694659, upload-time = "2025-08-07T13:53:17.759Z" }, { url = "https://files.pythonhosted.org/packages/92/2e/ea25914b1ebfde93b6fc4ff46d6864564fba59024e928bdc7de475affc25/greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735", size = 695355, upload-time = "2025-08-07T13:18:34.517Z" }, { url = "https://files.pythonhosted.org/packages/72/60/fc56c62046ec17f6b0d3060564562c64c862948c9d4bc8aa807cf5bd74f4/greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337", size = 657512, upload-time = "2025-08-07T13:18:33.969Z" }, + { url = "https://files.pythonhosted.org/packages/23/6e/74407aed965a4ab6ddd93a7ded3180b730d281c77b765788419484cdfeef/greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269", size = 1612508, upload-time = "2025-11-04T12:42:23.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/da/343cd760ab2f92bac1845ca07ee3faea9fe52bee65f7bcb19f16ad7de08b/greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681", size = 1680760, upload-time = "2025-11-04T12:42:25.341Z" }, { url = "https://files.pythonhosted.org/packages/e3/a5/6ddab2b4c112be95601c13428db1d8b6608a8b6039816f2ba09c346c08fc/greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01", size = 303425, upload-time = "2025-08-07T13:32:27.59Z" }, { url = "https://files.pythonhosted.org/packages/f7/c0/93885c4106d2626bf51fdec377d6aef740dfa5c4877461889a7cf8e565cc/greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c", size = 269859, upload-time = "2025-08-07T13:16:16.003Z" }, { url = "https://files.pythonhosted.org/packages/4d/f5/33f05dc3ba10a02dedb1485870cf81c109227d3d3aa280f0e48486cac248/greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d", size = 627610, upload-time = "2025-08-07T13:43:01.345Z" }, @@ -1049,6 +1064,8 @@ { url = "https://files.pythonhosted.org/packages/6b/4c/f3de2a8de0e840ecb0253ad0dc7e2bb3747348e798ec7e397d783a3cb380/greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df", size = 582817, upload-time = "2025-08-07T13:18:35.48Z" }, { url = "https://files.pythonhosted.org/packages/89/80/7332915adc766035c8980b161c2e5d50b2f941f453af232c164cff5e0aeb/greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594", size = 1111985, upload-time = "2025-08-07T13:42:42.425Z" }, { url = "https://files.pythonhosted.org/packages/66/71/1928e2c80197353bcb9b50aa19c4d8e26ee6d7a900c564907665cf4b9a41/greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98", size = 1136137, upload-time = "2025-08-07T13:18:26.168Z" }, + { url = "https://files.pythonhosted.org/packages/4b/bf/7bd33643e48ed45dcc0e22572f650767832bd4e1287f97434943cc402148/greenlet-3.2.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:28a3c6b7cd72a96f61b0e4b2a36f681025b60ae4779cc73c1535eb5f29560b10", size = 1542941, upload-time = "2025-11-04T12:42:27.427Z" }, + { url = "https://files.pythonhosted.org/packages/9b/74/4bc433f91d0d09a1c22954a371f9df928cb85e72640870158853a83415e5/greenlet-3.2.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:52206cd642670b0b320a1fd1cbfd95bca0e043179c1d8a045f2c6109dfe973be", size = 1609685, upload-time = "2025-11-04T12:42:29.242Z" }, { url = "https://files.pythonhosted.org/packages/89/48/a5dc74dde38aeb2b15d418cec76ed50e1dd3d620ccda84d8199703248968/greenlet-3.2.4-cp39-cp39-win32.whl", hash = "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b", size = 281400, upload-time = "2025-08-07T14:02:20.263Z" }, { url = "https://files.pythonhosted.org/packages/e5/44/342c4591db50db1076b8bda86ed0ad59240e3e1da17806a4cf10a6d0e447/greenlet-3.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb", size = 298533, upload-time = "2025-08-07T13:56:34.168Z" }, ] @@ -1064,15 +1081,15 @@ [[package]] name = "h2" -version = "4.1.0" +version = "4.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "hpack" }, { name = "hyperframe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/32/fec683ddd10629ea4ea46d206752a95a2d8a48c22521edd70b142488efe1/h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb", size = 2145593, upload-time = "2021-10-05T18:27:47.18Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/17/afa56379f94ad0fe8defd37d6eb3f89a25404ffc71d4d848893d270325fc/h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1", size = 2152026, upload-time = "2025-08-23T18:12:19.778Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e5/db6d438da759efbb488c4f3fbdab7764492ff3c3f953132efa6b9f0e9e53/h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d", size = 57488, upload-time = "2021-10-05T18:27:39.977Z" }, + { url = "https://files.pythonhosted.org/packages/69/b2/119f6e6dcbd96f9069ce9a2665e0146588dc9f88f29549711853645e736a/h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd", size = 61779, upload-time = "2025-08-23T18:12:17.779Z" }, ] [[package]] @@ -1129,7 +1146,8 @@ version = "4.14.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/b6/43/50033d25ad96a7f3845f40999b4778f753c3901a11808a584fed7c00d9f5/humanize-4.14.0.tar.gz", hash = "sha256:2fa092705ea640d605c435b1ca82b2866a1b601cdf96f076d70b79a855eba90d", size = 82939, upload-time = "2025-10-15T13:04:51.214Z" } @@ -1202,7 +1220,7 @@ version = "8.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp" }, + { name = "zipp", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } wheels = [ @@ -1291,7 +1309,8 @@ version = "4.0.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] dependencies = [ @@ -1426,7 +1445,8 @@ version = "0.5.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] dependencies = [ @@ -1640,7 +1660,8 @@ version = "4.5.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", "python_full_version == '3.10.*'", ] sdist = { url = "https://files.pythonhosted.org/packages/61/33/9611380c2bdb1225fdef633e2a9610622310fed35ab11dac9620972ee088/platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312", size = 21632, upload-time = "2025-10-08T17:44:48.791Z" } @@ -2039,7 +2060,8 @@ version = "8.2.3" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.11'", + "python_full_version >= '3.13'", + "python_full_version >= '3.11' and python_full_version < '3.13'", ] dependencies = [ { name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, @@ -2166,8 +2188,8 @@ version = "0.2.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "exceptiongroup" }, - { name = "typing-extensions" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f0/8d/e218e0160cc1b692e6e0e5ba34e8865dbb171efeb5fc9a704544b3020605/taskgroup-0.2.2.tar.gz", hash = "sha256:078483ac3e78f2e3f973e2edbf6941374fbea81b9c5d0a96f51d297717f4752d", size = 11504, upload-time = "2025-01-03T09:24:13.761Z" } wheels = [ @@ -2484,7 +2506,7 @@ dependencies = [ { name = "distlib" }, { name = "filelock", version = "3.19.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, - { name = "filelock", version = "3.20.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "filelock", version = "3.20.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "platformdirs", version = "4.4.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "platformdirs", version = "4.5.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, @@ -2505,14 +2527,14 @@ [[package]] name = "werkzeug" -version = "3.1.3" +version = "3.1.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925, upload-time = "2024-11-08T15:52:18.093Z" } +sdist = { url = "https://files.pythonhosted.org/packages/45/ea/b0f8eeb287f8df9066e56e831c7824ac6bab645dd6c7a8f4b2d767944f9b/werkzeug-3.1.4.tar.gz", hash = "sha256:cd3cd98b1b92dc3b7b3995038826c68097dcb16f9baa63abe35f20eafeb9fe5e", size = 864687, upload-time = "2025-11-29T02:15:22.841Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498, upload-time = "2024-11-08T15:52:16.132Z" }, + { url = "https://files.pythonhosted.org/packages/2f/f9/9e082990c2585c744734f85bec79b5dae5df9c974ffee58fe421652c8e91/werkzeug-3.1.4-py3-none-any.whl", hash = "sha256:2ad50fb9ed09cc3af22c54698351027ace879a0b60a3b5edf5730b2f7d876905", size = 224960, upload-time = "2025-11-29T02:15:21.13Z" }, ] [[package]]
