From 8debaf81c3b802fac6671025c8e37d5f7f73c33d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 14:10:25 -1000 Subject: [PATCH 01/28] Move lru cache from inside of _encode_host to outside Everything ended up being cached on the inside of the function so it makes more sense to have a single cache for hosts --- tests/test_cache.py | 8 ++- yarl/_url.py | 160 ++++++++++++++++++++------------------------ 2 files changed, 80 insertions(+), 88 deletions(-) diff --git a/tests/test_cache.py b/tests/test_cache.py index 9b0e75a35..da06fc77f 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -13,7 +13,13 @@ def test_cache_clear() -> None: def test_cache_info() -> None: info = yarl.cache_info() - assert info.keys() == {"idna_encode", "idna_decode", "ip_address", "host_validate"} + assert info.keys() == { + "idna_encode", + "idna_decode", + "ip_address", + "host_validate", + "encode_host", + } def test_cache_configure_default() -> None: diff --git a/yarl/_url.py b/yarl/_url.py index bb9e3d436..906dce4b2 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -88,6 +88,7 @@ class CacheInfo(TypedDict): idna_decode: _CacheInfo ip_address: _CacheInfo host_validate: _CacheInfo + encode_host: _CacheInfo class _InternalURLCache(TypedDict, total=False): @@ -265,53 +266,6 @@ def _parse_host(host: str) -> tuple[bool, str, Union[bool, None], str, str, str] return False, lower_host, is_ascii, "", "", "" -def _encode_host(host: str, validate_host: bool) -> str: - """Encode host part of URL.""" - looks_like_ip, lower_host, is_ascii, raw_ip, sep, zone = _parse_host(host) - if looks_like_ip: - # If it looks like an IP, we check with _ip_compressed_version - # and fall-through if its not an IP address. This is a performance - # optimization to avoid parsing IP addresses as much as possible - # because it is orders of magnitude slower than almost any other - # operation this library does. - # Might be an IP address, check it - # - # IP Addresses can look like: - # https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2 - # - 127.0.0.1 (last character is a digit) - # - 2001:db8::ff00:42:8329 (contains a colon) - # - 2001:db8::ff00:42:8329%eth0 (contains a colon) - # - [2001:db8::ff00:42:8329] (contains a colon -- brackets should - # have been removed before it gets here) - # Rare IP Address formats are not supported per: - # https://datatracker.ietf.org/doc/html/rfc3986#section-7.4 - # - # IP parsing is slow, so its wrapped in an LRU - try: - host, version = _ip_compressed_version(raw_ip) - except ValueError: - pass - else: - # These checks should not happen in the - # LRU to keep the cache size small - if version == 6: - return f"[{host}%{zone}]" if sep else f"[{host}]" - return f"{host}%{zone}" if sep else host - - # IDNA encoding is slow, - # skip it for ASCII-only strings - # Don't move the check into _idna_encode() helper - # to reduce the cache size - if is_ascii: - # Check for invalid characters explicitly; _idna_encode() does this - # for non-ascii host names. - if validate_host: - _host_validate(lower_host) - return lower_host - - return _idna_encode(lower_host) - - @lru_cache # match the same size as urlsplit def _split_netloc( netloc: str, @@ -1737,7 +1691,7 @@ def _human_quote(s: Union[str, None], unsafe: str) -> Union[str, None]: return "".join(c if c.isprintable() else quote(c) for c in s) -_MAXCACHE = 256 +_MAXCACHE = 512 @lru_cache(_MAXCACHE) @@ -1749,55 +1703,81 @@ def _idna_decode(raw: str) -> str: @lru_cache(_MAXCACHE) -def _idna_encode(host: str) -> str: +def _encode_host(host: str, validate_host: bool) -> str: + """Encode host part of URL.""" + # If the host ends with a digit or contains a colon, its likely + # an IP address. + if host and (host[-1].isdigit() or ":" in host): + raw_ip, sep, zone = host.partition("%") + # If it looks like an IP, we check with _ip_compressed_version + # and fall-through if its not an IP address. This is a performance + # optimization to avoid parsing IP addresses as much as possible + # because it is orders of magnitude slower than almost any other + # operation this library does. + # Might be an IP address, check it + # + # IP Addresses can look like: + # https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2 + # - 127.0.0.1 (last character is a digit) + # - 2001:db8::ff00:42:8329 (contains a colon) + # - 2001:db8::ff00:42:8329%eth0 (contains a colon) + # - [2001:db8::ff00:42:8329] (contains a colon -- brackets should + # have been removed before it gets here) + # Rare IP Address formats are not supported per: + # https://datatracker.ietf.org/doc/html/rfc3986#section-7.4 + # + # IP parsing is slow, so its wrapped in an LRU + try: + ip = ip_address(raw_ip) + except ValueError: + pass + else: + # These checks should not happen in the + # LRU to keep the cache size small + host = ip.compressed + if ip.version == 6: + return f"[{host}%{zone}]" if sep else f"[{host}]" + return f"{host}%{zone}" if sep else host + + # IDNA encoding is slow, skip it for ASCII-only strings + if host.isascii(): + # Check for invalid characters explicitly; _idna_encode() does this + # for non-ascii host names. + if validate_host and (invalid := _not_reg_name.search(host)): + value, pos, extra = invalid.group(), invalid.start(), "" + if value == "@" or (value == ":" and "@" in host[pos:]): + # this looks like an authority string + extra = ( + ", if the value includes a username or password, " + "use 'authority' instead of 'host'" + ) + raise ValueError( + f"Host {host!r} cannot contain {value!r} (at position " f"{pos}){extra}" + ) from None + return host.lower() + try: - return idna.encode(host, uts46=True).decode("ascii") + return idna.encode(host.lower(), uts46=True).decode("ascii") except UnicodeError: return host.encode("idna").decode("ascii") -@lru_cache(_MAXCACHE) -def _ip_compressed_version(raw_ip: str) -> tuple[str, int]: - """Return compressed version of IP address and its version.""" - ip = ip_address(raw_ip) - return ip.compressed, ip.version - - -@lru_cache(_MAXCACHE) -def _host_validate(host: str) -> None: - """Validate an ascii host name.""" - invalid = _not_reg_name.search(host) - if invalid is None: - return - value, pos, extra = invalid.group(), invalid.start(), "" - if value == "@" or (value == ":" and "@" in host[pos:]): - # this looks like an authority string - extra = ( - ", if the value includes a username or password, " - "use 'authority' instead of 'host'" - ) - raise ValueError( - f"Host {host!r} cannot contain {value!r} (at position " f"{pos}){extra}" - ) from None - - @rewrite_module def cache_clear() -> None: """Clear all LRU caches.""" _idna_decode.cache_clear() - _idna_encode.cache_clear() - _ip_compressed_version.cache_clear() - _host_validate.cache_clear() + _encode_host.cache_clear() @rewrite_module def cache_info() -> CacheInfo: """Report cache statistics.""" return { - "idna_encode": _idna_encode.cache_info(), + "idna_encode": _encode_host.cache_info(), "idna_decode": _idna_decode.cache_info(), - "ip_address": _ip_compressed_version.cache_info(), - "host_validate": _host_validate.cache_info(), + "ip_address": _encode_host.cache_info(), + "host_validate": _encode_host.cache_info(), + "encode_host": _encode_host.cache_info(), } @@ -1808,13 +1788,19 @@ def cache_configure( idna_decode_size: Union[int, None] = _MAXCACHE, ip_address_size: Union[int, None] = _MAXCACHE, host_validate_size: Union[int, None] = _MAXCACHE, + encode_host_size: Union[int, None] = _MAXCACHE, ) -> None: """Configure LRU cache sizes.""" - global _idna_decode, _idna_encode, _ip_compressed_version, _host_validate + global _idna_decode, _encode_host + # idna_encode_size, ip_address_size, host_validate_size are no longer + # used, but are kept for backwards compatibility. + if encode_host_size is not None: + for size in (idna_encode_size, ip_address_size, host_validate_size): + if size is None: + encode_host_size = None + break + elif size > encode_host_size: + encode_host_size = size - _idna_encode = lru_cache(idna_encode_size)(_idna_encode.__wrapped__) + _encode_host = lru_cache(encode_host_size)(_encode_host.__wrapped__) _idna_decode = lru_cache(idna_decode_size)(_idna_decode.__wrapped__) - _ip_compressed_version = lru_cache(ip_address_size)( - _ip_compressed_version.__wrapped__ - ) - _host_validate = lru_cache(host_validate_size)(_host_validate.__wrapped__) From 056f2e564cb3612fc9a00b08c6d3a52900c0ca75 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 14:40:50 -1000 Subject: [PATCH 02/28] remove unused --- yarl/_url.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/yarl/_url.py b/yarl/_url.py index 906dce4b2..68d2dc543 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -241,31 +241,6 @@ def _check_netloc(netloc: str) -> None: ) -@lru_cache # match the same size as urlsplit -def _parse_host(host: str) -> tuple[bool, str, Union[bool, None], str, str, str]: - """Parse host into parts - - Returns a tuple of: - - True if the host looks like an IP address, False otherwise. - - Lowercased host - - True if the host is ASCII-only, False otherwise. - - Raw IP address - - Separator between IP address and zone - - Zone part of the IP address - """ - lower_host = host.lower() - is_ascii = host.isascii() - - # If the host ends with a digit or contains a colon, its likely - # an IP address. - if host and (host[-1].isdigit() or ":" in host): - if "%" in host: - return True, lower_host, is_ascii, *host.partition("%") - return True, lower_host, is_ascii, host, "", "" - - return False, lower_host, is_ascii, "", "", "" - - @lru_cache # match the same size as urlsplit def _split_netloc( netloc: str, From dea6b8eb83ed6da1729f3a7a6d367165ecc50b4b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:25:39 -1000 Subject: [PATCH 03/28] docs --- docs/api.rst | 36 ++++++++++++++++++++++++++---------- yarl/_url.py | 26 +++++++++++++++++++++----- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index b7b80cf61..7999d2d4c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1039,18 +1039,18 @@ Cache control IDNA conversion, host validation, and IP Address parsing used for host encoding are quite expensive operations, that's why the ``yarl`` -library caches these calls by storing last ``256`` results in the +library caches these calls by storing last ``512`` results in the global LRU cache. .. function:: cache_clear() - Clear IDNA, host validation, and IP Address caches. + Clear IDNA and host encoding cache. .. function:: cache_info() Return a dictionary with ``"idna_encode"``, ``"idna_decode"``, ``"ip_address"``, - and ``"host_validate"`` keys, each value + ``"host_validate"``, and ``"encode_host"`` keys, each value points to corresponding ``CacheInfo`` structure (see :func:`functools.lru_cache` for details): @@ -1058,22 +1058,38 @@ global LRU cache. :options: +SKIP >>> yarl.cache_info() - {'idna_encode': CacheInfo(hits=5, misses=5, maxsize=256, currsize=5), - 'idna_decode': CacheInfo(hits=24, misses=15, maxsize=256, currsize=15), - 'ip_address': CacheInfo(hits=46933, misses=84, maxsize=256, currsize=101), - 'host_validate': CacheInfo(hits=0, misses=0, maxsize=256, currsize=0)} + {'idna_encode': CacheInfo(hits=5, misses=5, maxsize=512, currsize=5), + 'idna_decode': CacheInfo(hits=24, misses=15, maxsize=512, currsize=15), + 'ip_address': CacheInfo(hits=46933, misses=84, maxsize=512, currsize=101), + 'host_validate': CacheInfo(hits=0, misses=0, maxsize=512, currsize=0), + 'encode_host': CacheInfo(hits=0, misses=0, maxsize=512, currsize=0)} + :: versionchanged:: 1.16 + The ``idna_encode``, ``ip_address``, and ``host_validate`` + are deprecated in favor of a single ``encode_host`` cache. -.. function:: cache_configure(*, idna_encode_size=256, idna_decode_size=256, ip_address_size=256, host_validate_size=256) +.. function:: cache_configure( + *, + idna_encode_size=512, + idna_decode_size=512, + ip_address_size=512, + host_validate_size=512, + encode_host=512 + ) - Set the IP Address, host validation, and IDNA encode and - decode cache sizes (``256`` for each by default). + Set the IP Address, host validation, and IDNA encode, host encode and + decode cache sizes (``512`` for each by default). Pass ``None`` to make the corresponding cache unbounded (may speed up host encoding operation a little but the memory footprint can be very high, please use with caution). + :: versionchanged:: 1.16 + + The ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` + are deprecated in favor of a single ``encode_host`` cache. + References ---------- diff --git a/yarl/_url.py b/yarl/_url.py index 68d2dc543..8ea135bd6 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -1756,13 +1756,16 @@ def cache_info() -> CacheInfo: } +_SENTINEL = object() + + @rewrite_module def cache_configure( *, - idna_encode_size: Union[int, None] = _MAXCACHE, + idna_encode_size: Union[int, None, object] = _SENTINEL, idna_decode_size: Union[int, None] = _MAXCACHE, - ip_address_size: Union[int, None] = _MAXCACHE, - host_validate_size: Union[int, None] = _MAXCACHE, + ip_address_size: Union[int, None, object] = _SENTINEL, + host_validate_size: Union[int, None, object] = _SENTINEL, encode_host_size: Union[int, None] = _MAXCACHE, ) -> None: """Configure LRU cache sizes.""" @@ -1774,8 +1777,21 @@ def cache_configure( if size is None: encode_host_size = None break - elif size > encode_host_size: - encode_host_size = size + elif size is _SENTINEL: + warnings.warn( + "cache_configure() no longer accepts idna_encode_size, " + "ip_address_size, or host_validate_size arguments, " + "they are used to set the encode_host_size instead " + "and will be removed in the future", + DeprecationWarning, + stacklevel=2, + ) + real_size = _MAXCACHE + else: + assert isinstance(size, int) + real_size = size + if real_size > encode_host_size: + encode_host_size = real_size _encode_host = lru_cache(encode_host_size)(_encode_host.__wrapped__) _idna_decode = lru_cache(idna_decode_size)(_idna_decode.__wrapped__) From 0a4a7314298d7f89ad1a05fa36d28d377216c6b9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:26:10 -1000 Subject: [PATCH 04/28] docs --- yarl/_url.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/yarl/_url.py b/yarl/_url.py index 8ea135bd6..1f699265b 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -1786,12 +1786,11 @@ def cache_configure( DeprecationWarning, stacklevel=2, ) - real_size = _MAXCACHE - else: + size = _MAXCACHE + if TYPE_CHECKING: assert isinstance(size, int) - real_size = size - if real_size > encode_host_size: - encode_host_size = real_size + if size > encode_host_size: + encode_host_size = size _encode_host = lru_cache(encode_host_size)(_encode_host.__wrapped__) _idna_decode = lru_cache(idna_decode_size)(_idna_decode.__wrapped__) From 944526c5c647cedfd13adef087cca87299752946 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:27:21 -1000 Subject: [PATCH 05/28] docs --- docs/api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 7999d2d4c..61dbeed35 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1066,7 +1066,7 @@ global LRU cache. :: versionchanged:: 1.16 - The ``idna_encode``, ``ip_address``, and ``host_validate`` + ``idna_encode``, ``ip_address``, and ``host_validate`` are deprecated in favor of a single ``encode_host`` cache. .. function:: cache_configure( @@ -1087,7 +1087,7 @@ global LRU cache. :: versionchanged:: 1.16 - The ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` + ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` are deprecated in favor of a single ``encode_host`` cache. References From 25c1377da9327f37037f65a6add3e7a0fe76048d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:29:45 -1000 Subject: [PATCH 06/28] docs syntax fixes --- docs/api.rst | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 61dbeed35..3ce8249b6 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1064,19 +1064,12 @@ global LRU cache. 'host_validate': CacheInfo(hits=0, misses=0, maxsize=512, currsize=0), 'encode_host': CacheInfo(hits=0, misses=0, maxsize=512, currsize=0)} - :: versionchanged:: 1.16 + .. versionchanged:: 1.16 ``idna_encode``, ``ip_address``, and ``host_validate`` are deprecated in favor of a single ``encode_host`` cache. -.. function:: cache_configure( - *, - idna_encode_size=512, - idna_decode_size=512, - ip_address_size=512, - host_validate_size=512, - encode_host=512 - ) +.. function:: cache_configure(*, idna_encode_size=512, idna_decode_size=512, ip_address_size=512, host_validate_size=512, encode_host=512) Set the IP Address, host validation, and IDNA encode, host encode and decode cache sizes (``512`` for each by default). @@ -1085,7 +1078,7 @@ global LRU cache. operation a little but the memory footprint can be very high, please use with caution). - :: versionchanged:: 1.16 + .. versionchanged:: 1.16 ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` are deprecated in favor of a single ``encode_host`` cache. From e9271f456f04ee02f0585d3f6ef6d2b5b4c127f8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:41:11 -1000 Subject: [PATCH 07/28] coverage --- tests/test_cache.py | 31 +++++++++++++++++++++++++------ yarl/_url.py | 9 +++++---- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/tests/test_cache.py b/tests/test_cache.py index da06fc77f..bc155f5a4 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -1,3 +1,5 @@ +import pytest + import yarl # Don't check the actual behavior but make sure that calls are allowed @@ -28,17 +30,34 @@ def test_cache_configure_default() -> None: def test_cache_configure_None() -> None: yarl.cache_configure( - idna_encode_size=None, idna_decode_size=None, - ip_address_size=None, - host_validate_size=None, + encode_host_size=None, ) def test_cache_configure_explicit() -> None: yarl.cache_configure( - idna_encode_size=128, idna_decode_size=128, - ip_address_size=128, - host_validate_size=128, + encode_host_size=128, + ) + + +def test_cache_configure_waring() -> None: + msg = ( + r"cache_configure\(\) no longer accepts idna_encode_size, ip_address_size, " + r"or host_validate_size arguments, they are used to set the " + r"encode_host_size instead and will be removed in the future" ) + with pytest.warns(DeprecationWarning, match=msg): + yarl.cache_configure( + idna_encode_size=1024, + idna_decode_size=1024, + ip_address_size=1024, + host_validate_size=1024, + ) + + assert yarl.cache_info()["encode_host"].maxsize == 1024 + with pytest.warns(DeprecationWarning, match=msg): + yarl.cache_configure(host_validate_size=None) + + assert yarl.cache_info()["encode_host"].maxsize is None diff --git a/yarl/_url.py b/yarl/_url.py index 1f699265b..b976b1026 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -1774,10 +1774,7 @@ def cache_configure( # used, but are kept for backwards compatibility. if encode_host_size is not None: for size in (idna_encode_size, ip_address_size, host_validate_size): - if size is None: - encode_host_size = None - break - elif size is _SENTINEL: + if size is not _SENTINEL: warnings.warn( "cache_configure() no longer accepts idna_encode_size, " "ip_address_size, or host_validate_size arguments, " @@ -1786,6 +1783,10 @@ def cache_configure( DeprecationWarning, stacklevel=2, ) + if size is None: + encode_host_size = None + break + elif size is _SENTINEL: size = _MAXCACHE if TYPE_CHECKING: assert isinstance(size, int) From b0311b6baf5006c093b2ecd2fd578b7e888a52bd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:51:58 -1000 Subject: [PATCH 08/28] changelog --- CHANGES/1348.breaking.rst | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CHANGES/1348.breaking.rst diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst new file mode 100644 index 000000000..61dc44314 --- /dev/null +++ b/CHANGES/1348.breaking.rst @@ -0,0 +1,5 @@ +Migrate to using a single cache for encoding hosts -- by :user:`bdraco` + +Passing ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host`` parameter and will be removed in a future release. + +For backwards compatibility, the old parameters affect the ``encode_host`` cache size. From 60ae8236c6421596849e689695b74f51b0cb1d70 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:52:15 -1000 Subject: [PATCH 09/28] bump ver --- yarl/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarl/__init__.py b/yarl/__init__.py index 7ca6ae2a2..44eeab3f2 100644 --- a/yarl/__init__.py +++ b/yarl/__init__.py @@ -8,7 +8,7 @@ cache_info, ) -__version__ = "1.15.6.dev0" +__version__ = "1.16.0.dev0" __all__ = ( "URL", From 60c1b74d2a30ad50c7abdfef09554a419cf11d63 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:52:50 -1000 Subject: [PATCH 10/28] Update CHANGES/1348.breaking.rst --- CHANGES/1348.breaking.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst index 61dc44314..b70d70fb5 100644 --- a/CHANGES/1348.breaking.rst +++ b/CHANGES/1348.breaking.rst @@ -1,4 +1,4 @@ -Migrate to using a single cache for encoding hosts -- by :user:`bdraco` +Migrated to using a single cache for encoding hosts -- by :user:`bdraco` Passing ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host`` parameter and will be removed in a future release. From 1441defb1f6ebc7e510754e5361a71a825719268 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:54:17 -1000 Subject: [PATCH 11/28] bump ver --- CHANGES/1348.breaking.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst index 61dc44314..2d539930c 100644 --- a/CHANGES/1348.breaking.rst +++ b/CHANGES/1348.breaking.rst @@ -2,4 +2,6 @@ Migrate to using a single cache for encoding hosts -- by :user:`bdraco` Passing ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host`` parameter and will be removed in a future release. +The default cache size has been changed from ``256`` to ``512`` to account for combining the caches. + For backwards compatibility, the old parameters affect the ``encode_host`` cache size. From fb219d2310eb3a712c15be56a9083eef240ded2a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 15:56:38 -1000 Subject: [PATCH 12/28] Update yarl/_url.py --- yarl/_url.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarl/_url.py b/yarl/_url.py index b976b1026..ab67ecb1a 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -1727,7 +1727,7 @@ def _encode_host(host: str, validate_host: bool) -> str: "use 'authority' instead of 'host'" ) raise ValueError( - f"Host {host!r} cannot contain {value!r} (at position " f"{pos}){extra}" + f"Host {host!r} cannot contain {value!r} (at position {pos}){extra}" ) from None return host.lower() From 0a7fdb824ab63fd8a2b13ce835591e139c17ba8f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:02:15 -1000 Subject: [PATCH 13/28] keep _idna_encode --- CHANGES/1348.breaking.rst | 2 +- docs/api.rst | 4 ++-- tests/test_cache.py | 2 ++ yarl/_url.py | 27 +++++++++++++++++---------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst index 62070a2c8..fafc91f20 100644 --- a/CHANGES/1348.breaking.rst +++ b/CHANGES/1348.breaking.rst @@ -1,6 +1,6 @@ Migrated to using a single cache for encoding hosts -- by :user:`bdraco` -Passing ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host`` parameter and will be removed in a future release. +Passing ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host`` parameter and will be removed in a future release. The default cache size has been changed from ``256`` to ``512`` to account for combining the caches. diff --git a/docs/api.rst b/docs/api.rst index 3ce8249b6..c833d245b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1066,7 +1066,7 @@ global LRU cache. .. versionchanged:: 1.16 - ``idna_encode``, ``ip_address``, and ``host_validate`` + ``ip_address``, and ``host_validate`` are deprecated in favor of a single ``encode_host`` cache. .. function:: cache_configure(*, idna_encode_size=512, idna_decode_size=512, ip_address_size=512, host_validate_size=512, encode_host=512) @@ -1080,7 +1080,7 @@ global LRU cache. .. versionchanged:: 1.16 - ``idna_encode_size``, ``ip_address_size``, and ``host_validate_size`` + ``ip_address_size`` and ``host_validate_size`` are deprecated in favor of a single ``encode_host`` cache. References diff --git a/tests/test_cache.py b/tests/test_cache.py index bc155f5a4..4a61ff4f3 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -31,6 +31,7 @@ def test_cache_configure_default() -> None: def test_cache_configure_None() -> None: yarl.cache_configure( idna_decode_size=None, + idna_encode_size=None, encode_host_size=None, ) @@ -38,6 +39,7 @@ def test_cache_configure_None() -> None: def test_cache_configure_explicit() -> None: yarl.cache_configure( idna_decode_size=128, + idna_encode_size=128, encode_host_size=128, ) diff --git a/yarl/_url.py b/yarl/_url.py index ab67ecb1a..01fb30b3d 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -1677,6 +1677,14 @@ def _idna_decode(raw: str) -> str: return raw.encode("ascii").decode("idna") +@lru_cache(_MAXCACHE) +def _idna_encode(host: str) -> str: + try: + return idna.encode(host.lower(), uts46=True).decode("ascii") + except UnicodeError: + return host.encode("idna").decode("ascii") + + @lru_cache(_MAXCACHE) def _encode_host(host: str, validate_host: bool) -> str: """Encode host part of URL.""" @@ -1731,15 +1739,13 @@ def _encode_host(host: str, validate_host: bool) -> str: ) from None return host.lower() - try: - return idna.encode(host.lower(), uts46=True).decode("ascii") - except UnicodeError: - return host.encode("idna").decode("ascii") + return _idna_encode(host) @rewrite_module def cache_clear() -> None: """Clear all LRU caches.""" + _idna_encode.cache_clear() _idna_decode.cache_clear() _encode_host.cache_clear() @@ -1748,7 +1754,7 @@ def cache_clear() -> None: def cache_info() -> CacheInfo: """Report cache statistics.""" return { - "idna_encode": _encode_host.cache_info(), + "idna_encode": _idna_encode.cache_info(), "idna_decode": _idna_decode.cache_info(), "ip_address": _encode_host.cache_info(), "host_validate": _encode_host.cache_info(), @@ -1769,15 +1775,15 @@ def cache_configure( encode_host_size: Union[int, None] = _MAXCACHE, ) -> None: """Configure LRU cache sizes.""" - global _idna_decode, _encode_host - # idna_encode_size, ip_address_size, host_validate_size are no longer + global _idna_decode, _idna_encode, _encode_host + # ip_address_size, host_validate_size are no longer # used, but are kept for backwards compatibility. if encode_host_size is not None: - for size in (idna_encode_size, ip_address_size, host_validate_size): + for size in (ip_address_size, host_validate_size): if size is not _SENTINEL: warnings.warn( - "cache_configure() no longer accepts idna_encode_size, " - "ip_address_size, or host_validate_size arguments, " + "cache_configure() no longer accepts the " + "ip_address_size or host_validate_size arguments, " "they are used to set the encode_host_size instead " "and will be removed in the future", DeprecationWarning, @@ -1795,3 +1801,4 @@ def cache_configure( _encode_host = lru_cache(encode_host_size)(_encode_host.__wrapped__) _idna_decode = lru_cache(idna_decode_size)(_idna_decode.__wrapped__) + _idna_encode = lru_cache(idna_decode_size)(_idna_encode.__wrapped__) From 61ad89ac2a60027d66455eb5b10f3a659f9ce726 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:03:12 -1000 Subject: [PATCH 14/28] keep _idna_encode --- tests/test_cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cache.py b/tests/test_cache.py index 4a61ff4f3..c79f554c8 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -46,7 +46,7 @@ def test_cache_configure_explicit() -> None: def test_cache_configure_waring() -> None: msg = ( - r"cache_configure\(\) no longer accepts idna_encode_size, ip_address_size, " + r"cache_configure\(\) no longer accepts the ip_address_size " r"or host_validate_size arguments, they are used to set the " r"encode_host_size instead and will be removed in the future" ) From 861fed756f0800e991a2e517473205053bd80a9e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:04:33 -1000 Subject: [PATCH 15/28] revert to 256 to check benchmark --- yarl/_url.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarl/_url.py b/yarl/_url.py index 01fb30b3d..9755205fd 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -1666,7 +1666,7 @@ def _human_quote(s: Union[str, None], unsafe: str) -> Union[str, None]: return "".join(c if c.isprintable() else quote(c) for c in s) -_MAXCACHE = 512 +_MAXCACHE = 256 @lru_cache(_MAXCACHE) From 40a16dc1fc1aadafe77e6a5fdfb0f8c9fe211e52 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:11:41 -1000 Subject: [PATCH 16/28] split sizes --- CHANGES/1348.breaking.rst | 2 -- docs/api.rst | 10 ++++------ yarl/_url.py | 17 +++++++++-------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst index fafc91f20..4dabd0724 100644 --- a/CHANGES/1348.breaking.rst +++ b/CHANGES/1348.breaking.rst @@ -2,6 +2,4 @@ Migrated to using a single cache for encoding hosts -- by :user:`bdraco` Passing ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host`` parameter and will be removed in a future release. -The default cache size has been changed from ``256`` to ``512`` to account for combining the caches. - For backwards compatibility, the old parameters affect the ``encode_host`` cache size. diff --git a/docs/api.rst b/docs/api.rst index c833d245b..31a8d364d 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1058,10 +1058,8 @@ global LRU cache. :options: +SKIP >>> yarl.cache_info() - {'idna_encode': CacheInfo(hits=5, misses=5, maxsize=512, currsize=5), - 'idna_decode': CacheInfo(hits=24, misses=15, maxsize=512, currsize=15), - 'ip_address': CacheInfo(hits=46933, misses=84, maxsize=512, currsize=101), - 'host_validate': CacheInfo(hits=0, misses=0, maxsize=512, currsize=0), + {'idna_encode': CacheInfo(hits=5, misses=5, maxsize=256, currsize=5), + 'idna_decode': CacheInfo(hits=24, misses=15, maxsize=256, currsize=15), 'encode_host': CacheInfo(hits=0, misses=0, maxsize=512, currsize=0)} .. versionchanged:: 1.16 @@ -1069,10 +1067,10 @@ global LRU cache. ``ip_address``, and ``host_validate`` are deprecated in favor of a single ``encode_host`` cache. -.. function:: cache_configure(*, idna_encode_size=512, idna_decode_size=512, ip_address_size=512, host_validate_size=512, encode_host=512) +.. function:: cache_configure(*, idna_encode_size=256, idna_decode_size=256, encode_host=512) Set the IP Address, host validation, and IDNA encode, host encode and - decode cache sizes (``512`` for each by default). + decode cache sizes. Pass ``None`` to make the corresponding cache unbounded (may speed up host encoding operation a little but the memory footprint can be very high, diff --git a/yarl/_url.py b/yarl/_url.py index 9755205fd..2a9ef2fb0 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -1666,10 +1666,11 @@ def _human_quote(s: Union[str, None], unsafe: str) -> Union[str, None]: return "".join(c if c.isprintable() else quote(c) for c in s) -_MAXCACHE = 256 +_DEFAULT_IDNA_SIZE = 256 +_DEFAULT_ENCODE_SIZE = 512 -@lru_cache(_MAXCACHE) +@lru_cache(_DEFAULT_IDNA_SIZE) def _idna_decode(raw: str) -> str: try: return idna.decode(raw.encode("ascii")) @@ -1677,7 +1678,7 @@ def _idna_decode(raw: str) -> str: return raw.encode("ascii").decode("idna") -@lru_cache(_MAXCACHE) +@lru_cache(_DEFAULT_IDNA_SIZE) def _idna_encode(host: str) -> str: try: return idna.encode(host.lower(), uts46=True).decode("ascii") @@ -1685,7 +1686,7 @@ def _idna_encode(host: str) -> str: return host.encode("idna").decode("ascii") -@lru_cache(_MAXCACHE) +@lru_cache(_DEFAULT_ENCODE_SIZE) def _encode_host(host: str, validate_host: bool) -> str: """Encode host part of URL.""" # If the host ends with a digit or contains a colon, its likely @@ -1768,11 +1769,11 @@ def cache_info() -> CacheInfo: @rewrite_module def cache_configure( *, - idna_encode_size: Union[int, None, object] = _SENTINEL, - idna_decode_size: Union[int, None] = _MAXCACHE, + idna_encode_size: Union[int, None, object] = _DEFAULT_IDNA_SIZE, + idna_decode_size: Union[int, None] = _DEFAULT_IDNA_SIZE, ip_address_size: Union[int, None, object] = _SENTINEL, host_validate_size: Union[int, None, object] = _SENTINEL, - encode_host_size: Union[int, None] = _MAXCACHE, + encode_host_size: Union[int, None] = _DEFAULT_ENCODE_SIZE, ) -> None: """Configure LRU cache sizes.""" global _idna_decode, _idna_encode, _encode_host @@ -1793,7 +1794,7 @@ def cache_configure( encode_host_size = None break elif size is _SENTINEL: - size = _MAXCACHE + size = _DEFAULT_ENCODE_SIZE if TYPE_CHECKING: assert isinstance(size, int) if size > encode_host_size: From 7a61562c8dfc7820cfa399bd2b53d5f1518d9c84 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:16:28 -1000 Subject: [PATCH 17/28] Update docs/api.rst --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 31a8d364d..a06e54c12 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1067,7 +1067,7 @@ global LRU cache. ``ip_address``, and ``host_validate`` are deprecated in favor of a single ``encode_host`` cache. -.. function:: cache_configure(*, idna_encode_size=256, idna_decode_size=256, encode_host=512) +.. function:: cache_configure(*, idna_encode_size=256, idna_decode_size=256, encode_host_size=512) Set the IP Address, host validation, and IDNA encode, host encode and decode cache sizes. From e176f59225318a0097fe6644cade05b27eabb5ea Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:17:21 -1000 Subject: [PATCH 18/28] Apply suggestions from code review --- docs/api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index a06e54c12..9993ad139 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1069,8 +1069,8 @@ global LRU cache. .. function:: cache_configure(*, idna_encode_size=256, idna_decode_size=256, encode_host_size=512) - Set the IP Address, host validation, and IDNA encode, host encode and - decode cache sizes. + Set the IDNA encode, IDNA decode, and host encode + cache sizes. Pass ``None`` to make the corresponding cache unbounded (may speed up host encoding operation a little but the memory footprint can be very high, From e6d87443db074331f659f3abb6d335e3d870328a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:18:45 -1000 Subject: [PATCH 19/28] Update docs/api.rst --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 9993ad139..7f08d161b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1039,7 +1039,7 @@ Cache control IDNA conversion, host validation, and IP Address parsing used for host encoding are quite expensive operations, that's why the ``yarl`` -library caches these calls by storing last ``512`` results in the +library caches these calls by storing last ``256`` results in the global LRU cache. .. function:: cache_clear() From fd9432b39eb1e579f07a7b8546666c8b12789bf8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:19:49 -1000 Subject: [PATCH 20/28] split defaults --- docs/api.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 7f08d161b..a409c2d40 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1037,9 +1037,8 @@ Default port substitution Cache control ------------- -IDNA conversion, host validation, and IP Address parsing used for host -encoding are quite expensive operations, that's why the ``yarl`` -library caches these calls by storing last ``256`` results in the +IDNA conversion and host encoding encoding are quite expensive operations, +that's why the ``yarl`` library caches these calls by storing results in the global LRU cache. .. function:: cache_clear() From baa6966282ffbe30976dccca9ce39f4b2e9dc4f5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:20:17 -1000 Subject: [PATCH 21/28] Update CHANGES/1348.breaking.rst --- CHANGES/1348.breaking.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst index 4dabd0724..44b794335 100644 --- a/CHANGES/1348.breaking.rst +++ b/CHANGES/1348.breaking.rst @@ -1,5 +1,5 @@ Migrated to using a single cache for encoding hosts -- by :user:`bdraco` -Passing ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host`` parameter and will be removed in a future release. +Passing ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host_size`` parameter and will be removed in a future release. For backwards compatibility, the old parameters affect the ``encode_host`` cache size. From 0f4c4817a4a64ff7f60dc106cb111a51f652568f Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:20:35 -1000 Subject: [PATCH 22/28] Update docs/api.rst --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index a409c2d40..6da307f24 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1037,7 +1037,7 @@ Default port substitution Cache control ------------- -IDNA conversion and host encoding encoding are quite expensive operations, +IDNA conversion and host encoding are quite expensive operations, that's why the ``yarl`` library caches these calls by storing results in the global LRU cache. From 6bd0f1a60b2fec3a61ff5af8ba43695153b523d8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:21:27 -1000 Subject: [PATCH 23/28] Apply suggestions from code review --- docs/api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 6da307f24..6f0120b7a 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1048,8 +1048,8 @@ global LRU cache. .. function:: cache_info() - Return a dictionary with ``"idna_encode"``, ``"idna_decode"``, ``"ip_address"``, - ``"host_validate"``, and ``"encode_host"`` keys, each value + Return a dictionary with ``"idna_encode"``, ``"idna_decode"``, + and ``"encode_host"`` keys, each value points to corresponding ``CacheInfo`` structure (see :func:`functools.lru_cache` for details): From 02318e5ae655e445cc2279b527e140b177dbcbe4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:23:59 -1000 Subject: [PATCH 24/28] fix --- docs/api.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 6f0120b7a..3c123739a 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1048,10 +1048,9 @@ global LRU cache. .. function:: cache_info() - Return a dictionary with ``"idna_encode"``, ``"idna_decode"``, - and ``"encode_host"`` keys, each value - points to corresponding ``CacheInfo`` structure (see :func:`functools.lru_cache` for - details): + Return a dictionary with ``"idna_encode"``, ``"idna_decode"``, and + ``"encode_host"`` keys, each value points to corresponding ``CacheInfo`` + structure (see :func:`functools.lru_cache` for details): .. doctest:: :options: +SKIP @@ -1063,8 +1062,8 @@ global LRU cache. .. versionchanged:: 1.16 - ``ip_address``, and ``host_validate`` - are deprecated in favor of a single ``encode_host`` cache. + ``ip_address``, and ``host_validate`` are deprecated + in favor of a single ``encode_host`` cache. .. function:: cache_configure(*, idna_encode_size=256, idna_decode_size=256, encode_host_size=512) From 099abd95d289f46c2ef4c86afc52ea9a008bafc6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:25:53 -1000 Subject: [PATCH 25/28] Update yarl/_url.py --- yarl/_url.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarl/_url.py b/yarl/_url.py index 2a9ef2fb0..87bd6e10c 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -1681,7 +1681,7 @@ def _idna_decode(raw: str) -> str: @lru_cache(_DEFAULT_IDNA_SIZE) def _idna_encode(host: str) -> str: try: - return idna.encode(host.lower(), uts46=True).decode("ascii") + return idna.encode(host, uts46=True).decode("ascii") except UnicodeError: return host.encode("idna").decode("ascii") From 54bdd41c86d0ef669c3e0a5fde7fe5e36cc5fb62 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 16:37:46 -1000 Subject: [PATCH 26/28] Update CHANGES/1348.breaking.rst --- CHANGES/1348.breaking.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst index 44b794335..836286bd1 100644 --- a/CHANGES/1348.breaking.rst +++ b/CHANGES/1348.breaking.rst @@ -1,5 +1,5 @@ Migrated to using a single cache for encoding hosts -- by :user:`bdraco` -Passing ``ip_address_size``, and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host_size`` parameter and will be removed in a future release. +Passing ``ip_address_size`` and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host_size`` parameter and will be removed in a future release. For backwards compatibility, the old parameters affect the ``encode_host`` cache size. From df3a97f802688f52869f030ef6bc0b4322339165 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 17:14:13 -1000 Subject: [PATCH 27/28] cleanup changelog message --- CHANGES/1348.breaking.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst index 836286bd1..9ed631b0b 100644 --- a/CHANGES/1348.breaking.rst +++ b/CHANGES/1348.breaking.rst @@ -1,5 +1,3 @@ Migrated to using a single cache for encoding hosts -- by :user:`bdraco` -Passing ``ip_address_size`` and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host_size`` parameter and will be removed in a future release. - -For backwards compatibility, the old parameters affect the ``encode_host`` cache size. +Passing ``ip_address_size`` and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host_size`` parameter and will be removed in a future release. For backwards compatibility, the old parameters affect the ``encode_host`` cache size. From 5c891a557fdea06352027c99c45088346db9c574 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Oct 2024 17:14:31 -1000 Subject: [PATCH 28/28] Update CHANGES/1348.breaking.rst --- CHANGES/1348.breaking.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/1348.breaking.rst b/CHANGES/1348.breaking.rst index 9ed631b0b..845e85800 100644 --- a/CHANGES/1348.breaking.rst +++ b/CHANGES/1348.breaking.rst @@ -1,3 +1,3 @@ -Migrated to using a single cache for encoding hosts -- by :user:`bdraco` +Migrated to using a single cache for encoding hosts -- by :user:`bdraco`. Passing ``ip_address_size`` and ``host_validate_size`` to :py:meth:`~yarl.cache_configure` is deprecated in favor of the new ``encode_host_size`` parameter and will be removed in a future release. For backwards compatibility, the old parameters affect the ``encode_host`` cache size.