From 92a58cd4f96660a45ea7b836b36b5efa59ac46d5 Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Tue, 1 Mar 2016 15:42:06 +0200 Subject: [PATCH] Move fetch_cls_init() to utils module --- dependency_injector/injections.py | 31 ++++++++----------------------- dependency_injector/utils.py | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/dependency_injector/injections.py b/dependency_injector/injections.py index 661daaf6..f9d7feb4 100644 --- a/dependency_injector/injections.py +++ b/dependency_injector/injections.py @@ -1,7 +1,5 @@ """Injections module.""" -import sys - import six from .utils import is_provider @@ -9,17 +7,11 @@ from .utils import is_delegated_provider from .utils import is_injection from .utils import is_arg_injection from .utils import is_kwarg_injection +from .utils import fetch_cls_init from .errors import Error -_IS_PYPY = '__pypy__' in sys.builtin_module_names -if _IS_PYPY or six.PY3: # pragma: no cover - _OBJECT_INIT = six.get_unbound_function(object.__init__) -else: # pragma: no cover - _OBJECT_INIT = None - - @six.python_2_unicode_compatible class Injection(object): """Base injection class. @@ -225,7 +217,13 @@ def inject(*args, **kwargs): """Dependency injection decorator.""" if isinstance(callback_or_cls, six.class_types): cls = callback_or_cls - cls.__init__ = decorator(_fetch_cls_init(cls)) + cls_init = fetch_cls_init(cls) + if not cls_init: + raise Error( + 'Class {0}.{1} has no __init__() '.format(cls.__module__, + cls.__name__) + + 'method and could not be decorated with @inject decorator') + cls.__init__ = decorator(cls_init) return cls callback = callback_or_cls @@ -256,19 +254,6 @@ def inject(*args, **kwargs): return decorator -def _fetch_cls_init(cls): - """Return reference to the class.__init__() method if it is defined.""" - try: - cls_init = six.get_unbound_function(cls.__init__) - assert cls_init is not _OBJECT_INIT - except (AttributeError, AssertionError): - raise Error( - 'Class {0}.{1} has no __init__() '.format(cls.__module__, - cls.__name__) + - 'method and could not be decorated with @inject decorator') - return cls_init - - def _parse_args_injections(args): """Parse positional argument injections according to current syntax.""" return tuple(Arg(arg) if not is_injection(arg) else arg diff --git a/dependency_injector/utils.py b/dependency_injector/utils.py index 569fcf71..46d170ed 100644 --- a/dependency_injector/utils.py +++ b/dependency_injector/utils.py @@ -1,5 +1,6 @@ """Utils module.""" +import sys import threading import six @@ -13,6 +14,12 @@ GLOBAL_LOCK = threading.RLock() :type: :py:class:`threading.RLock` """ +_IS_PYPY = '__pypy__' in sys.builtin_module_names +if _IS_PYPY or six.PY3: # pragma: no cover + _OBJECT_INIT = six.get_unbound_function(object.__init__) +else: # pragma: no cover + _OBJECT_INIT = None + def is_provider(instance): """Check if instance is provider instance. @@ -220,3 +227,21 @@ def represent_provider(provider, provides): provider.__class__.__name__)), provides=repr(provides) if provides is not None else '', address=hex(id(provider))) + + +def fetch_cls_init(cls): + """Return reference to the class.__init__() method if it is defined. + + :param cls: Class instance + :type cls: type + + :return: Reference to the class.__init__() if any, or None otherwise. + :rtype: unbound method | None + """ + try: + cls_init = six.get_unbound_function(cls.__init__) + assert cls_init is not _OBJECT_INIT + except (AttributeError, AssertionError): + return None + else: + return cls_init