commit:     8ab50ae15e2aa43bfd764a8af322fab92bb989b8
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat May 24 19:36:35 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May 24 19:36:35 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=8ab50ae1

dev-python/aiocache: enable py3.13

Closes: https://bugs.gentoo.org/952315
Signed-off-by: Sam James <sam <AT> gentoo.org>

 dev-python/aiocache/aiocache-0.12.3-r1.ebuild      |  73 +++++++
 .../aiocache/files/aiocache-0.12.3-py313.patch     | 239 +++++++++++++++++++++
 2 files changed, 312 insertions(+)

diff --git a/dev-python/aiocache/aiocache-0.12.3-r1.ebuild 
b/dev-python/aiocache/aiocache-0.12.3-r1.ebuild
new file mode 100644
index 000000000000..270ad52a1dde
--- /dev/null
+++ b/dev-python/aiocache/aiocache-0.12.3-r1.ebuild
@@ -0,0 +1,73 @@
+# Copyright 1999-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DISTUTILS_USE_PEP517=setuptools
+PYTHON_COMPAT=( python3_{11..13} )
+
+inherit distutils-r1 pypi
+
+DESCRIPTION="Asyncio cache manager"
+HOMEPAGE="
+       https://github.com/aio-libs/aiocache/
+       https://pypi.org/project/aiocache/
+"
+
+LICENSE="Apache-2.0"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+
+BDEPEND="
+       test? (
+               dev-db/redis
+               dev-python/marshmallow[${PYTHON_USEDEP}]
+               >=dev-python/msgpack-0.5.5[${PYTHON_USEDEP}]
+               dev-python/pytest-asyncio[${PYTHON_USEDEP}]
+               dev-python/pytest-mock[${PYTHON_USEDEP}]
+               >=dev-python/redis-4.2.0[${PYTHON_USEDEP}]
+       )
+"
+
+PATCHES=(
+       "${FILESDIR}"/${P}-py313.patch
+)
+
+distutils_enable_tests pytest
+
+python_test() {
+       local EPYTEST_DESELECT=(
+               # broken by newer dev-python/redis (?), removed upstream
+               tests/ut/backends/test_redis.py::TestRedisBackend::test_close
+       )
+       local EPYTEST_IGNORE=(
+               # benchmarks
+               tests/performance
+               # requires aiomcache
+               tests/ut/backends/test_memcached.py
+       )
+
+       local -x PYTEST_DISABLE_PLUGIN_AUTOLOAD=1
+       epytest -o addopts= -m "not memcached" -p asyncio -p pytest_mock
+}
+
+src_test() {
+       local redis_pid="${T}"/redis.pid
+       local redis_port=6379
+
+       # Spawn Redis for testing purposes
+       einfo "Spawning Redis"
+       einfo "NOTE: Port ${redis_port} must be free"
+       "${EPREFIX}"/usr/sbin/redis-server - <<- EOF || die "Unable to start 
redis server"
+               daemonize yes
+               pidfile ${redis_pid}
+               port ${redis_port}
+               bind 127.0.0.1 ::1
+       EOF
+
+       # Run the tests
+       distutils-r1_src_test
+
+       # Clean up afterwards
+       kill "$(<"${redis_pid}")" || die
+}

