Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clear() method with 'namespace' parameter fails: TypeError: delete() missing 1 required positional argument: 'key' #472

Open
AbuSM opened this issue Dec 24, 2019 · 8 comments

Comments

@AbuSM
Copy link

AbuSM commented Dec 24, 2019

I want to use certain namespace while cleaning redis cache, like below:
coros.append(asyncio.ensure_future(cache.clear(namespace='main')))
Error occured when redis cache doesn't have key with namespace 'main' :
coros.append(asyncio.ensure_future(cache.clear(namespace='dialog_api')))

I've found the problem in file aiocache/backends/redis.py in 187 line:

async def _clear(self, namespace=None, _conn=None):
        if namespace:
            keys = await _conn.keys("{}:*".format(namespace))
            await _conn.delete(*keys)
        else:
            await _conn.flushdb()
        return True

So, I want to fix it by adding if statement, like:

async def _clear(self, namespace=None, _conn=None):
        if namespace:
            keys = await _conn.keys("{}:*".format(namespace))
            if keys:
                await _conn.delete(*keys)

I could be wrong or miss something, if anybody faced with it please comment

@argaen
Copy link
Member

argaen commented Dec 24, 2019

thanks for reporting @AbuSM, could you please post the error traceback you get when this happens?

@argaen
Copy link
Member

argaen commented Dec 24, 2019

Anyway, checking code for aioredis in https://github.com/aio-libs/aioredis/blob/master/aioredis/commands/generic.py#L10 I would say you are right. If you could open a PR and also add corresponding tests I would be happy to merge :)

@AbuSM
Copy link
Author

AbuSM commented Dec 24, 2019

Hi, @argaen! Here is traceback:

Traceback (most recent call last):
  File "../app.py", line 6, in <module>
    main()
  File "../lib/main.py", line 112, in main
    loop.run_until_complete(asyncio.gather(*coros))
  File "uvloop/loop.pyx", line 1451, in uvloop.loop.Loop.run_until_complete
  File "../venv/lib/python3.7/site-packages/aiocache/base.py", line 61, in _enabled
    return await func(*args, **kwargs)
  File "../venv/lib/python3.7/site-packages/aiocache/base.py", line 45, in _timeout
    return await asyncio.wait_for(func(self, *args, **kwargs), timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/tasks.py", line 416, in wait_for
    return fut.result()
  File "../venv/lib/python3.7/site-packages/aiocache/base.py", line 75, in _plugins
    ret = await func(self, *args, **kwargs)
  File "../venv/lib/python3.7/site-packages/aiocache/base.py", line 429, in clear
    ret = await self._clear(namespace, _conn=_conn)
  File "../venv/lib/python3.7/site-packages/aiocache/backends/redis.py", line 24, in wrapper
    return await func(self, *args, _conn=_conn, **kwargs)
  File "../venv/lib/python3.7/site-packages/aiocache/backends/redis.py", line 187, in _clear
    await _conn.delete(*keys)
TypeError: delete() missing 1 required positional argument: 'key'

I'll open PR with tests as soon as possible :)

@long2ice
Copy link

long2ice commented Feb 7, 2020

Hi,the reason is maybe in cached decorator, if use alias param,the **kwargs,which include namespace,is not pass on cache backend,like RedisCache,look it:

    # in decorators.py,line 80-89
    def __call__(self, f):
        if self.alias:
            self.cache = caches.get(self.alias)
        else:
            self.cache = _get_cache(
                cache=self._cache,
                serializer=self._serializer,
                plugins=self._plugins,
                **self._kwargs
            )

so the namespace param will not take part in key_builder,when you call clear(namespace),you only get empty list keys,which cause TypeError: delete() missing 1 required positional argument: 'key' error.

method to fix it may to add **kwargs in caches.get(self.alias),looks like:

    # in decorators.py,line 80-89
    def __call__(self, f):
        if self.alias:
            self.cache = caches.get(self.alias,**self._kwargs)
        else:
            self.cache = _get_cache(
                cache=self._cache,
                serializer=self._serializer,
                plugins=self._plugins,
                **self._kwargs
            )

@AbuSM
Copy link
Author

AbuSM commented Feb 29, 2020

@long2ice Great achievement! I didn't look at the root of the problem. Have you tested it? Sure you might write some tests and make a PR. Think this will help to whole project, not only to clear method

@long2ice
Copy link

@AbuSM Yes,I make some changes in my fork,but I am not sure if it's right and appropriate or not,that's appreciative if you can review https://github.com/long2ice/aiocache/commits/master and give some suggestions,then I will complete it and make tests,and give a pull request.

@AbuSM
Copy link
Author

AbuSM commented Mar 1, 2020

@long2ice I didn't find anything awful in your code and suppose everything is fine. Maybe @argaen may give some comments to it?!

@argaen argaen added this to the 0.12.0 milestone Oct 15, 2020
@Dreamsorcerer
Copy link
Member

If you create a PR, even as a draft, we'll take a look and provide feedback.

@Dreamsorcerer Dreamsorcerer removed this from the 0.12.0 milestone Jan 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants