Skip to content

Commit

Permalink
Merge branch 'master' into fix/ignore_updated_values_in_multi_cache
Browse files Browse the repository at this point in the history
  • Loading branch information
argaen committed Oct 19, 2020
2 parents 0444f9d + a966f84 commit 9981377
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 54 deletions.
64 changes: 36 additions & 28 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,14 @@ jobs:
include:
- stage: syntax
script: tox
python: 3.6
python: 3.8
env: TOXENV=syntax
- script: tox
python: 3.6
python: 3.8
env: TOXENV=docs-html

- stage: test
script: tox
env: TOXENV=py35,codecov
python: 3.5
- script: tox
env: TOXENV=py35,codecov
python: 3.5-dev
- script: tox
env: TOXENV=py35-ujson,codecov
python: 3.5
- script: tox
env: TOXENV=py35-deps-lowest,codecov
python: 3.5
- script: tox
env: TOXENV=py35-deps-devel,codecov
python: 3.5

- script: tox
env: TOXENV=py36,codecov
python: 3.6
- script: tox
Expand All @@ -54,27 +38,51 @@ jobs:
- script: tox
env: TOXENV=py37,codecov
python: 3.7
dist: xenial
sudo: true
- script: tox
env: TOXENV=py37,codecov
python: 3.7-dev
- script: tox
env: TOXENV=py37-ujson,codecov
python: 3.7
dist: xenial
sudo: true
- script: tox
env: TOXENV=py37-deps-lowest,codecov
python: 3.7
dist: xenial
sudo: true
- script: tox
env: TOXENV=py37-deps-devel,codecov
python: 3.7
dist: xenial
sudo: true

- script: tox
env: TOXENV=py38,codecov
python: 3.8
- script: tox
env: TOXENV=py38,codecov
python: 3.8-dev
- script: tox
env: TOXENV=py38-ujson,codecov
python: 3.8
- script: tox
env: TOXENV=py38-deps-lowest,codecov
python: 3.8
- script: tox
env: TOXENV=py38-deps-devel,codecov
python: 3.8

- script: tox
env: TOXENV=py39,codecov
python: 3.9-dev
- script: tox
env: TOXENV=py39-ujson,codecov
python: 3.9-dev
- script: tox
env: TOXENV=py39-deps-lowest,codecov
python: 3.9-dev
- script: tox
env: TOXENV=py39-deps-devel,codecov
python: 3.9-dev

- stage: deploy
script: skip
python: 3.6
python: 3.8
deploy: &pypi
provider: pypi
user: blck
Expand All @@ -83,4 +91,4 @@ jobs:
distributions: "sdist bdist_wheel"
on:
tags: true
python: 3.6
python: 3.8
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cov-report = true


lint:
flake8
flake8 tests/ aiocache/
black -l 100 --check tests/ aiocache/

format:
Expand Down
2 changes: 1 addition & 1 deletion aiocache/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@
"cached",
"cached_stampede",
"multi_cached",
*list(AIOCACHE_CACHES.values()),
*(c.__name__ for c in AIOCACHE_CACHES.values()),
"__version__",
)
4 changes: 2 additions & 2 deletions aiocache/backends/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ async def _redlock_release(self, key, value):

