diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index e254a743..b94cbbda 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -10,6 +10,7 @@ follows `Semantic versioning`_ Development version ------------------- - Add ``dependency_injector.injections`` module (C extension). +- Transfer ``dependency_injector.utils`` module to Cython (C extension). - Transfer ``dependency_injector.errors`` module to Cython (C extension). - Remove ``@inject`` decorator. - Add makefile (``clean``, ``test``, ``build``, ``install``, ``uninstall`` diff --git a/setup.py b/setup.py index c91dd47e..df827713 100644 --- a/setup.py +++ b/setup.py @@ -50,6 +50,10 @@ setup(name='dependency-injector', ['src/dependency_injector/injections.c'], define_macros=defined_macros, extra_compile_args=['-O2']), + Extension('dependency_injector.utils', + ['src/dependency_injector/utils.c'], + define_macros=defined_macros, + extra_compile_args=['-O2']), Extension('dependency_injector.errors', ['src/dependency_injector/errors.c'], define_macros=defined_macros, diff --git a/src/dependency_injector/injections.pyx b/src/dependency_injector/injections.pyx index 673360a1..39e41593 100644 --- a/src/dependency_injector/injections.pyx +++ b/src/dependency_injector/injections.pyx @@ -5,7 +5,7 @@ Powered by Cython. cimport cython -from .utils import ( +from .utils cimport ( is_provider, is_delegated, ) diff --git a/src/dependency_injector/utils.pxd b/src/dependency_injector/utils.pxd new file mode 100644 index 00000000..6fb93278 --- /dev/null +++ b/src/dependency_injector/utils.pxd @@ -0,0 +1,16 @@ +"""Dependency injector utils. + +Powered by Cython. +""" + +cpdef bint is_provider(object instance) + +cpdef object ensure_is_provider(object instance) + +cpdef bint is_delegated(object instance) + +cpdef bint is_container(object instance) + +cpdef str represent_provider(object provider, object provides) + +cpdef object deepcopy(object instance, dict memo=*) diff --git a/src/dependency_injector/utils.py b/src/dependency_injector/utils.pyx similarity index 69% rename from src/dependency_injector/utils.py rename to src/dependency_injector/utils.pyx index 550fdcc1..8433389e 100644 --- a/src/dependency_injector/utils.py +++ b/src/dependency_injector/utils.pyx @@ -1,13 +1,16 @@ -"""Dependency injector utils module.""" +"""Dependency injector utils. + +Powered by Cython. +""" + +cimport cpython.version + +from dependency_injector cimport errors import copy as _copy import types import threading -import six - -from dependency_injector import errors - GLOBAL_LOCK = threading.RLock() """Dependency injector global reentrant lock. @@ -15,14 +18,19 @@ GLOBAL_LOCK = threading.RLock() :type: :py:class:`threading.RLock` """ -if six.PY2: # pragma: no cover +if cpython.version.PY_MAJOR_VERSION < 3: # pragma: no cover + CLASS_TYPES = (type, types.ClassType) + _copy._deepcopy_dispatch[types.MethodType] = \ lambda obj, memo: type(obj)(obj.im_func, _copy.deepcopy(obj.im_self, memo), obj.im_class) +else: # pragma: no cover + CLASS_TYPES = (type,) -def is_provider(instance): + +cpdef bint is_provider(object instance): """Check if instance is provider instance. :param instance: Instance to be checked. @@ -30,12 +38,11 @@ def is_provider(instance): :rtype: bool """ - return (not isinstance(instance, six.class_types) and - hasattr(instance, '__IS_PROVIDER__') and - getattr(instance, '__IS_PROVIDER__') is True) + return (not isinstance(instance, CLASS_TYPES) and + getattr(instance, '__IS_PROVIDER__', False) is True) -def ensure_is_provider(instance): +cpdef object ensure_is_provider(object instance): """Check if instance is provider instance and return it. :param instance: Instance to be checked. @@ -52,7 +59,7 @@ def ensure_is_provider(instance): return instance -def is_delegated(instance): +cpdef bint is_delegated(object instance): """Check if instance is delegated provider. :param instance: Instance to be checked. @@ -60,12 +67,11 @@ def is_delegated(instance): :rtype: bool """ - return (not isinstance(instance, six.class_types) and - hasattr(instance, '__IS_DELEGATED__') and - getattr(instance, '__IS_DELEGATED__') is True) + return (not isinstance(instance, CLASS_TYPES) and + getattr(instance, '__IS_DELEGATED__', False) is True) -def is_container(instance): +cpdef bint is_container(object instance): """Check if instance is container instance. :param instance: Instance to be checked. @@ -73,11 +79,10 @@ def is_container(instance): :rtype: bool """ - return (hasattr(instance, '__IS_CONTAINER__') and - getattr(instance, '__IS_CONTAINER__', False) is True) + return getattr(instance, '__IS_CONTAINER__', False) is True -def represent_provider(provider, provides): +cpdef str represent_provider(object provider, object provides): """Return string representation of provider. :param provider: Provider object @@ -96,6 +101,7 @@ def represent_provider(provider, provides): address=hex(id(provider))) -def deepcopy(instance, memo=None): +cpdef object deepcopy(object instance, dict memo=None): """Make full copy of instance.""" return _copy.deepcopy(instance, memo) +