From 7729d97a418c37db8eab6e9b022e5d3d1379368c Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Sun, 22 May 2016 15:37:39 +0300 Subject: [PATCH] Make injections 2 times faster --- dependency_injector/injections.py | 28 +++++++-------------- dependency_injector/providers/callable.py | 4 +-- dependency_injector/providers/creational.py | 6 ++--- tests/test_injections.py | 6 ++--- 4 files changed, 17 insertions(+), 27 deletions(-) diff --git a/dependency_injector/injections.py b/dependency_injector/injections.py index fe526715..2387c63c 100644 --- a/dependency_injector/injections.py +++ b/dependency_injector/injections.py @@ -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) diff --git a/dependency_injector/providers/callable.py b/dependency_injector/providers/callable.py index 7caffda5..f2714b3c 100644 --- a/dependency_injector/providers/callable.py +++ b/dependency_injector/providers/callable.py @@ -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) diff --git a/dependency_injector/providers/creational.py b/dependency_injector/providers/creational.py index 785c3471..4a307ed1 100644 --- a/dependency_injector/providers/creational.py +++ b/dependency_injector/providers/creational.py @@ -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 diff --git a/tests/test_injections.py b/tests/test_injections.py index 9fca174f..c9385e18 100644 --- a/tests/test_injections.py +++ b/tests/test_injections.py @@ -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."""