Add implementation and tests

This commit is contained in:
Roman Mogylatov 2021-01-29 08:47:18 -05:00
parent 1f17bc6e08
commit 6a2d53a28e
6 changed files with 15060 additions and 7958 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,7 @@ cdef class Delegate(Provider):
cdef class Dependency(Provider):
cdef object __instance_of
cdef object __default
cdef class ExternalDependency(Dependency):

View File

@ -82,9 +82,11 @@ class Delegate(Provider[Provider]):
class Dependency(Provider[T]):
def __init__(self, instance_of: Type[T] = object) -> None: ...
def __init__(self, instance_of: Type[T] = object, default: Optional[Union[Provider, Any]] = None) -> None: ...
@property
def instance_of(self) -> Type[T]: ...
@property
def default(self) -> Provider[T]: ...
def provided_by(self, provider: Provider) -> OverridingContext: ...

View File

@ -12,7 +12,6 @@ import sys
import types
import threading
import warnings
import weakref
try:
import asyncio
@ -525,7 +524,7 @@ cdef class Dependency(Provider):
:type: type
"""
def __init__(self, object instance_of=object):
def __init__(self, object instance_of=object, default=UNDEFINED):
"""Initializer."""
if not isinstance(instance_of, CLASS_TYPES):
raise TypeError(
@ -534,8 +533,12 @@ cdef class Dependency(Provider):
instance_of,
)
)
self.__instance_of = instance_of
if default is not UNDEFINED and not isinstance(default, Provider):
default = Object(default)
self.__default = default
super(Dependency, self).__init__()
def __deepcopy__(self, memo):
@ -544,7 +547,8 @@ cdef class Dependency(Provider):
if copied is not None:
return copied
copied = self.__class__(self.__instance_of)
copied_default = deepcopy(self.__default, memo) if self.__default is not UNDEFINED else UNDEFINED
copied = self.__class__(self.__instance_of, copied_default)
self._copy_overridings(copied, memo)
@ -557,12 +561,13 @@ cdef class Dependency(Provider):
:rtype: object
"""
if self.__last_overriding is None:
if self.__last_overriding:
result = self.__last_overriding(*args, **kwargs)
elif not self.__last_overriding and self.__default is not UNDEFINED:
result = self.__default(*args, **kwargs)
else:
raise Error('Dependency is not defined')
result = self.__last_overriding(*args, **kwargs)
if self.is_async_mode_disabled():
self._check_instance_type(result)
return result
@ -609,6 +614,11 @@ cdef class Dependency(Provider):
"""Return class of required dependency."""
return self.__instance_of
@property
def default(self):
"""Return default provider."""
return self.__default
def provided_by(self, provider):
"""Set external dependency provider.

View File

@ -271,6 +271,25 @@ class DependencyTests(unittest.TestCase):
def test_provided_instance_provider(self):
self.assertIsInstance(self.provider.provided, providers.ProvidedInstance)
def test_default(self):
provider = providers.Dependency(instance_of=dict, default={'foo': 'bar'})
self.assertEqual(provider(), {'foo': 'bar'})
def test_default_attribute(self):
provider = providers.Dependency(instance_of=dict, default={'foo': 'bar'})
self.assertEqual(provider.default(), {'foo': 'bar'})
def test_default_provider(self):
provider = providers.Dependency(instance_of=dict, default=providers.Factory(dict, foo='bar'))
self.assertEqual(provider.default(), {'foo': 'bar'})
def test_default_attribute_provider(self):
default = providers.Factory(dict, foo='bar')
provider = providers.Dependency(instance_of=dict, default=default)
self.assertEqual(provider.default(), {'foo': 'bar'})
self.assertIs(provider.default, default)
def test_call_overridden(self):
self.provider.provided_by(providers.Factory(list))
self.assertIsInstance(self.provider(), list)
@ -314,6 +333,62 @@ class DependencyTests(unittest.TestCase):
self.assertIsNot(overriding_provider, overriding_provider_copy)
self.assertIsInstance(overriding_provider_copy, providers.Provider)
def test_deep_copy_default_object(self):
default = {'foo': 'bar'}
provider = providers.Dependency(dict, default=default)
provider_copy = providers.deepcopy(provider)
self.assertIs(provider_copy(), default)
self.assertIs(provider_copy.default(), default)
def test_deep_copy_default_provider(self):
bar = object()
default = providers.Factory(dict, foo=providers.Object(bar))
provider = providers.Dependency(dict, default=default)
provider_copy = providers.deepcopy(provider)
self.assertEqual(provider_copy(), {'foo': bar})
self.assertEqual(provider_copy.default(), {'foo': bar})
self.assertIs(provider_copy()['foo'], bar)
def test_with_container_default_object(self):
default = {'foo': 'bar'}
class Container(containers.DeclarativeContainer):
provider = providers.Dependency(dict, default=default)
container = Container()
self.assertIs(container.provider(), default)
self.assertIs(container.provider.default(), default)
def test_with_container_default_provider(self):
bar = object()
class Container(containers.DeclarativeContainer):
provider = providers.Dependency(dict, default=providers.Factory(dict, foo=providers.Object(bar)))
container = Container()
self.assertEqual(container.provider(), {'foo': bar})
self.assertEqual(container.provider.default(), {'foo': bar})
self.assertIs(container.provider()['foo'], bar)
def test_with_container_default_provider_with_overriding(self):
bar = object()
baz = object()
class Container(containers.DeclarativeContainer):
provider = providers.Dependency(dict, default=providers.Factory(dict, foo=providers.Object(bar)))
container = Container(provider=providers.Factory(dict, foo=providers.Object(baz)))
self.assertEqual(container.provider(), {'foo': baz})
self.assertEqual(container.provider.default(), {'foo': bar})
self.assertIs(container.provider()['foo'], baz)
def test_repr(self):
self.assertEqual(repr(self.provider),
'<dependency_injector.providers.'