Skip to content

Commit

Permalink
Move lru cache from inside of _encode_host to outside (#1348)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Oct 21, 2024
1 parent 77ac632 commit db92ab5
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 133 deletions.
3 changes: 3 additions & 0 deletions CHANGES/1348.breaking.rst
Original file line number Diff line number Diff line change
@@ -0,0 +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.
31 changes: 18 additions & 13 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1037,43 +1037,48 @@ 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 are quite expensive operations,
that's why the ``yarl`` library caches these calls by storing 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
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

>>> 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)}
'encode_host': CacheInfo(hits=0, misses=0, maxsize=512, currsize=0)}

.. versionchanged:: 1.16

``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=256, idna_decode_size=256, encode_host_size=512)

Set the IP Address, host validation, and IDNA encode and
decode cache sizes (``256`` for each by default).
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,
please use with caution).

.. versionchanged:: 1.16

``ip_address_size`` and ``host_validate_size``
are deprecated in favor of a single ``encode_host`` cache.

References
----------

Expand Down
41 changes: 34 additions & 7 deletions tests/test_cache.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import pytest

import yarl

# Don't check the actual behavior but make sure that calls are allowed
Expand All @@ -13,7 +15,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:
Expand All @@ -22,17 +30,36 @@ 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,
idna_encode_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,
idna_encode_size=128,
encode_host_size=128,
)


def test_cache_configure_waring() -> None:
msg = (
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"
)
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
2 changes: 1 addition & 1 deletion yarl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
cache_info,
)

__version__ = "1.15.6.dev0"
__version__ = "1.16.0.dev0"

__all__ = (
"URL",
Expand Down
Loading

0 comments on commit db92ab5

Please sign in to comment.