From 56abf9f08efab85f54c5d3aec1a91dd22e5ebaba Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sun, 20 May 2018 23:12:34 +0900 Subject: [PATCH] qualname compat --- ring/_compat.py | 12 ++++++++++++ ring/callable.py | 12 ++++++------ ring/django.py | 5 +++-- ring/func.py | 4 ++-- ring/func_asyncio.py | 2 +- ring/func_base.py | 34 +++++++++++++++++++++++++--------- ring/func_sync.py | 2 +- ring/key.py | 5 ++--- tests/test_compat.py | 11 +++++++++++ 9 files changed, 63 insertions(+), 24 deletions(-) create mode 100644 tests/test_compat.py diff --git a/ring/_compat.py b/ring/_compat.py index 193ec32..dbb1222 100644 --- a/ring/_compat.py +++ b/ring/_compat.py @@ -13,3 +13,15 @@ from functools import lru_cache except ImportError: # for py2 from functools32 import lru_cache # noqa + + +def qualname(x): + if six.PY34: + return x.__qualname__ + + # not perfect - but it is ok for cache key + if hasattr(x, 'im_class'): + return '.'.join( + (x.im_class.__name__, x.__name__)) + else: + return x.__name__ diff --git a/ring/callable.py b/ring/callable.py index 722dca2..fef18a9 100644 --- a/ring/callable.py +++ b/ring/callable.py @@ -1,8 +1,8 @@ from __future__ import absolute_import -from collections import OrderedDict -from ring._util import cached_property -from ring._compat import inspect +import collections +from ._util import cached_property +from ._compat import inspect, qualname __all__ = ('Callable', ) @@ -41,7 +41,7 @@ def annotations(self): def kwargify(self, args, kwargs): """Create a merged kwargs-like object with given args and kwargs.""" - merged = OrderedDict() + merged = collections.OrderedDict() _params = self.parameters_values _params_len = len(_params) @@ -128,8 +128,8 @@ def kwargify(self, args, kwargs): @cached_property def identifier(self): - return '{self.callable.__module__}.{self.callable.__qualname__}'.format( - self=self) + return '.'.join( + (self.callable.__module__, qualname(self.callable))) @cached_property def first_parameter(self): diff --git a/ring/django.py b/ring/django.py index cc60686..c9ec09f 100644 --- a/ring/django.py +++ b/ring/django.py @@ -2,10 +2,11 @@ ======================================== """ from __future__ import absolute_import + import functools from django.core import cache -from ring import func_base as fbase -from ring.func_sync import ring_class_factory, CacheInterface +from . import func_base as fbase +from .func_sync import ring_class_factory, CacheInterface __all__ = ('django', 'django_default') diff --git a/ring/func.py b/ring/func.py index ea7f53f..79870a6 100644 --- a/ring/func.py +++ b/ring/func.py @@ -4,7 +4,7 @@ Ring object factory functions are aggregated in this module. """ -from ring.func_sync import dict, memcache, redis_py, redis, disk +from .func_sync import dict, memcache, redis_py, redis, disk try: import asyncio @@ -12,7 +12,7 @@ asyncio = False if asyncio: - from ring.func_asyncio import aiodict, aiomcache, aioredis + from .func_asyncio import aiodict, aiomcache, aioredis else: aiodict = None aiomcache = None diff --git a/ring/func_asyncio.py b/ring/func_asyncio.py index afb4891..6fb4722 100644 --- a/ring/func_asyncio.py +++ b/ring/func_asyncio.py @@ -4,7 +4,7 @@ import asyncio import inspect import time -from ring import func_base as fbase +from . import func_base as fbase __all__ = ('dict', 'aiodict', 'aiomcache', 'aioredis', ) diff --git a/ring/func_base.py b/ring/func_base.py index 6e258e4..94e10ac 100644 --- a/ring/func_base.py +++ b/ring/func_base.py @@ -5,11 +5,12 @@ import abc import functools import six -from ring._compat import lru_cache -from ring.callable import Callable -from ring.key import CallableKey -from ring.wire import Wire -from ring.coder import registry as coder_registry, coderize + +from ._compat import lru_cache, qualname +from .callable import Callable +from .key import CallableKey +from .wire import Wire +from .coder import registry as coder_registry, coderize __all__ = ( 'is_method', 'is_classmethod', 'Ring', 'factory', 'NotFound', @@ -52,15 +53,20 @@ def suggest_ignorable_keys(c, ignorable_keys): def suggest_key_prefix(c, key_prefix): if key_prefix is None: + cc = c.callable if is_method(c): key_prefix = \ '{0.__module__}.{{self.__class__.__qualname__}}.' \ - '{0.__qualname__}'.format(c.callable) + '{1}'.format(cc, qualname(cc)) + if not six.PY34: + key_prefix = key_prefix.replace('__qualname__', '__name__') elif is_classmethod(c): # cls is already a str object somehow - key_prefix = '{0.__module__}.{{cls}}.{0.__qualname__}'.format(c.callable) + key_prefix = '{0.__module__}.{{cls}}.{1}'.format( + cc, qualname(cc)) else: - key_prefix = '{0.__module__}.{0.__qualname__}'.format(c.callable) + key_prefix = '{0.__module__}.{1}'.format( + cc, qualname(cc)) else: key_prefix = key_prefix.replace('{', '{{').replace('}', '}}') return key_prefix @@ -225,7 +231,17 @@ def impl_f(*args, **kwargs): if function_args_count == 0: functools.wraps(c)(impl_f) impl_f.__name__ = '.'.join((c.__name__, name)) - impl_f.__qualname__ = '.'.join((c.__qualname__, name)) + if six.PY34: + impl_f.__qualname__ = '.'.join( + (c.__qualname__, name)) + else: + # mock __qualname__ for py2 + if hasattr(impl_f, 'im_class'): + impl_f.__qualname__ = '.'.join( + (impl_f.im_class.__name__, + impl_f.__name__)) + else: + impl_f.__qualname__ = impl_f.__name__ setattr(self, name, impl_f) return self.__getattribute__(name) diff --git a/ring/func_sync.py b/ring/func_sync.py index 3afd2ae..504e346 100644 --- a/ring/func_sync.py +++ b/ring/func_sync.py @@ -4,7 +4,7 @@ import time import re import hashlib -from ring import func_base as fbase +from . import func_base as fbase __all__ = ('dict', 'memcache', 'redis_py', 'redis', 'disk', 'arcus') diff --git a/ring/key.py b/ring/key.py index cf68570..8dd4102 100644 --- a/ring/key.py +++ b/ring/key.py @@ -1,9 +1,8 @@ - from __future__ import absolute_import import re -from ring._util import cached_property -from ring.callable import Callable +from ._util import cached_property +from .callable import Callable class Key(object): diff --git a/tests/test_compat.py b/tests/test_compat.py new file mode 100644 index 0000000..444372c --- /dev/null +++ b/tests/test_compat.py @@ -0,0 +1,11 @@ + +from ring._compat import qualname + + +def test_qualname(): + + class A(object): + def f(): + pass + + assert qualname(A.f).endswith('A.f')