Implement lazy initialization and improve copying for Selector provider

This commit is contained in:
Roman Mogylatov 2021-03-08 18:25:35 -05:00
parent ee44c8f838
commit f7fcb22139
4 changed files with 1738 additions and 1434 deletions

File diff suppressed because it is too large Load Diff

View File

@ -389,10 +389,16 @@ class Container(Provider[T]):
class Selector(Provider[Any]):
def __init__(self, selector: _Callable[..., Any], **providers: Provider): ...
def __init__(self, selector: Optional[_Callable[..., Any]] = None, **providers: Provider): ...
def __getattr__(self, name: str) -> Provider: ...
@property
def selector(self) -> Optional[_Callable[..., Any]]: ...
def set_selector(self, selector: Optional[_Callable[..., Any]]) -> Selector: ...
@property
def providers(self) -> _Dict[str, Provider]: ...
def set_providers(self, **providers: Provider) -> Selector: ...
class ProvidedInstanceFluentInterface:

View File

@ -3718,10 +3718,14 @@ cdef class Selector(Provider):
assert isinstance(instance_2, SomeOtherClass)
"""
def __init__(self, selector, **providers):
def __init__(self, selector=None, **providers):
"""Initialize provider."""
self.__selector = selector
self.__providers = providers
self.__selector = None
self.set_selector(selector)
self.__providers = {}
self.set_providers(**providers)
super(Selector, self).__init__()
def __deepcopy__(self, memo):
@ -3730,10 +3734,10 @@ cdef class Selector(Provider):
if copied is not None:
return copied
copied = self.__class__(
deepcopy(self.__selector, memo),
**deepcopy(self.__providers, memo),
)
copied = _memorized_duplicate(self, memo)
copied.set_selector(deepcopy(self.__selector, memo))
copied.set_providers(**deepcopy(self.__providers, memo))
self._copy_overridings(copied, memo)
return copied
@ -3766,11 +3770,26 @@ cdef class Selector(Provider):
address=hex(id(self)),
)
@property
def selector(self):
"""Return selector."""
return self.__selector
def set_selector(self, selector):
"""Set selector."""
self.__selector = selector
return self
@property
def providers(self):
"""Return providers."""
return dict(self.__providers)
def set_providers(self, **providers: Provider):
"""Set providers."""
self.__providers = providers
return self
@property
def related(self):
"""Return related providers generator."""

View File

@ -16,6 +16,28 @@ class SelectorTests(unittest.TestCase):
def test_is_provider(self):
self.assertTrue(providers.is_provider(providers.Selector(self.selector)))
def test_init_optional(self):
one = providers.Object(1)
two = providers.Object(2)
provider = providers.Selector()
provider.set_selector(self.selector)
provider.set_providers(one=one, two=two)
self.assertEqual(provider.providers, {'one': one, 'two': two})
with self.selector.override('one'):
self.assertEqual(provider(), one())
with self.selector.override('two'):
self.assertEqual(provider(), two())
def test_set_selector_returns_self(self):
provider = providers.Selector()
self.assertIs(provider.set_selector(self.selector), provider)
def test_set_providers_returns_self(self):
provider = providers.Selector()
self.assertIs(provider.set_providers(one=providers.Provider()), provider)
def test_provided_instance_provider(self):
provider = providers.Selector(self.selector)
self.assertIsInstance(provider.provided, providers.ProvidedInstance)