Make injections 2 times faster

This commit is contained in:
Roman Mogilatov 2016-05-22 15:37:39 +03:00
parent d9aac553c5
commit 7729d97a41
4 changed files with 17 additions and 27 deletions

View File

@ -38,7 +38,7 @@ class Injection(object):
"""
__IS_INJECTION__ = True
__slots__ = ('injectable', 'call_injectable')
__slots__ = ('injectable', 'get_value')
def __init__(self, injectable):
"""Initializer.
@ -49,24 +49,14 @@ class Injection(object):
:py:class:`dependency_injector.providers.Provider`
"""
self.injectable = injectable
self.call_injectable = (is_provider(injectable) and
not is_delegated_provider(injectable))
if not is_provider(injectable) or is_delegated_provider(injectable):
def injectable():
return self.injectable
self.get_value = injectable
super(Injection, self).__init__()
@property
def value(self):
"""Read-only property that represents injectable value.
Injectable values and delegated providers are provided "as is".
Other providers will be called every time, when injection needs to
be done.
:rtype: object
"""
if self.call_injectable:
return self.injectable.provide()
return self.injectable
def __str__(self):
"""Return string representation of provider.
@ -229,11 +219,11 @@ def inject(*args, **kwargs):
def decorated(*args, **kwargs):
"""Decorated with dependency injection callback."""
if decorated.args:
args = tuple(arg.value for arg in decorated.args) + args
args = tuple(arg.get_value() for arg in decorated.args) + args
for kwarg in decorated.kwargs:
if kwarg.name not in kwargs:
kwargs[kwarg.name] = kwarg.value
kwargs[kwarg.name] = kwarg.get_value()
return callback(*args, **kwargs)

View File

@ -102,11 +102,11 @@ class Callable(Provider):
:rtype: object
"""
if self._args:
args = tuple(arg.value for arg in self._args) + args
args = tuple(arg.get_value() for arg in self._args) + args
for kwarg in self._kwargs:
if kwarg.name not in kwargs:
kwargs[kwarg.name] = kwarg.value
kwargs[kwarg.name] = kwarg.get_value()
return self._provides(*args, **kwargs)

View File

@ -120,16 +120,16 @@ class Factory(Callable):
:rtype: object
"""
if self._args:
args = tuple(arg.value for arg in self._args) + args
args = tuple(arg.get_value() for arg in self._args) + args
for kwarg in self._kwargs:
if kwarg.name not in kwargs:
kwargs[kwarg.name] = kwarg.value
kwargs[kwarg.name] = kwarg.get_value()
instance = self._provides(*args, **kwargs)
for attribute in self._attributes:
setattr(instance, attribute.name, attribute.value)
setattr(instance, attribute.name, attribute.get_value())
return instance

View File

@ -19,12 +19,12 @@ class InjectionTests(unittest.TestCase):
def test_value_with_scalar_injectable(self):
"""Test Injection value property with scalar value."""
injection = injections.Injection('some_value')
self.assertEqual(injection.value, 'some_value')
self.assertEqual(injection.get_value(), 'some_value')
def test_value_with_provider_injectable(self):
"""Test Injection value property with provider."""
injection = injections.Injection(providers.Factory(object))
self.assertIsInstance(injection.value, object)
self.assertIsInstance(injection.get_value(), object)
def test_value_with_catalog_bundle_injectable(self):
"""Test Injection value property with catalog bundle."""
@ -35,7 +35,7 @@ class InjectionTests(unittest.TestCase):
injection = injections.Injection(
TestCatalog.Bundle(TestCatalog.provider))
self.assertIsInstance(injection.value, TestCatalog.Bundle)
self.assertIsInstance(injection.get_value(), TestCatalog.Bundle)
def test_repr(self):
"""Test Injection representation."""