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 2023-07-26 13:22:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-urllib3 (Old) and /work/SRC/openSUSE:Factory/.python-urllib3.new.15225 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-urllib3" Wed Jul 26 13:22:14 2023 rev:59 rq:1100699 version:2.0.4 Changes: -------- --- /work/SRC/openSUSE:Factory/python-urllib3/python-urllib3.changes 2023-07-06 18:28:09.206954409 +0200 +++ /work/SRC/openSUSE:Factory/.python-urllib3.new.15225/python-urllib3.changes 2023-07-26 13:22:32.751517700 +0200 @@ -1,0 +2,12 @@ +Tue Jul 25 18:33:23 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 2.0.4: + * Added support for union operators to ``HTTPHeaderDict`` + * Added ``BaseHTTPResponse`` to ``urllib3.__all__`` (`#3078 + * Fixed ``urllib3.connection.HTTPConnection`` to raise the + ``http.client.connect`` audit event to have the same behavior + as the standard library HTTP client + * Relied on the standard library for checking hostnames in + supported PyPy releases + +------------------------------------------------------------------- Old: ---- urllib3-2.0.3.tar.gz New: ---- urllib3-2.0.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-urllib3.spec ++++++ --- /var/tmp/diff_new_pack.Ex6zHV/_old 2023-07-26 13:22:33.699523065 +0200 +++ /var/tmp/diff_new_pack.Ex6zHV/_new 2023-07-26 13:22:33.703523088 +0200 @@ -26,7 +26,7 @@ %endif %{?sle15_python_module_pythons} Name: python-urllib3%{psuffix} -Version: 2.0.3 +Version: 2.0.4 Release: 0 Summary: HTTP library with thread-safe connection pooling, file post, and more License: MIT ++++++ urllib3-2.0.3.tar.gz -> urllib3-2.0.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/CHANGES.rst new/urllib3-2.0.4/CHANGES.rst --- old/urllib3-2.0.3/CHANGES.rst 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/CHANGES.rst 2023-07-19 16:46:02.000000000 +0200 @@ -1,3 +1,12 @@ +2.0.4 (2023-07-19) +================== + +- Added support for union operators to ``HTTPHeaderDict`` (`#2254 <https://github.com/urllib3/urllib3/issues/2254>`__) +- Added ``BaseHTTPResponse`` to ``urllib3.__all__`` (`#3078 <https://github.com/urllib3/urllib3/issues/3078>`__) +- Fixed ``urllib3.connection.HTTPConnection`` to raise the ``http.client.connect`` audit event to have the same behavior as the standard library HTTP client (`#2757 <https://github.com/urllib3/urllib3/issues/2757>`__) +- Relied on the standard library for checking hostnames in supported PyPy releases (`#3087 <https://github.com/urllib3/urllib3/issues/3087>`__) + + 2.0.3 (2023-06-07) ================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/PKG-INFO new/urllib3-2.0.4/PKG-INFO --- old/urllib3-2.0.3/PKG-INFO 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/PKG-INFO 2023-07-19 16:46:02.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: urllib3 -Version: 2.0.3 +Version: 2.0.4 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/dev-requirements.txt new/urllib3-2.0.4/dev-requirements.txt --- old/urllib3-2.0.3/dev-requirements.txt 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/dev-requirements.txt 2023-07-19 16:46:02.000000000 +0200 @@ -1,11 +1,13 @@ coverage==7.0.4 -freezegun==1.2.2 tornado==6.2 PySocks==1.7.1 -pytest==7.2.0 +pytest==7.4.0 pytest-timeout==2.1.0 trustme==0.9.0 -cryptography==39.0.1 +# We have to install at most cryptography 39.0.2 for PyPy<7.3.10 +# versions of Python 3.7, 3.8, and 3.9. +cryptography==39.0.2;implementation_name=="pypy" and implementation_version<"7.3.10" +cryptography==41.0.2;implementation_name!="pypy" or implementation_version>="7.3.10" backports.zoneinfo==0.2.1;python_version<"3.9" towncrier==21.9.0 pytest-memray==1.4.0;python_version>="3.8" and python_version<"3.12" and sys_platform!="win32" and implementation_name=="cpython" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/docs/conf.py new/urllib3-2.0.4/docs/conf.py --- old/urllib3-2.0.3/docs/conf.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/docs/conf.py 2023-07-19 16:46:02.000000000 +0200 @@ -40,9 +40,8 @@ # Open Graph metadata ogp_title = "urllib3 documentation" -ogp_site_url = "https://urllib3.readthedocs.io" ogp_type = "website" -ogp_image = "https://github.com/urllib3/urllib3/raw/main/docs/_static/banner_github.svg" +ogp_social_cards = {"image": "images/logo.png", "line_color": "#F09837"} ogp_description = "urllib3 is a user-friendly HTTP client library for Python." # Test code blocks only when explicitly specified @@ -73,6 +72,9 @@ # The name of the Pygments (syntax highlighting) style to use. pygments_style = "friendly" +# The base URL with a proper language and version. +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") + # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = "furo" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/docs/user-guide.rst new/urllib3-2.0.4/docs/user-guide.rst --- old/urllib3-2.0.3/docs/user-guide.rst 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/docs/user-guide.rst 2023-07-19 16:46:02.000000000 +0200 @@ -319,28 +319,27 @@ JSON ~~~~ -You can send a JSON request by specifying the data as ``json`` argument, -urllib3 automatically encodes data using ``json`` module with ``UTF-8`` -encoding. Also by default ``"Content-Type"`` in headers is set to -``"application/json"`` if not specified when calling -:meth:`~urllib3.PoolManager.request`: +To send JSON in the body of a request, provide the data in the ``json`` argument to +:meth:`~urllib3.PoolManager.request` and urllib3 will automatically encode the data +using the ``json`` module with ``UTF-8`` encoding. +In addition, when ``json`` is provided, the ``"Content-Type"`` in headers is set to +``"application/json"`` if not specified otherwise. .. code-block:: python import urllib3 - data = {"attribute": "value"} - resp = urllib3.request( "POST", "https://httpbin.org/post", - body=data, + json={"attribute": "value"}, headers={"Content-Type": "application/json"} ) print(resp.json()) - # {"attribute": "value"} - + # {'headers': {'Content-Type': 'application/json', ...}, + # 'data': '{"attribute":"value"}', 'json': {'attribute': 'value'}, ...} + Files & Binary Data ~~~~~~~~~~~~~~~~~~~ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/pyproject.toml new/urllib3-2.0.4/pyproject.toml --- old/urllib3-2.0.3/pyproject.toml 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/pyproject.toml 2023-07-19 16:46:02.000000000 +0200 @@ -99,11 +99,6 @@ '''default:ssl\.PROTOCOL_TLSv1_2 is deprecated:DeprecationWarning''', '''default:unclosed .*:ResourceWarning''', '''default:ssl NPN is deprecated, use ALPN instead:DeprecationWarning''', - # https://github.com/pytest-dev/pytest/issues/10977 - '''default:ast\.(Num|NameConstant|Str) is deprecated and will be removed in Python 3\.14; use ast\.Constant instead:DeprecationWarning:_pytest''', - '''default:Attribute s is deprecated and will be removed in Python 3\.14; use value instead:DeprecationWarning:_pytest''', - # https://github.com/dateutil/dateutil/issues/1284 - '''default:datetime\.utcfromtimestamp\(\) is deprecated and scheduled for removal in a future version\.*:DeprecationWarning:dateutil''', ] [tool.isort] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/src/urllib3/__init__.py new/urllib3-2.0.4/src/urllib3/__init__.py --- old/urllib3-2.0.3/src/urllib3/__init__.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/src/urllib3/__init__.py 2023-07-19 16:46:02.000000000 +0200 @@ -81,6 +81,7 @@ "make_headers", "proxy_from_url", "request", + "BaseHTTPResponse", ) logging.getLogger(__name__).addHandler(NullHandler()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/src/urllib3/_collections.py new/urllib3-2.0.4/src/urllib3/_collections.py --- old/urllib3-2.0.3/src/urllib3/_collections.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/src/urllib3/_collections.py 2023-07-19 16:46:02.000000000 +0200 @@ -432,3 +432,32 @@ if header_name in self: return potential_value in self._container[header_name.lower()][1:] return False + + def __ior__(self, other: object) -> HTTPHeaderDict: + # Supports extending a header dict in-place using operator |= + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + self.extend(maybe_constructable) + return self + + def __or__(self, other: object) -> HTTPHeaderDict: + # Supports merging header dicts using operator | + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + result = self.copy() + result.extend(maybe_constructable) + return result + + def __ror__(self, other: object) -> HTTPHeaderDict: + # Supports merging header dicts using operator | when other is on left side + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + result = type(self)(maybe_constructable) + result.extend(self) + return result diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/src/urllib3/_version.py new/urllib3-2.0.4/src/urllib3/_version.py --- old/urllib3-2.0.3/src/urllib3/_version.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/src/urllib3/_version.py 2023-07-19 16:46:02.000000000 +0200 @@ -1,4 +1,4 @@ # This file is protected via CODEOWNERS from __future__ import annotations -__version__ = "2.0.3" +__version__ = "2.0.4" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/src/urllib3/connection.py new/urllib3-2.0.4/src/urllib3/connection.py --- old/urllib3-2.0.3/src/urllib3/connection.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/src/urllib3/connection.py 2023-07-19 16:46:02.000000000 +0200 @@ -5,6 +5,7 @@ import os import re import socket +import sys import typing import warnings from http.client import HTTPConnection as _HTTPConnection @@ -76,6 +77,8 @@ _CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]") +_HAS_SYS_AUDIT = hasattr(sys, "audit") + class HTTPConnection(_HTTPConnection): """ @@ -216,6 +219,10 @@ self, f"Failed to establish a new connection: {e}" ) from e + # Audit hooks are only available in Python 3.8+ + if _HAS_SYS_AUDIT: + sys.audit("http.client.connect", self, self.host, self.port) + return sock def set_tunnel( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/src/urllib3/util/request.py new/urllib3-2.0.4/src/urllib3/util/request.py --- old/urllib3-2.0.3/src/urllib3/util/request.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/src/urllib3/util/request.py 2023-07-19 16:46:02.000000000 +0200 @@ -223,7 +223,7 @@ nonlocal body, blocksize encode = isinstance(body, io.TextIOBase) while True: - datablock = body.read(blocksize) # type: ignore[union-attr] + datablock = body.read(blocksize) if not datablock: break if encode: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/src/urllib3/util/ssl_.py new/urllib3-2.0.4/src/urllib3/util/ssl_.py --- old/urllib3-2.0.3/src/urllib3/util/ssl_.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/src/urllib3/util/ssl_.py 2023-07-19 16:46:02.000000000 +0200 @@ -26,39 +26,41 @@ def _is_bpo_43522_fixed( - implementation_name: str, version_info: _TYPE_VERSION_INFO + implementation_name: str, + version_info: _TYPE_VERSION_INFO, + pypy_version_info: _TYPE_VERSION_INFO | None, ) -> bool: - """Return True for CPython 3.8.9+, 3.9.3+ or 3.10+ where setting - SSLContext.hostname_checks_common_name to False works. - - PyPy 7.3.7 doesn't work as it doesn't ship with OpenSSL 1.1.1l+ - so we're waiting for a version of PyPy that works before - allowing this function to return 'True'. + """Return True for CPython 3.8.9+, 3.9.3+ or 3.10+ and PyPy 7.3.8+ where + setting SSLContext.hostname_checks_common_name to False works. Outside of CPython and PyPy we don't know which implementations work or not so we conservatively use our hostname matching as we know that works on all implementations. https://github.com/urllib3/urllib3/issues/2192#issuecomment-821832963 - https://foss.heptapod.net/pypy/pypy/-/issues/3539# + https://foss.heptapod.net/pypy/pypy/-/issues/3539 """ - if implementation_name != "cpython": + if implementation_name == "pypy": + # https://foss.heptapod.net/pypy/pypy/-/issues/3129 + return pypy_version_info >= (7, 3, 8) and version_info >= (3, 8) # type: ignore[operator] + elif implementation_name == "cpython": + major_minor = version_info[:2] + micro = version_info[2] + return ( + (major_minor == (3, 8) and micro >= 9) + or (major_minor == (3, 9) and micro >= 3) + or major_minor >= (3, 10) + ) + else: # Defensive: return False - major_minor = version_info[:2] - micro = version_info[2] - return ( - (major_minor == (3, 8) and micro >= 9) - or (major_minor == (3, 9) and micro >= 3) - or major_minor >= (3, 10) - ) - def _is_has_never_check_common_name_reliable( openssl_version: str, openssl_version_number: int, implementation_name: str, version_info: _TYPE_VERSION_INFO, + pypy_version_info: _TYPE_VERSION_INFO | None, ) -> bool: # As of May 2023, all released versions of LibreSSL fail to reject certificates with # only common names, see https://github.com/urllib3/urllib3/pull/3024 @@ -71,7 +73,7 @@ return is_openssl and ( is_openssl_issue_14579_fixed - or _is_bpo_43522_fixed(implementation_name, version_info) + or _is_bpo_43522_fixed(implementation_name, version_info, pypy_version_info) ) @@ -117,6 +119,7 @@ OPENSSL_VERSION_NUMBER, sys.implementation.name, sys.version_info, + sys.pypy_version_info if sys.implementation.name == "pypy" else None, # type: ignore[attr-defined] ): HAS_NEVER_CHECK_COMMON_NAME = False @@ -341,7 +344,7 @@ try: context.hostname_checks_common_name = False - except AttributeError: + except AttributeError: # Defensive: for CPython < 3.8.9 and 3.9.3; for PyPy < 7.3.8 pass # Enable logging of TLS session keys via defacto standard environment variable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/test/test_collections.py new/urllib3-2.0.4/test/test_collections.py --- old/urllib3-2.0.3/test/test_collections.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/test/test_collections.py 2023-07-19 16:46:02.000000000 +0200 @@ -423,3 +423,32 @@ d._container[marker] = ["some", "strings"] # type: ignore[index] assert marker not in d assert marker in d._container + + def test_union(self, d: HTTPHeaderDict) -> None: + to_merge = {"Cookie": "tim-tam"} + result = d | to_merge + assert result == HTTPHeaderDict({"Cookie": "foo, bar, tim-tam"}) + assert to_merge == {"Cookie": "tim-tam"} + assert d == HTTPHeaderDict({"Cookie": "foo, bar"}) + + def test_union_rhs(self, d: HTTPHeaderDict) -> None: + to_merge = {"Cookie": "tim-tam"} + result = to_merge | d + assert result == HTTPHeaderDict({"Cookie": "tim-tam, foo, bar"}) + assert to_merge == {"Cookie": "tim-tam"} + assert d == HTTPHeaderDict({"Cookie": "foo, bar"}) + + def test_inplace_union(self, d: HTTPHeaderDict) -> None: + to_merge = {"Cookie": "tim-tam"} + d |= to_merge + assert d == HTTPHeaderDict({"Cookie": "foo, bar, tim-tam"}) + + def test_union_with_unsupported_type(self, d: HTTPHeaderDict) -> None: + with pytest.raises(TypeError, match="unsupported operand type.*'int'"): + d | 42 + with pytest.raises(TypeError, match="unsupported operand type.*'float'"): + 3.14 | d + + def test_inplace_union_with_unsupported_type(self, d: HTTPHeaderDict) -> None: + with pytest.raises(TypeError, match="unsupported operand type.*'NoneType'"): + d |= None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/test/test_retry.py new/urllib3-2.0.4/test/test_retry.py --- old/urllib3-2.0.3/test/test_retry.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/test/test_retry.py 2023-07-19 16:46:02.000000000 +0200 @@ -1,9 +1,9 @@ from __future__ import annotations +import datetime from test import DUMMY_POOL from unittest import mock -import freezegun # type: ignore[import] import pytest from urllib3.exceptions import ( @@ -400,9 +400,12 @@ ) -> None: retry = Retry(respect_retry_after_header=respect_retry_after_header) - with freezegun.freeze_time("2019-06-03 11:00:00", tz_offset=0), mock.patch( - "time.sleep" - ) as sleep_mock: + with mock.patch( + "time.time", + return_value=datetime.datetime( + 2019, 6, 3, 11, tzinfo=datetime.timezone.utc + ).timestamp(), + ), mock.patch("time.sleep") as sleep_mock: # for the default behavior, it must be in RETRY_AFTER_STATUS_CODES response = HTTPResponse( status=503, headers={"Retry-After": retry_after_header} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/test/test_util.py new/urllib3-2.0.4/test/test_util.py --- old/urllib3-2.0.3/test/test_util.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/test/test_util.py 2023-07-19 16:46:02.000000000 +0200 @@ -1068,19 +1068,22 @@ warn.assert_not_called() @pytest.mark.parametrize( - "openssl_version, openssl_version_number, implementation_name, version_info, reliable", + "openssl_version, openssl_version_number, implementation_name, version_info, pypy_version_info, reliable", [ # OpenSSL and Python OK -> reliable - ("OpenSSL 1.1.1", 0x101010CF, "cpython", (3, 9, 3), True), + ("OpenSSL 1.1.1", 0x101010CF, "cpython", (3, 9, 3), None, True), # Python OK -> reliable - ("OpenSSL 1.1.1", 0x10101000, "cpython", (3, 9, 3), True), - ("OpenSSL 1.1.1", 0x10101000, "pypy", (3, 6, 9), False), + ("OpenSSL 1.1.1", 0x10101000, "cpython", (3, 9, 3), None, True), + # PyPy: depends on the version + ("OpenSSL 1.1.1", 0x10101000, "pypy", (3, 6, 9), (7, 3, 7), False), + ("OpenSSL 1.1.1", 0x10101000, "pypy", (3, 7, 13), (7, 3, 9), False), + ("OpenSSL 1.1.1", 0x101010CF, "pypy", (3, 8, 12), (7, 3, 8), True), # OpenSSL OK -> reliable - ("OpenSSL 1.1.1", 0x101010CF, "cpython", (3, 9, 2), True), + ("OpenSSL 1.1.1", 0x101010CF, "cpython", (3, 9, 2), None, True), # not OpenSSSL -> unreliable - ("LibreSSL 2.8.3", 0x101010CF, "cpython", (3, 10, 0), False), + ("LibreSSL 2.8.3", 0x101010CF, "cpython", (3, 10, 0), None, False), # old OpenSSL and old Python, unreliable - ("OpenSSL 1.1.0", 0x10101000, "cpython", (3, 9, 2), False), + ("OpenSSL 1.1.0", 0x10101000, "cpython", (3, 9, 2), None, False), ], ) def test_is_has_never_check_common_name_reliable( @@ -1089,6 +1092,7 @@ openssl_version_number: int, implementation_name: str, version_info: _TYPE_VERSION_INFO, + pypy_version_info: _TYPE_VERSION_INFO | None, reliable: bool, ) -> None: assert ( @@ -1097,6 +1101,7 @@ openssl_version_number, implementation_name, version_info, + pypy_version_info, ) == reliable ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/test/with_dummyserver/test_connection.py new/urllib3-2.0.4/test/with_dummyserver/test_connection.py --- old/urllib3-2.0.3/test/with_dummyserver/test_connection.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/test/with_dummyserver/test_connection.py 2023-07-19 16:46:02.000000000 +0200 @@ -1,7 +1,9 @@ from __future__ import annotations +import sys import typing from http.client import ResponseNotReady +from unittest import mock import pytest @@ -33,6 +35,19 @@ assert isinstance(response, HTTPResponse) +@pytest.mark.skipif(not hasattr(sys, "audit"), reason="requires python 3.8+") +@mock.patch("urllib3.connection.sys.audit") +def test_audit_event(audit_mock: mock.Mock, pool: HTTPConnectionPool) -> None: + conn = pool._get_conn() + conn.request("GET", "/") + audit_mock.assert_any_call("http.client.connect", conn, conn.host, conn.port) + # Ensure the event is raised only once. + connect_events = [ + call for call in audit_mock.mock_calls if call.args[0] == "http.client.connect" + ] + assert len(connect_events) == 1 + + def test_does_not_release_conn(pool: HTTPConnectionPool) -> None: conn = pool._get_conn() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/urllib3-2.0.3/test/with_dummyserver/test_poolmanager.py new/urllib3-2.0.4/test/with_dummyserver/test_poolmanager.py --- old/urllib3-2.0.3/test/with_dummyserver/test_poolmanager.py 2023-06-07 12:13:12.000000000 +0200 +++ new/urllib3-2.0.4/test/with_dummyserver/test_poolmanager.py 2023-07-19 16:46:02.000000000 +0200 @@ -1,6 +1,7 @@ from __future__ import annotations import gzip +import typing from test import LONG_TIMEOUT from unittest import mock @@ -379,6 +380,28 @@ ["Extra", "extra"], ] + def test_merge_headers_with_pool_manager_headers(self) -> None: + headers = HTTPHeaderDict() + headers.add("Cookie", "choc-chip") + headers.add("Cookie", "oatmeal-raisin") + orig = headers.copy() + added_headers = {"Cookie": "tim-tam"} + + with PoolManager(headers=headers) as http: + r = http.request( + "GET", + f"{self.base_url}/multi_headers", + headers=typing.cast(HTTPHeaderDict, http.headers) | added_headers, + ) + returned_headers = r.json()["headers"] + assert returned_headers[-3:] == [ + ["Cookie", "choc-chip"], + ["Cookie", "oatmeal-raisin"], + ["Cookie", "tim-tam"], + ] + # make sure the pool headers weren't modified + assert http.headers == orig + def test_headers_http_multi_header_multipart(self) -> None: headers = HTTPHeaderDict() headers.add("Multi", "1")