mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-16 19:40:59 +03:00
Add provider OverridingContext
This commit is contained in:
parent
cfaaa723fe
commit
1f7a76ef5e
|
@ -60,7 +60,7 @@ class Injection(object):
|
||||||
:rtype: object
|
:rtype: object
|
||||||
"""
|
"""
|
||||||
if self.call_injectable:
|
if self.call_injectable:
|
||||||
return self.injectable()
|
return self.injectable.provide()
|
||||||
return self.injectable
|
return self.injectable
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -64,7 +64,7 @@ class Provider(object):
|
||||||
|
|
||||||
__IS_PROVIDER__ = True
|
__IS_PROVIDER__ = True
|
||||||
__OPTIMIZED_CALLS__ = True
|
__OPTIMIZED_CALLS__ = True
|
||||||
__slots__ = ('overridden_by', '__call__')
|
__slots__ = ('overridden_by', 'provide', '__call__')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Initializer."""
|
"""Initializer."""
|
||||||
|
@ -72,7 +72,7 @@ class Provider(object):
|
||||||
super(Provider, self).__init__()
|
super(Provider, self).__init__()
|
||||||
# Enable __call__() / _provide() optimization
|
# Enable __call__() / _provide() optimization
|
||||||
if self.__class__.__OPTIMIZED_CALLS__:
|
if self.__class__.__OPTIMIZED_CALLS__:
|
||||||
self.__call__ = self._provide
|
self.__call__ = self.provide = self._provide
|
||||||
|
|
||||||
def _provide(self, *args, **kwargs):
|
def _provide(self, *args, **kwargs):
|
||||||
"""Providing strategy implementation.
|
"""Providing strategy implementation.
|
||||||
|
@ -124,9 +124,9 @@ class Provider(object):
|
||||||
|
|
||||||
# Disable __call__() / _provide() optimization
|
# Disable __call__() / _provide() optimization
|
||||||
if self.__class__.__OPTIMIZED_CALLS__:
|
if self.__class__.__OPTIMIZED_CALLS__:
|
||||||
self.__call__ = self._call_last_overriding
|
self.__call__ = self.provide = self._call_last_overriding
|
||||||
|
|
||||||
return provider
|
return OverridingContext(self)
|
||||||
|
|
||||||
def reset_last_overriding(self):
|
def reset_last_overriding(self):
|
||||||
"""Reset last overriding provider.
|
"""Reset last overriding provider.
|
||||||
|
@ -143,7 +143,7 @@ class Provider(object):
|
||||||
if not self.is_overridden:
|
if not self.is_overridden:
|
||||||
# Enable __call__() / _provide() optimization
|
# Enable __call__() / _provide() optimization
|
||||||
if self.__class__.__OPTIMIZED_CALLS__:
|
if self.__class__.__OPTIMIZED_CALLS__:
|
||||||
self.__call__ = self._provide
|
self.__call__ = self.provide = self._provide
|
||||||
|
|
||||||
def reset_override(self):
|
def reset_override(self):
|
||||||
"""Reset all overriding providers.
|
"""Reset all overriding providers.
|
||||||
|
@ -154,7 +154,7 @@ class Provider(object):
|
||||||
|
|
||||||
# Enable __call__() / _provide() optimization
|
# Enable __call__() / _provide() optimization
|
||||||
if self.__class__.__OPTIMIZED_CALLS__:
|
if self.__class__.__OPTIMIZED_CALLS__:
|
||||||
self.__call__ = self._provide
|
self.__call__ = self.provide = self._provide
|
||||||
|
|
||||||
def delegate(self):
|
def delegate(self):
|
||||||
"""Return provider's delegate.
|
"""Return provider's delegate.
|
||||||
|
@ -1042,6 +1042,36 @@ class ChildConfig(Provider):
|
||||||
__repr__ = __str__
|
__repr__ = __str__
|
||||||
|
|
||||||
|
|
||||||
|
class OverridingContext(object):
|
||||||
|
"""Provider overriding context.
|
||||||
|
|
||||||
|
:py:class:`OverridingContext` is used by :py:meth:`Provider.override` for
|
||||||
|
implemeting ``with`` contexts. When :py:class:`OverridingContext` is
|
||||||
|
closed, overriding that was created in this context is dropped also.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
with provider.override(another_provider):
|
||||||
|
assert provider.is_overridden
|
||||||
|
assert not provider.is_overridden
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, overridden):
|
||||||
|
"""Initializer.
|
||||||
|
|
||||||
|
:param overridden: Overridden provider
|
||||||
|
:type overridden: :py:class:`Provider`
|
||||||
|
"""
|
||||||
|
self.overridden = overridden
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
"""Do nothing."""
|
||||||
|
|
||||||
|
def __exit__(self, *_):
|
||||||
|
"""Exit overriding context."""
|
||||||
|
self.overridden.reset_last_overriding()
|
||||||
|
|
||||||
|
|
||||||
def override(overridden):
|
def override(overridden):
|
||||||
"""Decorator for overriding providers.
|
"""Decorator for overriding providers.
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,13 @@ class ProviderTests(unittest.TestCase):
|
||||||
self.provider.override(overriding_provider)
|
self.provider.override(overriding_provider)
|
||||||
self.assertTrue(self.provider.is_overridden)
|
self.assertTrue(self.provider.is_overridden)
|
||||||
|
|
||||||
|
def test_overriding_context(self):
|
||||||
|
"""Test provider overriding context."""
|
||||||
|
overriding_provider = providers.Provider()
|
||||||
|
with self.provider.override(overriding_provider):
|
||||||
|
self.assertTrue(self.provider.is_overridden)
|
||||||
|
self.assertFalse(self.provider.is_overridden)
|
||||||
|
|
||||||
def test_override_with_itself(self):
|
def test_override_with_itself(self):
|
||||||
"""Test provider overriding with itself."""
|
"""Test provider overriding with itself."""
|
||||||
self.assertRaises(errors.Error, self.provider.override, self.provider)
|
self.assertRaises(errors.Error, self.provider.override, self.provider)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user