diff --git a/dev-python/aiocache/files/aiocache-0.12.3-py313.patch 
b/dev-python/aiocache/files/aiocache-0.12.3-py313.patch
new file mode 100644
index 000000000000..5df233144a62
--- /dev/null
+++ b/dev-python/aiocache/files/aiocache-0.12.3-py313.patch
@@ -0,0 +1,239 @@
+https://github.com/aio-libs/aiocache/commit/47ac136b65db9cb4106ed68f764ad257db0277bb
+
+From 47ac136b65db9cb4106ed68f764ad257db0277bb Mon Sep 17 00:00:00 2001
+From: Sam Bull <[email protected]>
+Date: Mon, 25 Nov 2024 09:26:30 +0000
+Subject: [PATCH] Update for Python 3.13 (#864)
+
+Co-authored-by: Andrew Svetlov <[email protected]>
+---
+ .github/workflows/ci.yml               |  8 ++++----
+ .pre-commit-config.yaml                |  4 ++--
+ .readthedocs.yml                       | 24 ++++++++++++++++++++++++
+ aiocache/backends/redis.py             |  3 ++-
+ examples/frameworks/aiohttp_example.py |  2 +-
+ requirements-dev.txt                   |  7 ++++---
+ requirements.txt                       | 18 +++++++++---------
+ setup.cfg                              |  2 ++
+ setup.py                               |  7 ++++---
+ tests/performance/server.py            | 11 +++++++----
+ tests/ut/backends/test_redis.py        |  2 +-
+ tests/ut/test_decorators.py            | 20 ++++++++++----------
+ 12 files changed, 70 insertions(+), 38 deletions(-)
+ create mode 100644 .readthedocs.yml
+
+diff --git a/aiocache/backends/redis.py b/aiocache/backends/redis.py
+index d0e3bd65..ce115516 100644
+--- a/aiocache/backends/redis.py
++++ b/aiocache/backends/redis.py
+@@ -51,6 +51,7 @@ def __init__(
+             warnings.warn(
+                 "Parameter 'pool_min_size' is deprecated since aiocache 0.12",
+                 DeprecationWarning,
++                stacklevel=2,
+             )
+ 
+         self.endpoint = endpoint
+@@ -188,7 +189,7 @@ async def _redlock_release(self, key, value):
+         return await self._raw("eval", self.RELEASE_SCRIPT, 1, key, value)
+ 
+     async def _close(self, *args, _conn=None, **kwargs):
+-        await self.client.close()
++        await self.client.aclose()
+ 
+ 
+ class RedisCache(RedisBackend):
+diff --git a/examples/frameworks/aiohttp_example.py 
b/examples/frameworks/aiohttp_example.py
+index e612b30a..7220c711 100644
+--- a/examples/frameworks/aiohttp_example.py
++++ b/examples/frameworks/aiohttp_example.py
+@@ -25,7 +25,7 @@ def __init__(self, *args, **kwargs):
+     async def get_from_cache(self, key):
+         try:
+             value = await self.cache.get(key)
+-            if type(value) == web.Response:
++            if type(value) is web.Response:
+                 return web.Response(
+                     body=value.body,
+                     status=value.status,
+diff --git a/requirements-dev.txt b/requirements-dev.txt
+index 82a078fb..a4380ba4 100644
+--- a/requirements-dev.txt
++++ b/requirements-dev.txt
+@@ -1,10 +1,11 @@
+ -r requirements.txt
+ 
+-flake8==6.0.0
++flake8==7.1.1
+ flake8-bandit==4.1.1
+-flake8-bugbear==22.12.6
++flake8-bugbear==24.10.31
+ flake8-import-order==0.18.2
+-flake8-requirements==1.7.6
++flake8-requirements==2.2.1
+ mypy==0.991; implementation_name=="cpython"
+ types-redis==4.4.0.0
+ types-ujson==5.7.0.0
++sphinx==8.1.3
+diff --git a/requirements.txt b/requirements.txt
+index 31dfe1a2..6a1e5ba4 100644
+--- a/requirements.txt
++++ b/requirements.txt
+@@ -1,11 +1,11 @@
+ -e .
+ 
+-aiomcache==0.8.0
+-aiohttp==3.8.3
+-marshmallow==3.19.0
+-msgpack==1.0.4
+-pytest==7.2.0
+-pytest-asyncio==0.20.3
+-pytest-cov==4.0.0
+-pytest-mock==3.10.0
+-redis==4.4.2
++aiomcache==0.8.2
++aiohttp==3.9.5
++marshmallow==3.21.3
++msgpack==1.0.8
++pytest==7.4.4
++pytest-asyncio==0.23.7
++pytest-cov==5.0.0
++pytest-mock==3.14.0
++redis==5.0.5
+diff --git a/setup.py b/setup.py
+index ed54028b..c8bcbada 100644
+--- a/setup.py
++++ b/setup.py
+@@ -22,17 +22,18 @@
+     long_description=readme,
+     classifiers=[
+         "Programming Language :: Python",
+-        "Programming Language :: Python :: 3.7",
+-        "Programming Language :: Python :: 3.8",
+         "Programming Language :: Python :: 3.9",
+         "Programming Language :: Python :: 3.10",
+         "Programming Language :: Python :: 3.11",
++        "Programming Language :: Python :: 3.12",
++        "Programming Language :: Python :: 3.13",
+         "Framework :: AsyncIO",
+     ],
++    python_requires=">=3.9",
+     packages=("aiocache",),
+     install_requires=None,
+     extras_require={
+-        "redis": ["redis>=4.2.0"],
++        "redis": ["redis>=5"],
+         "memcached": ["aiomcache>=0.5.2"],
+         "msgpack": ["msgpack>=0.5.5"],
+     },
+diff --git a/tests/performance/server.py b/tests/performance/server.py
+index 8de8c6b8..7fcfd319 100644
+--- a/tests/performance/server.py
++++ b/tests/performance/server.py
+@@ -28,22 +28,25 @@ async def close(self, *_):
+         await self.cache.close()
+ 
+ 
++cache_key = web.AppKey("cache", CacheManager)
++
++
+ async def handler_get(req):
+     try:
+-        data = await req.app["cache"].get("testkey")
++        data = await req.app[cache_key].get("testkey")
+         if data:
+             return web.Response(text=data)
+     except asyncio.TimeoutError:
+         return web.Response(status=404)
+ 
+     data = str(uuid.uuid4())
+-    await req.app["cache"].set("testkey", data)
++    await req.app[cache_key].set("testkey", data)
+     return web.Response(text=str(data))
+ 
+ 
+ def run_server(backend: str) -> None:
+     app = web.Application()
+-    app["cache"] = CacheManager(backend)
+-    app.on_shutdown.append(app["cache"].close)
++    app[cache_key] = CacheManager(backend)
++    app.on_shutdown.append(app[cache_key].close)
+     app.router.add_route("GET", "/", handler_get)
+     web.run_app(app)
+diff --git a/tests/ut/backends/test_redis.py b/tests/ut/backends/test_redis.py
+index a26e4086..2837cbcf 100644
+--- a/tests/ut/backends/test_redis.py
++++ b/tests/ut/backends/test_redis.py
+@@ -233,7 +233,7 @@ async def test_redlock_release(self, mocker, redis):
+ 
+     async def test_close(self, redis):
+         await redis._close()
+-        assert redis.client.close.call_count == 1
++        assert redis.client.aclose.call_count == 1
+ 
+ 
+ class TestRedisCache:
+diff --git a/tests/ut/test_decorators.py b/tests/ut/test_decorators.py
+index e4a1a07e..a59fb31c 100644
+--- a/tests/ut/test_decorators.py
++++ b/tests/ut/test_decorators.py
+@@ -154,8 +154,8 @@ async def test_calls_fn_set_when_get_none(self, mocker, 
decorator, decorator_cal
+ 
+     async def test_calls_fn_raises_exception(self, decorator, decorator_call):
+         decorator.cache.get.return_value = None
+-        stub.side_effect = Exception()
+-        with pytest.raises(Exception):
++        stub.side_effect = RuntimeError()
++        with pytest.raises(RuntimeError):
+             assert await decorator_call()
+ 
+     async def test_cache_write_waits_for_future(self, decorator, 
decorator_call):
+@@ -167,11 +167,10 @@ async def test_cache_write_waits_for_future(self, 
decorator, decorator_call):
+     async def test_cache_write_doesnt_wait_for_future(self, mocker, 
decorator, decorator_call):
+         mocker.spy(decorator, "set_in_cache")
+         with patch.object(decorator, "get_from_cache", autospec=True, 
return_value=None):
+-            with patch("aiocache.decorators.asyncio.ensure_future", 
autospec=True):
+-                await decorator_call(aiocache_wait_for_write=False, 
value="value")
++            await decorator_call(aiocache_wait_for_write=False, value="value")
+ 
+         decorator.set_in_cache.assert_not_awaited()
+-        decorator.set_in_cache.assert_called_once_with("stub()[('value', 
'value')]", "value")
++        # decorator.set_in_cache.assert_called_once_with("stub()[('value', 
'value')]", "value")
+ 
+     async def test_set_calls_set(self, decorator, decorator_call):
+         await decorator.set_in_cache("key", "value")
+@@ -287,10 +286,11 @@ async def test_calls_get_and_returns(self, decorator, 
decorator_call):
+         assert decorator.cache.set.call_count == 0
+         assert stub.call_count == 0
+ 
++    @pytest.mark.xfail(reason="Mess in stubs")
+     async def test_calls_fn_raises_exception(self, decorator, decorator_call):
+         decorator.cache.get.return_value = None
+-        stub.side_effect = Exception()
+-        with pytest.raises(Exception):
++        stub.side_effect = RuntimeError()
++        with pytest.raises(RuntimeError):
+             assert await decorator_call()
+ 
+     async def test_calls_redlock(self, decorator, decorator_call):
+@@ -483,7 +483,7 @@ async def test_cache_write_doesnt_wait_for_future(self, 
mocker, decorator, decor
+                                      aiocache_wait_for_write=False)
+ 
+         decorator.set_in_cache.assert_not_awaited()
+-        decorator.set_in_cache.assert_called_once_with({"a": ANY, "b": ANY}, 
stub_dict, ANY, ANY)
++        # decorator.set_in_cache.assert_called_once_with({"a": ANY, "b": 
ANY}, stub_dict, ANY, ANY)
+ 
+     async def test_calls_fn_with_only_missing_keys(self, mocker, decorator, 
decorator_call):
+         mocker.spy(decorator, "set_in_cache")
+@@ -496,8 +496,8 @@ async def test_calls_fn_with_only_missing_keys(self, 
mocker, decorator, decorato
+ 
+     async def test_calls_fn_raises_exception(self, decorator, decorator_call):
+         decorator.cache.multi_get.return_value = [None]
+-        stub_dict.side_effect = Exception()
+-        with pytest.raises(Exception):
++        stub_dict.side_effect = RuntimeError()
++        with pytest.raises(RuntimeError):
+             assert await decorator_call(keys=[])
+ 
+     async def test_cache_read_disabled(self, decorator, decorator_call):
+

Reply via email to