@classmethod
def __delete(cls, key):
if cls._cache.pop(key, None):
if cls._cache.pop(key, None) is not None:
handle = cls._handlers.pop(key, None)
if handle:
handle.cancel()
Expand All @@ -110,7 +110,7 @@ def __delete(cls, key):
class SimpleMemoryCache(SimpleMemoryBackend, BaseCache):
"""
Memory cache implementation with the following components as defaults:
- serializer: :class:`aiocache.serializers.JsonSerializer`
- serializer: :class:`aiocache.serializers.NullSerializer`
- plugins: None
Config options are:
Expand Down
2 changes: 1 addition & 1 deletion aiocache/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ async def decorator(

def get_cache_keys(self, f, args, kwargs):
args_dict = _get_args_dict(f, args, kwargs)
keys = args_dict[self.keys_from_attr] or []
keys = args_dict.get(self.keys_from_attr, []) or []
keys = [self.key_builder(key, f, *args, **kwargs) for key in keys]

args_names = f.__code__.co_varnames[: f.__code__.co_argcount]
Expand Down
6 changes: 5 additions & 1 deletion aiocache/serializers/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,18 @@ class PickleSerializer(BaseSerializer):

DEFAULT_ENCODING = None

def __init__(self, *args, protocol=pickle.DEFAULT_PROTOCOL, **kwargs):
super().__init__(*args, **kwargs)
self.protocol = protocol

def dumps(self, value):
"""
Serialize the received value using ``pickle.dumps``.
:param value: obj
:returns: bytes
"""
return pickle.dumps(value)
return pickle.dumps(value, protocol=self.protocol)

def loads(self, value):
"""
Expand Down
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,18 @@
long_description=readme,
classifiers=[
'Programming Language :: Python',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Framework :: AsyncIO',
],
packages=find_packages(),
install_requires=None,
extras_require={
'redis:python_version<"3.7"': ['aioredis>=0.3.3'],
'redis:python_version>="3.7"': ['aioredis>=1.0.0'],
'redis:python_version>="3.8"': ['aioredis>=1.3.0'],
'redis:python_version>="3.7" and python_version<"3.8"': ['aioredis>=1.0.0'],
'memcached': ['aiomcache>=0.5.2'],
'msgpack': ['msgpack>=0.5.5'],
'dev': [
Expand Down
14 changes: 14 additions & 0 deletions tests/ut/backends/test_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,20 @@ async def test_delete_missing(self, memory):
await memory._delete(pytest.KEY)
SimpleMemoryBackend._cache.pop.assert_called_with(pytest.KEY, None)

@pytest.mark.asyncio
async def test_delete_non_truthy(self, memory):
non_truthy = MagicMock()
non_truthy.__bool__.side_effect = ValueError("Does not implement truthiness")

with pytest.raises(ValueError):
bool(non_truthy)

SimpleMemoryBackend._cache.pop.return_value = non_truthy
await memory._delete(pytest.KEY)

assert non_truthy.__bool__.call_count == 1
SimpleMemoryBackend._cache.pop.assert_called_with(pytest.KEY, None)

@pytest.mark.asyncio
async def test_clear_namespace(self, memory):
SimpleMemoryBackend._cache.__iter__.return_value = iter(["nma", "nmb", "no"])
Expand Down
3 changes: 1 addition & 2 deletions tests/ut/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,7 @@ def test_get_cache_keys_empty_list(self, decorator):
assert decorator.get_cache_keys(stub_dict, (), {"keys": []}) == ([], [], -1)

def test_get_cache_keys_missing_kwarg(self, decorator):
with pytest.raises(KeyError):
assert decorator.get_cache_keys(stub_dict, (), {})
assert decorator.get_cache_keys(stub_dict, (), {}) == ([], [], -1)

def test_get_cache_keys_arg_key_from_attr(self, decorator):
def fake(keys, a=1, b=2):
Expand Down
37 changes: 23 additions & 14 deletions tests/ut/test_serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
import pickle

from collections import namedtuple
from unittest import mock
Expand Down Expand Up @@ -70,32 +71,40 @@ def test_loads(self):


class TestPickleSerializer:
def test_init(self):
serializer = PickleSerializer()
@pytest.fixture
def serializer(self):
yield PickleSerializer(protocol=4)

def test_init(self, serializer):
assert isinstance(serializer, BaseSerializer)
assert serializer.DEFAULT_ENCODING is None
assert serializer.encoding is None
assert serializer.protocol == 4

@pytest.mark.parametrize("obj", TYPES)
def test_set_types(self, obj):
def test_init_sets_default_protocol(self):
serializer = PickleSerializer()
assert serializer.protocol == pickle.DEFAULT_PROTOCOL

@pytest.mark.parametrize("obj", TYPES)
def test_set_types(self, obj, serializer):
assert serializer.loads(serializer.dumps(obj)) == obj

def test_dumps(self):
assert PickleSerializer().dumps("hi") == b"\x80\x03X\x02\x00\x00\x00hiq\x00."
def test_dumps(self, serializer):
assert (
serializer.dumps("hi") == b"\x80\x04\x95\x06\x00\x00\x00\x00\x00\x00\x00\x8c\x02hi\x94."
)

def test_dumps_with_none(self):
assert isinstance(PickleSerializer().dumps(None), bytes)
def test_dumps_with_none(self, serializer):
assert isinstance(serializer.dumps(None), bytes)

def test_loads(self):
assert PickleSerializer().loads(b"\x80\x03X\x02\x00\x00\x00hiq\x00.") == "hi"
def test_loads(self, serializer):
assert serializer.loads(b"\x80\x03X\x02\x00\x00\x00hiq\x00.") == "hi"

def test_loads_with_none(self):
assert PickleSerializer().loads(None) is None
def test_loads_with_none(self, serializer):
assert serializer.loads(None) is None

def test_dumps_and_loads(self):
def test_dumps_and_loads(self, serializer):
obj = Dummy(1, 2)
serializer = PickleSerializer()
assert serializer.loads(serializer.dumps(obj)) == obj


Expand Down
5 changes: 3 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tox]
envlist =
py{36,37}-{deps-lowest,deps-devel}
py{35,36,37}-ujson
py{36,37,38,39}-{deps-lowest,deps-devel}
py{36,37,38,39}-ujson
codecov
syntax
docs-html
Expand All @@ -14,6 +14,7 @@ whitelist_externals =
bash

deps =
py{38,39}-deps-lowest: aioredis==1.3.0
py37-deps-lowest: aioredis==1.0.0
py36-deps-lowest: aioredis==0.3.3
deps-lowest: aiomcache==0.5.2
Expand Down

0 comments on commit 9981377

Please sign in to comment.