mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-26 03:23:58 +03:00
Implement lazy initialization and improve copying for FactoryAggregate provider
This commit is contained in:
parent
a80e027c51
commit
ee44c8f838
File diff suppressed because it is too large
Load Diff
|
@ -270,6 +270,7 @@ class FactoryAggregate(Provider):
|
|||
|
||||
@property
|
||||
def factories(self) -> _Dict[str, Factory]: ...
|
||||
def set_factories(self, **factories: Factory) -> FactoryAggregate: ...
|
||||
|
||||
|
||||
class BaseSingleton(Provider[T]):
|
||||
|
|
|
@ -2377,29 +2377,19 @@ cdef class FactoryAggregate(Provider):
|
|||
__IS_DELEGATED__ = True
|
||||
|
||||
def __init__(self, **factories):
|
||||
"""Initializer.
|
||||
|
||||
:param factories: Dictionary of aggregate factories.
|
||||
:type factories: dict[str, :py:class:`Factory`]
|
||||
"""
|
||||
for factory in factories.values():
|
||||
if isinstance(factory, Factory) is False:
|
||||
raise Error(
|
||||
'{0} can aggregate only instances of {1}, given - {2}'
|
||||
.format(self.__class__, Factory, factory))
|
||||
self.__factories = factories
|
||||
"""Initialize provider."""
|
||||
self.__factories = {}
|
||||
self.set_factories(**factories)
|
||||
super(FactoryAggregate, self).__init__()
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
"""Create and return full copy of provider."""
|
||||
cdef FactoryAggregate copied
|
||||
|
||||
copied = memo.get(id(self))
|
||||
if copied is not None:
|
||||
return copied
|
||||
|
||||
copied = self.__class__()
|
||||
copied.__factories = deepcopy(self.__factories, memo)
|
||||
copied = _memorized_duplicate(self, memo)
|
||||
copied.set_factories(**deepcopy(self.factories, memo))
|
||||
|
||||
self._copy_overridings(copied, memo)
|
||||
|
||||
|
@ -2421,6 +2411,16 @@ cdef class FactoryAggregate(Provider):
|
|||
"""Return dictionary of factories, read-only."""
|
||||
return self.__factories
|
||||
|
||||
def set_factories(self, **factories):
|
||||
"""Set factories."""
|
||||
for factory in factories.values():
|
||||
if isinstance(factory, Factory) is False:
|
||||
raise Error(
|
||||
'{0} can aggregate only instances of {1}, given - {2}'
|
||||
.format(self.__class__, Factory, factory))
|
||||
self.__factories = factories
|
||||
return self
|
||||
|
||||
def override(self, _):
|
||||
"""Override provider with another provider.
|
||||
|
||||
|
|
|
@ -512,6 +512,26 @@ class FactoryAggregateTests(unittest.TestCase):
|
|||
example_a=providers.Factory(self.ExampleA),
|
||||
example_b=object())
|
||||
|
||||
def test_init_optional_factories(self):
|
||||
provider = providers.FactoryAggregate()
|
||||
provider.set_factories(
|
||||
example_a=self.example_a_factory,
|
||||
example_b=self.example_b_factory,
|
||||
)
|
||||
self.assertEqual(
|
||||
provider.factories,
|
||||
{
|
||||
'example_a': self.example_a_factory,
|
||||
'example_b': self.example_b_factory,
|
||||
},
|
||||
)
|
||||
self.assertIsInstance(provider('example_a'), self.ExampleA)
|
||||
self.assertIsInstance(provider('example_b'), self.ExampleB)
|
||||
|
||||
def test_set_provides_returns_self(self):
|
||||
provider = providers.FactoryAggregate()
|
||||
self.assertIs(provider.set_factories(example_a=self.example_a_factory), provider)
|
||||
|
||||
def test_call(self):
|
||||
object_a = self.factory_aggregate('example_a',
|
||||
1, 2, init_arg3=3, init_arg4=4)
|
||||
|
|
Loading…
Reference in New Issue
Block a user