mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-10-31 07:57:43 +03:00 
			
		
		
		
	Merge branch 'release/4.32.0' into master
This commit is contained in:
		
						commit
						fab4e3e5be
					
				|  | @ -7,6 +7,13 @@ that were made in every particular version. | ||||||
| From version 0.7.6 *Dependency Injector* framework strictly  | From version 0.7.6 *Dependency Injector* framework strictly  | ||||||
| follows `Semantic versioning`_ | follows `Semantic versioning`_ | ||||||
| 
 | 
 | ||||||
|  | 4.32.0 | ||||||
|  | ------ | ||||||
|  | - Add ``ContextLocalSingleton`` provider. | ||||||
|  |   See PR: `#443 <https://github.com/ets-labs/python-dependency-injector/pull/442>`_. | ||||||
|  |   Thanks to `@sonthonaxrk <https://github.com/sonthonaxrk>`_ for the contribution. | ||||||
|  | - Regenerate C sources using Cython 0.29.22. | ||||||
|  | 
 | ||||||
| 4.31.2 | 4.31.2 | ||||||
| ------ | ------ | ||||||
| - Fix an issue with ``Dict`` provider non-string keys. | - Fix an issue with ``Dict`` provider non-string keys. | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| cython==0.29.21 | cython==0.29.22 | ||||||
| tox | tox | ||||||
| coverage | coverage | ||||||
| flake8 | flake8 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| """Top-level package.""" | """Top-level package.""" | ||||||
| 
 | 
 | ||||||
| __version__ = '4.31.2' | __version__ = '4.32.0' | ||||||
| """Version number. | """Version number. | ||||||
| 
 | 
 | ||||||
| :type: str | :type: str | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -175,6 +175,11 @@ cdef class ThreadLocalSingleton(BaseSingleton): | ||||||
|     cpdef object _provide(self, tuple args, dict kwargs) |     cpdef object _provide(self, tuple args, dict kwargs) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | cdef class ContextLocalSingleton(BaseSingleton): | ||||||
|  | 
 | ||||||
|  |     cpdef object _provide(self, tuple args, dict kwargs) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton): | cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton): | ||||||
|     pass |     pass | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -336,6 +336,9 @@ class DelegatedThreadSafeSingleton(ThreadSafeSingleton[T]): ... | ||||||
| class ThreadLocalSingleton(BaseSingleton[T]): ... | class ThreadLocalSingleton(BaseSingleton[T]): ... | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class ContextLocalSingleton(BaseSingleton[T]): ... | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class DelegatedThreadLocalSingleton(ThreadLocalSingleton[T]): ... | class DelegatedThreadLocalSingleton(ThreadLocalSingleton[T]): ... | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,6 +13,12 @@ import types | ||||||
| import threading | import threading | ||||||
| import warnings | import warnings | ||||||
| 
 | 
 | ||||||
|  | try: | ||||||
|  |     import contextvars | ||||||
|  | except ImportError: | ||||||
|  |     contextvars = None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| try: | try: | ||||||
|     import asyncio |     import asyncio | ||||||
| except ImportError: | except ImportError: | ||||||
|  | @ -2928,6 +2934,89 @@ cdef class ThreadLocalSingleton(BaseSingleton): | ||||||
|             future_result.set_result(instance) |             future_result.set_result(instance) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | cdef class ContextLocalSingleton(BaseSingleton): | ||||||
|  |     """Context-local singleton provides single objects in scope of a context. | ||||||
|  | 
 | ||||||
|  |     .. py:attribute:: provided_type | ||||||
|  | 
 | ||||||
|  |         If provided type is defined, provider checks that providing class is | ||||||
|  |         its subclass. | ||||||
|  | 
 | ||||||
|  |         :type: type | None | ||||||
|  | 
 | ||||||
|  |     .. py:attribute:: cls | ||||||
|  |        :noindex: | ||||||
|  | 
 | ||||||
|  |         Class that provides object. | ||||||
|  |         Alias for :py:attr:`provides`. | ||||||
|  | 
 | ||||||
|  |         :type: type | ||||||
|  |     """ | ||||||
|  |     _none = object() | ||||||
|  | 
 | ||||||
|  |     def __init__(self, provides=None, *args, **kwargs): | ||||||
|  |         """Initializer. | ||||||
|  | 
 | ||||||
|  |         :param provides: Provided type. | ||||||
|  |         :type provides: type | ||||||
|  |         """ | ||||||
|  |         if not contextvars: | ||||||
|  |             raise RuntimeError( | ||||||
|  |                 'Contextvars library not found. This provider ' | ||||||
|  |                 'requires Python 3.7 or a backport of contextvars. ' | ||||||
|  |                 'To install a backport run "pip install contextvars".' | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |         super(ContextLocalSingleton, self).__init__(provides, *args, **kwargs) | ||||||
|  |         self.__storage = contextvars.ContextVar('__storage', default=self._none) | ||||||
|  | 
 | ||||||
|  |     def reset(self): | ||||||
|  |         """Reset cached instance, if any. | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         instance = self.__storage.get() | ||||||
|  |         if instance is self._none: | ||||||
|  |             return SingletonResetContext(self) | ||||||
|  | 
 | ||||||
|  |         if __is_future_or_coroutine(instance): | ||||||
|  |             asyncio.ensure_future(instance).cancel() | ||||||
|  | 
 | ||||||
|  |         self.__storage.set(self._none) | ||||||
|  | 
 | ||||||
|  |         return SingletonResetContext(self) | ||||||
|  | 
 | ||||||
|  |     cpdef object _provide(self, tuple args, dict kwargs): | ||||||
|  |         """Return single instance.""" | ||||||
|  |         cdef object instance | ||||||
|  | 
 | ||||||
|  |         instance = self.__storage.get() | ||||||
|  | 
 | ||||||
|  |         if instance is self._none: | ||||||
|  |             instance = __factory_call(self.__instantiator, args, kwargs) | ||||||
|  | 
 | ||||||
|  |             if __is_future_or_coroutine(instance): | ||||||
|  |                 future_result = asyncio.Future() | ||||||
|  |                 instance = asyncio.ensure_future(instance) | ||||||
|  |                 instance.add_done_callback(functools.partial(self._async_init_instance, future_result)) | ||||||
|  |                 self.__storage.set(future_result) | ||||||
|  |                 return future_result | ||||||
|  | 
 | ||||||
|  |             self.__storage.set(instance) | ||||||
|  | 
 | ||||||
|  |         return instance | ||||||
|  | 
 | ||||||
|  |     def _async_init_instance(self, future_result, result): | ||||||
|  |         try: | ||||||
|  |             instance = result.result() | ||||||
|  |         except Exception as exception: | ||||||
|  |             self.__storage.set(self._none) | ||||||
|  |             future_result.set_exception(exception) | ||||||
|  |         else: | ||||||
|  |             self.__storage.set(instance) | ||||||
|  |             future_result.set_result(instance) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton): | cdef class DelegatedThreadLocalSingleton(ThreadLocalSingleton): | ||||||
|     """Delegated thread-local singleton is injected "as is". |     """Delegated thread-local singleton is injected "as is". | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										434
									
								
								tests/unit/providers/singleton_common.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										434
									
								
								tests/unit/providers/singleton_common.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,434 @@ | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | from dependency_injector import providers, errors | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Example(object): | ||||||
|  | 
 | ||||||
|  |     def __init__(self, init_arg1=None, init_arg2=None, init_arg3=None, | ||||||
|  |                  init_arg4=None): | ||||||
|  |         self.init_arg1 = init_arg1 | ||||||
|  |         self.init_arg2 = init_arg2 | ||||||
|  |         self.init_arg3 = init_arg3 | ||||||
|  |         self.init_arg4 = init_arg4 | ||||||
|  | 
 | ||||||
|  |         self.attribute1 = None | ||||||
|  |         self.attribute2 = None | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class _BaseSingletonTestCase(object): | ||||||
|  | 
 | ||||||
|  |     singleton_cls = None | ||||||
|  | 
 | ||||||
|  |     def test_is_provider(self): | ||||||
|  |         self.assertTrue(providers.is_provider(self.singleton_cls(Example))) | ||||||
|  | 
 | ||||||
|  |     def test_init_with_callable(self): | ||||||
|  |         self.assertTrue(self.singleton_cls(credits)) | ||||||
|  | 
 | ||||||
|  |     def test_init_with_not_callable(self): | ||||||
|  |         self.assertRaises(errors.Error, self.singleton_cls, 123) | ||||||
|  | 
 | ||||||
|  |     def test_init_optional_provides(self): | ||||||
|  |         provider = self.singleton_cls() | ||||||
|  |         provider.set_provides(object) | ||||||
|  |         self.assertIs(provider.provides, object) | ||||||
|  |         self.assertIsInstance(provider(), object) | ||||||
|  | 
 | ||||||
|  |     def test_set_provides_returns_self(self): | ||||||
|  |         provider = self.singleton_cls() | ||||||
|  |         self.assertIs(provider.set_provides(object), provider) | ||||||
|  | 
 | ||||||
|  |     def test_init_with_valid_provided_type(self): | ||||||
|  |         class ExampleProvider(self.singleton_cls): | ||||||
|  |             provided_type = Example | ||||||
|  | 
 | ||||||
|  |         example_provider = ExampleProvider(Example, 1, 2) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(example_provider(), Example) | ||||||
|  | 
 | ||||||
|  |     def test_init_with_valid_provided_subtype(self): | ||||||
|  |         class ExampleProvider(self.singleton_cls): | ||||||
|  |             provided_type = Example | ||||||
|  | 
 | ||||||
|  |         class NewExampe(Example): | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|  |         example_provider = ExampleProvider(NewExampe, 1, 2) | ||||||
|  | 
 | ||||||
|  |         self.assertIsInstance(example_provider(), NewExampe) | ||||||
|  | 
 | ||||||
|  |     def test_init_with_invalid_provided_type(self): | ||||||
|  |         class ExampleProvider(self.singleton_cls): | ||||||
|  |             provided_type = Example | ||||||
|  | 
 | ||||||
|  |         with self.assertRaises(errors.Error): | ||||||
|  |             ExampleProvider(list) | ||||||
|  | 
 | ||||||
|  |     def test_provided_instance_provider(self): | ||||||
|  |         provider = providers.Singleton(Example) | ||||||
|  |         self.assertIsInstance(provider.provided, providers.ProvidedInstance) | ||||||
|  | 
 | ||||||
|  |     def test_call(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  | 
 | ||||||
|  |         instance1 = provider() | ||||||
|  |         instance2 = provider() | ||||||
|  | 
 | ||||||
|  |         self.assertIs(instance1, instance2) | ||||||
|  |         self.assertIsInstance(instance1, Example) | ||||||
|  |         self.assertIsInstance(instance2, Example) | ||||||
|  | 
 | ||||||
|  |     def test_call_with_init_positional_args(self): | ||||||
|  |         provider = self.singleton_cls(Example, 'i1', 'i2') | ||||||
|  | 
 | ||||||
|  |         instance1 = provider() | ||||||
|  |         instance2 = provider() | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance1.init_arg1, 'i1') | ||||||
|  |         self.assertEqual(instance1.init_arg2, 'i2') | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance2.init_arg1, 'i1') | ||||||
|  |         self.assertEqual(instance2.init_arg2, 'i2') | ||||||
|  | 
 | ||||||
|  |         self.assertIs(instance1, instance2) | ||||||
|  |         self.assertIsInstance(instance1, Example) | ||||||
|  |         self.assertIsInstance(instance2, Example) | ||||||
|  | 
 | ||||||
|  |     def test_call_with_init_keyword_args(self): | ||||||
|  |         provider = self.singleton_cls(Example, init_arg1='i1', init_arg2='i2') | ||||||
|  | 
 | ||||||
|  |         instance1 = provider() | ||||||
|  |         instance2 = provider() | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance1.init_arg1, 'i1') | ||||||
|  |         self.assertEqual(instance1.init_arg2, 'i2') | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance2.init_arg1, 'i1') | ||||||
|  |         self.assertEqual(instance2.init_arg2, 'i2') | ||||||
|  | 
 | ||||||
|  |         self.assertIs(instance1, instance2) | ||||||
|  |         self.assertIsInstance(instance1, Example) | ||||||
|  |         self.assertIsInstance(instance2, Example) | ||||||
|  | 
 | ||||||
|  |     def test_call_with_init_positional_and_keyword_args(self): | ||||||
|  |         provider = self.singleton_cls(Example, 'i1', init_arg2='i2') | ||||||
|  | 
 | ||||||
|  |         instance1 = provider() | ||||||
|  |         instance2 = provider() | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance1.init_arg1, 'i1') | ||||||
|  |         self.assertEqual(instance1.init_arg2, 'i2') | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance2.init_arg1, 'i1') | ||||||
|  |         self.assertEqual(instance2.init_arg2, 'i2') | ||||||
|  | 
 | ||||||
|  |         self.assertIs(instance1, instance2) | ||||||
|  |         self.assertIsInstance(instance1, Example) | ||||||
|  |         self.assertIsInstance(instance2, Example) | ||||||
|  | 
 | ||||||
|  |     def test_call_with_attributes(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  |         provider.add_attributes(attribute1='a1', attribute2='a2') | ||||||
|  | 
 | ||||||
|  |         instance1 = provider() | ||||||
|  |         instance2 = provider() | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance1.attribute1, 'a1') | ||||||
|  |         self.assertEqual(instance1.attribute2, 'a2') | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance2.attribute1, 'a1') | ||||||
|  |         self.assertEqual(instance2.attribute2, 'a2') | ||||||
|  | 
 | ||||||
|  |         self.assertIs(instance1, instance2) | ||||||
|  |         self.assertIsInstance(instance1, Example) | ||||||
|  |         self.assertIsInstance(instance2, Example) | ||||||
|  | 
 | ||||||
|  |     def test_call_with_context_args(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  | 
 | ||||||
|  |         instance = provider(11, 22) | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance.init_arg1, 11) | ||||||
|  |         self.assertEqual(instance.init_arg2, 22) | ||||||
|  | 
 | ||||||
|  |     def test_call_with_context_kwargs(self): | ||||||
|  |         provider = self.singleton_cls(Example, init_arg1=1) | ||||||
|  | 
 | ||||||
|  |         instance1 = provider(init_arg2=22) | ||||||
|  |         self.assertEqual(instance1.init_arg1, 1) | ||||||
|  |         self.assertEqual(instance1.init_arg2, 22) | ||||||
|  | 
 | ||||||
|  |         # Instance is created earlier | ||||||
|  |         instance1 = provider(init_arg1=11, init_arg2=22) | ||||||
|  |         self.assertEqual(instance1.init_arg1, 1) | ||||||
|  |         self.assertEqual(instance1.init_arg2, 22) | ||||||
|  | 
 | ||||||
|  |     def test_call_with_context_args_and_kwargs(self): | ||||||
|  |         provider = self.singleton_cls(Example, 11) | ||||||
|  | 
 | ||||||
|  |         instance = provider(22, init_arg3=33, init_arg4=44) | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance.init_arg1, 11) | ||||||
|  |         self.assertEqual(instance.init_arg2, 22) | ||||||
|  |         self.assertEqual(instance.init_arg3, 33) | ||||||
|  |         self.assertEqual(instance.init_arg4, 44) | ||||||
|  | 
 | ||||||
|  |     def test_fluent_interface(self): | ||||||
|  |         provider = self.singleton_cls(Example) \ | ||||||
|  |             .add_args(1, 2) \ | ||||||
|  |             .add_kwargs(init_arg3=3, init_arg4=4) \ | ||||||
|  |             .add_attributes(attribute1=5, attribute2=6) | ||||||
|  | 
 | ||||||
|  |         instance = provider() | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(instance.init_arg1, 1) | ||||||
|  |         self.assertEqual(instance.init_arg2, 2) | ||||||
|  |         self.assertEqual(instance.init_arg3, 3) | ||||||
|  |         self.assertEqual(instance.init_arg4, 4) | ||||||
|  |         self.assertEqual(instance.attribute1, 5) | ||||||
|  |         self.assertEqual(instance.attribute2, 6) | ||||||
|  | 
 | ||||||
|  |     def test_set_args(self): | ||||||
|  |         provider = self.singleton_cls(Example) \ | ||||||
|  |             .add_args(1, 2) \ | ||||||
|  |             .set_args(3, 4) | ||||||
|  |         self.assertEqual(provider.args, (3, 4)) | ||||||
|  | 
 | ||||||
|  |     def test_set_kwargs(self): | ||||||
|  |         provider = self.singleton_cls(Example) \ | ||||||
|  |             .add_kwargs(init_arg3=3, init_arg4=4) \ | ||||||
|  |             .set_kwargs(init_arg3=4, init_arg4=5) | ||||||
|  |         self.assertEqual(provider.kwargs, dict(init_arg3=4, init_arg4=5)) | ||||||
|  | 
 | ||||||
|  |     def test_set_attributes(self): | ||||||
|  |         provider = self.singleton_cls(Example) \ | ||||||
|  |             .add_attributes(attribute1=5, attribute2=6) \ | ||||||
|  |             .set_attributes(attribute1=6, attribute2=7) | ||||||
|  |         self.assertEqual(provider.attributes, dict(attribute1=6, attribute2=7)) | ||||||
|  | 
 | ||||||
|  |     def test_clear_args(self): | ||||||
|  |         provider = self.singleton_cls(Example) \ | ||||||
|  |             .add_args(1, 2) \ | ||||||
|  |             .clear_args() | ||||||
|  |         self.assertEqual(provider.args, tuple()) | ||||||
|  | 
 | ||||||
|  |     def test_clear_kwargs(self): | ||||||
|  |         provider = self.singleton_cls(Example) \ | ||||||
|  |             .add_kwargs(init_arg3=3, init_arg4=4) \ | ||||||
|  |             .clear_kwargs() | ||||||
|  |         self.assertEqual(provider.kwargs, dict()) | ||||||
|  | 
 | ||||||
|  |     def test_clear_attributes(self): | ||||||
|  |         provider = self.singleton_cls(Example) \ | ||||||
|  |             .add_attributes(attribute1=5, attribute2=6) \ | ||||||
|  |             .clear_attributes() | ||||||
|  |         self.assertEqual(provider.attributes, dict()) | ||||||
|  | 
 | ||||||
|  |     def test_call_overridden(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  |         overriding_provider1 = self.singleton_cls(dict) | ||||||
|  |         overriding_provider2 = self.singleton_cls(list) | ||||||
|  | 
 | ||||||
|  |         provider.override(overriding_provider1) | ||||||
|  |         provider.override(overriding_provider2) | ||||||
|  | 
 | ||||||
|  |         instance1 = provider() | ||||||
|  |         instance2 = provider() | ||||||
|  | 
 | ||||||
|  |         self.assertIs(instance1, instance2) | ||||||
|  |         self.assertIsInstance(instance1, list) | ||||||
|  |         self.assertIsInstance(instance2, list) | ||||||
|  | 
 | ||||||
|  |     def test_deepcopy(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  | 
 | ||||||
|  |         provider_copy = providers.deepcopy(provider) | ||||||
|  | 
 | ||||||
|  |         self.assertIsNot(provider, provider_copy) | ||||||
|  |         self.assertIs(provider.cls, provider_copy.cls) | ||||||
|  |         self.assertIsInstance(provider, self.singleton_cls) | ||||||
|  | 
 | ||||||
|  |     def test_deepcopy_from_memo(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  |         provider_copy_memo = self.singleton_cls(Example) | ||||||
|  | 
 | ||||||
|  |         provider_copy = providers.deepcopy( | ||||||
|  |             provider, memo={id(provider): provider_copy_memo}) | ||||||
|  | 
 | ||||||
|  |         self.assertIs(provider_copy, provider_copy_memo) | ||||||
|  | 
 | ||||||
|  |     def test_deepcopy_args(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  |         dependent_provider1 = self.singleton_cls(list) | ||||||
|  |         dependent_provider2 = self.singleton_cls(dict) | ||||||
|  | 
 | ||||||
|  |         provider.add_args(dependent_provider1, dependent_provider2) | ||||||
|  | 
 | ||||||
|  |         provider_copy = providers.deepcopy(provider) | ||||||
|  |         dependent_provider_copy1 = provider_copy.args[0] | ||||||
|  |         dependent_provider_copy2 = provider_copy.args[1] | ||||||
|  | 
 | ||||||
|  |         self.assertNotEqual(provider.args, provider_copy.args) | ||||||
|  | 
 | ||||||
|  |         self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls) | ||||||
|  |         self.assertIsNot(dependent_provider1, dependent_provider_copy1) | ||||||
|  | 
 | ||||||
|  |         self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls) | ||||||
|  |         self.assertIsNot(dependent_provider2, dependent_provider_copy2) | ||||||
|  | 
 | ||||||
|  |     def test_deepcopy_kwargs(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  |         dependent_provider1 = self.singleton_cls(list) | ||||||
|  |         dependent_provider2 = self.singleton_cls(dict) | ||||||
|  | 
 | ||||||
|  |         provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2) | ||||||
|  | 
 | ||||||
|  |         provider_copy = providers.deepcopy(provider) | ||||||
|  |         dependent_provider_copy1 = provider_copy.kwargs['a1'] | ||||||
|  |         dependent_provider_copy2 = provider_copy.kwargs['a2'] | ||||||
|  | 
 | ||||||
|  |         self.assertNotEqual(provider.kwargs, provider_copy.kwargs) | ||||||
|  | 
 | ||||||
|  |         self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls) | ||||||
|  |         self.assertIsNot(dependent_provider1, dependent_provider_copy1) | ||||||
|  | 
 | ||||||
|  |         self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls) | ||||||
|  |         self.assertIsNot(dependent_provider2, dependent_provider_copy2) | ||||||
|  | 
 | ||||||
|  |     def test_deepcopy_attributes(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  |         dependent_provider1 = self.singleton_cls(list) | ||||||
|  |         dependent_provider2 = self.singleton_cls(dict) | ||||||
|  | 
 | ||||||
|  |         provider.add_attributes(a1=dependent_provider1, a2=dependent_provider2) | ||||||
|  | 
 | ||||||
|  |         provider_copy = providers.deepcopy(provider) | ||||||
|  |         dependent_provider_copy1 = provider_copy.attributes['a1'] | ||||||
|  |         dependent_provider_copy2 = provider_copy.attributes['a2'] | ||||||
|  | 
 | ||||||
|  |         self.assertNotEqual(provider.attributes, provider_copy.attributes) | ||||||
|  | 
 | ||||||
|  |         self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls) | ||||||
|  |         self.assertIsNot(dependent_provider1, dependent_provider_copy1) | ||||||
|  | 
 | ||||||
|  |         self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls) | ||||||
|  |         self.assertIsNot(dependent_provider2, dependent_provider_copy2) | ||||||
|  | 
 | ||||||
|  |     def test_deepcopy_overridden(self): | ||||||
|  |         provider = self.singleton_cls(Example) | ||||||
|  |         object_provider = providers.Object(object()) | ||||||
|  | 
 | ||||||
|  |         provider.override(object_provider) | ||||||
|  | 
 | ||||||
|  |         provider_copy = providers.deepcopy(provider) | ||||||
|  |         object_provider_copy = provider_copy.overridden[0] | ||||||
|  | 
 | ||||||
|  |         self.assertIsNot(provider, provider_copy) | ||||||
|  |         self.assertIs(provider.cls, provider_copy.cls) | ||||||
|  |         self.assertIsInstance(provider, self.singleton_cls) | ||||||
|  | 
 | ||||||
|  |         self.assertIsNot(object_provider, object_provider_copy) | ||||||
|  |         self.assertIsInstance(object_provider_copy, providers.Object) | ||||||
|  | 
 | ||||||
|  |     def test_deepcopy_with_sys_streams(self): | ||||||
|  |         provider = providers.Singleton(Example) | ||||||
|  |         provider.add_args(sys.stdin) | ||||||
|  |         provider.add_kwargs(a2=sys.stdout) | ||||||
|  |         provider.add_attributes(a3=sys.stderr) | ||||||
|  | 
 | ||||||
|  |         provider_copy = providers.deepcopy(provider) | ||||||
|  | 
 | ||||||
|  |         self.assertIsNot(provider, provider_copy) | ||||||
|  |         self.assertIsInstance(provider_copy, providers.Singleton) | ||||||
|  |         self.assertIs(provider.args[0], sys.stdin) | ||||||
|  |         self.assertIs(provider.kwargs['a2'], sys.stdout) | ||||||
|  |         self.assertIs(provider.attributes['a3'], sys.stderr) | ||||||
|  | 
 | ||||||
|  |     def test_reset(self): | ||||||
|  |         provider = self.singleton_cls(object) | ||||||
|  | 
 | ||||||
|  |         instance1 = provider() | ||||||
|  |         self.assertIsInstance(instance1, object) | ||||||
|  | 
 | ||||||
|  |         provider.reset() | ||||||
|  | 
 | ||||||
|  |         instance2 = provider() | ||||||
|  |         self.assertIsInstance(instance2, object) | ||||||
|  | 
 | ||||||
|  |         self.assertIsNot(instance1, instance2) | ||||||
|  | 
 | ||||||
|  |     def test_reset_with_singleton(self): | ||||||
|  |         dependent_singleton = providers.Singleton(object) | ||||||
|  |         provider = self.singleton_cls(dict, dependency=dependent_singleton) | ||||||
|  | 
 | ||||||
|  |         dependent_instance = dependent_singleton() | ||||||
|  |         instance1 = provider() | ||||||
|  |         self.assertIs(instance1['dependency'], dependent_instance) | ||||||
|  | 
 | ||||||
|  |         provider.reset() | ||||||
|  | 
 | ||||||
|  |         instance2 = provider() | ||||||
|  |         self.assertIs(instance1['dependency'], dependent_instance) | ||||||
|  | 
 | ||||||
|  |         self.assertIsNot(instance1, instance2) | ||||||
|  | 
 | ||||||
|  |     def test_reset_context_manager(self): | ||||||
|  |         singleton = self.singleton_cls(object) | ||||||
|  | 
 | ||||||
|  |         instance1 = singleton() | ||||||
|  |         with singleton.reset(): | ||||||
|  |             instance2 = singleton() | ||||||
|  |         instance3 = singleton() | ||||||
|  |         self.assertEqual(len({instance1, instance2, instance3}), 3) | ||||||
|  | 
 | ||||||
|  |     def test_reset_context_manager_as_attribute(self): | ||||||
|  |         singleton = self.singleton_cls(object) | ||||||
|  | 
 | ||||||
|  |         with singleton.reset() as alias: | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|  |         self.assertIs(singleton, alias) | ||||||
|  | 
 | ||||||
|  |     def test_full_reset(self): | ||||||
|  |         dependent_singleton = providers.Singleton(object) | ||||||
|  |         provider = self.singleton_cls(dict, dependency=dependent_singleton) | ||||||
|  | 
 | ||||||
|  |         dependent_instance1 = dependent_singleton() | ||||||
|  |         instance1 = provider() | ||||||
|  |         self.assertIs(instance1['dependency'], dependent_instance1) | ||||||
|  | 
 | ||||||
|  |         provider.full_reset() | ||||||
|  | 
 | ||||||
|  |         dependent_instance2 = dependent_singleton() | ||||||
|  |         instance2 = provider() | ||||||
|  |         self.assertIsNot(instance2['dependency'], dependent_instance1) | ||||||
|  |         self.assertIsNot(dependent_instance1, dependent_instance2) | ||||||
|  |         self.assertIsNot(instance1, instance2) | ||||||
|  | 
 | ||||||
|  |     def test_full_reset_context_manager(self): | ||||||
|  |         class Item: | ||||||
|  |             def __init__(self, dependency): | ||||||
|  |                 self.dependency = dependency | ||||||
|  | 
 | ||||||
|  |         dependent_singleton = providers.Singleton(object) | ||||||
|  |         singleton = self.singleton_cls(Item, dependency=dependent_singleton) | ||||||
|  | 
 | ||||||
|  |         instance1 = singleton() | ||||||
|  |         with singleton.full_reset(): | ||||||
|  |             instance2 = singleton() | ||||||
|  |         instance3 = singleton() | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(len({instance1, instance2, instance3}), 3) | ||||||
|  |         self.assertEqual( | ||||||
|  |             len({instance1.dependency, instance2.dependency, instance3.dependency}), | ||||||
|  |             3, | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def test_full_reset_context_manager_as_attribute(self): | ||||||
|  |         singleton = self.singleton_cls(object) | ||||||
|  | 
 | ||||||
|  |         with singleton.full_reset() as alias: | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|  |         self.assertIs(singleton, alias) | ||||||
|  | @ -1,7 +1,5 @@ | ||||||
| """Dependency injector singleton providers unit tests.""" | """Dependency injector singleton providers unit tests.""" | ||||||
| 
 | 
 | ||||||
| import sys |  | ||||||
| 
 |  | ||||||
| import unittest | import unittest | ||||||
| 
 | 
 | ||||||
| from dependency_injector import ( | from dependency_injector import ( | ||||||
|  | @ -9,436 +7,7 @@ from dependency_injector import ( | ||||||
|     errors, |     errors, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| 
 | from .singleton_common import Example, _BaseSingletonTestCase | ||||||
| class Example(object): |  | ||||||
| 
 |  | ||||||
|     def __init__(self, init_arg1=None, init_arg2=None, init_arg3=None, |  | ||||||
|                  init_arg4=None): |  | ||||||
|         self.init_arg1 = init_arg1 |  | ||||||
|         self.init_arg2 = init_arg2 |  | ||||||
|         self.init_arg3 = init_arg3 |  | ||||||
|         self.init_arg4 = init_arg4 |  | ||||||
| 
 |  | ||||||
|         self.attribute1 = None |  | ||||||
|         self.attribute2 = None |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class _BaseSingletonTestCase(object): |  | ||||||
| 
 |  | ||||||
|     singleton_cls = None |  | ||||||
| 
 |  | ||||||
|     def test_is_provider(self): |  | ||||||
|         self.assertTrue(providers.is_provider(self.singleton_cls(Example))) |  | ||||||
| 
 |  | ||||||
|     def test_init_with_callable(self): |  | ||||||
|         self.assertTrue(self.singleton_cls(credits)) |  | ||||||
| 
 |  | ||||||
|     def test_init_with_not_callable(self): |  | ||||||
|         self.assertRaises(errors.Error, self.singleton_cls, 123) |  | ||||||
| 
 |  | ||||||
|     def test_init_optional_provides(self): |  | ||||||
|         provider = self.singleton_cls() |  | ||||||
|         provider.set_provides(object) |  | ||||||
|         self.assertIs(provider.provides, object) |  | ||||||
|         self.assertIsInstance(provider(), object) |  | ||||||
| 
 |  | ||||||
|     def test_set_provides_returns_self(self): |  | ||||||
|         provider = self.singleton_cls() |  | ||||||
|         self.assertIs(provider.set_provides(object), provider) |  | ||||||
| 
 |  | ||||||
|     def test_init_with_valid_provided_type(self): |  | ||||||
|         class ExampleProvider(self.singleton_cls): |  | ||||||
|             provided_type = Example |  | ||||||
| 
 |  | ||||||
|         example_provider = ExampleProvider(Example, 1, 2) |  | ||||||
| 
 |  | ||||||
|         self.assertIsInstance(example_provider(), Example) |  | ||||||
| 
 |  | ||||||
|     def test_init_with_valid_provided_subtype(self): |  | ||||||
|         class ExampleProvider(self.singleton_cls): |  | ||||||
|             provided_type = Example |  | ||||||
| 
 |  | ||||||
|         class NewExampe(Example): |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         example_provider = ExampleProvider(NewExampe, 1, 2) |  | ||||||
| 
 |  | ||||||
|         self.assertIsInstance(example_provider(), NewExampe) |  | ||||||
| 
 |  | ||||||
|     def test_init_with_invalid_provided_type(self): |  | ||||||
|         class ExampleProvider(self.singleton_cls): |  | ||||||
|             provided_type = Example |  | ||||||
| 
 |  | ||||||
|         with self.assertRaises(errors.Error): |  | ||||||
|             ExampleProvider(list) |  | ||||||
| 
 |  | ||||||
|     def test_provided_instance_provider(self): |  | ||||||
|         provider = providers.Singleton(Example) |  | ||||||
|         self.assertIsInstance(provider.provided, providers.ProvidedInstance) |  | ||||||
| 
 |  | ||||||
|     def test_call(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
| 
 |  | ||||||
|         instance1 = provider() |  | ||||||
|         instance2 = provider() |  | ||||||
| 
 |  | ||||||
|         self.assertIs(instance1, instance2) |  | ||||||
|         self.assertIsInstance(instance1, Example) |  | ||||||
|         self.assertIsInstance(instance2, Example) |  | ||||||
| 
 |  | ||||||
|     def test_call_with_init_positional_args(self): |  | ||||||
|         provider = self.singleton_cls(Example, 'i1', 'i2') |  | ||||||
| 
 |  | ||||||
|         instance1 = provider() |  | ||||||
|         instance2 = provider() |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance1.init_arg1, 'i1') |  | ||||||
|         self.assertEqual(instance1.init_arg2, 'i2') |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance2.init_arg1, 'i1') |  | ||||||
|         self.assertEqual(instance2.init_arg2, 'i2') |  | ||||||
| 
 |  | ||||||
|         self.assertIs(instance1, instance2) |  | ||||||
|         self.assertIsInstance(instance1, Example) |  | ||||||
|         self.assertIsInstance(instance2, Example) |  | ||||||
| 
 |  | ||||||
|     def test_call_with_init_keyword_args(self): |  | ||||||
|         provider = self.singleton_cls(Example, init_arg1='i1', init_arg2='i2') |  | ||||||
| 
 |  | ||||||
|         instance1 = provider() |  | ||||||
|         instance2 = provider() |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance1.init_arg1, 'i1') |  | ||||||
|         self.assertEqual(instance1.init_arg2, 'i2') |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance2.init_arg1, 'i1') |  | ||||||
|         self.assertEqual(instance2.init_arg2, 'i2') |  | ||||||
| 
 |  | ||||||
|         self.assertIs(instance1, instance2) |  | ||||||
|         self.assertIsInstance(instance1, Example) |  | ||||||
|         self.assertIsInstance(instance2, Example) |  | ||||||
| 
 |  | ||||||
|     def test_call_with_init_positional_and_keyword_args(self): |  | ||||||
|         provider = self.singleton_cls(Example, 'i1', init_arg2='i2') |  | ||||||
| 
 |  | ||||||
|         instance1 = provider() |  | ||||||
|         instance2 = provider() |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance1.init_arg1, 'i1') |  | ||||||
|         self.assertEqual(instance1.init_arg2, 'i2') |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance2.init_arg1, 'i1') |  | ||||||
|         self.assertEqual(instance2.init_arg2, 'i2') |  | ||||||
| 
 |  | ||||||
|         self.assertIs(instance1, instance2) |  | ||||||
|         self.assertIsInstance(instance1, Example) |  | ||||||
|         self.assertIsInstance(instance2, Example) |  | ||||||
| 
 |  | ||||||
|     def test_call_with_attributes(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
|         provider.add_attributes(attribute1='a1', attribute2='a2') |  | ||||||
| 
 |  | ||||||
|         instance1 = provider() |  | ||||||
|         instance2 = provider() |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance1.attribute1, 'a1') |  | ||||||
|         self.assertEqual(instance1.attribute2, 'a2') |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance2.attribute1, 'a1') |  | ||||||
|         self.assertEqual(instance2.attribute2, 'a2') |  | ||||||
| 
 |  | ||||||
|         self.assertIs(instance1, instance2) |  | ||||||
|         self.assertIsInstance(instance1, Example) |  | ||||||
|         self.assertIsInstance(instance2, Example) |  | ||||||
| 
 |  | ||||||
|     def test_call_with_context_args(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
| 
 |  | ||||||
|         instance = provider(11, 22) |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance.init_arg1, 11) |  | ||||||
|         self.assertEqual(instance.init_arg2, 22) |  | ||||||
| 
 |  | ||||||
|     def test_call_with_context_kwargs(self): |  | ||||||
|         provider = self.singleton_cls(Example, init_arg1=1) |  | ||||||
| 
 |  | ||||||
|         instance1 = provider(init_arg2=22) |  | ||||||
|         self.assertEqual(instance1.init_arg1, 1) |  | ||||||
|         self.assertEqual(instance1.init_arg2, 22) |  | ||||||
| 
 |  | ||||||
|         # Instance is created earlier |  | ||||||
|         instance1 = provider(init_arg1=11, init_arg2=22) |  | ||||||
|         self.assertEqual(instance1.init_arg1, 1) |  | ||||||
|         self.assertEqual(instance1.init_arg2, 22) |  | ||||||
| 
 |  | ||||||
|     def test_call_with_context_args_and_kwargs(self): |  | ||||||
|         provider = self.singleton_cls(Example, 11) |  | ||||||
| 
 |  | ||||||
|         instance = provider(22, init_arg3=33, init_arg4=44) |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance.init_arg1, 11) |  | ||||||
|         self.assertEqual(instance.init_arg2, 22) |  | ||||||
|         self.assertEqual(instance.init_arg3, 33) |  | ||||||
|         self.assertEqual(instance.init_arg4, 44) |  | ||||||
| 
 |  | ||||||
|     def test_fluent_interface(self): |  | ||||||
|         provider = self.singleton_cls(Example) \ |  | ||||||
|             .add_args(1, 2) \ |  | ||||||
|             .add_kwargs(init_arg3=3, init_arg4=4) \ |  | ||||||
|             .add_attributes(attribute1=5, attribute2=6) |  | ||||||
| 
 |  | ||||||
|         instance = provider() |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(instance.init_arg1, 1) |  | ||||||
|         self.assertEqual(instance.init_arg2, 2) |  | ||||||
|         self.assertEqual(instance.init_arg3, 3) |  | ||||||
|         self.assertEqual(instance.init_arg4, 4) |  | ||||||
|         self.assertEqual(instance.attribute1, 5) |  | ||||||
|         self.assertEqual(instance.attribute2, 6) |  | ||||||
| 
 |  | ||||||
|     def test_set_args(self): |  | ||||||
|         provider = self.singleton_cls(Example) \ |  | ||||||
|             .add_args(1, 2) \ |  | ||||||
|             .set_args(3, 4) |  | ||||||
|         self.assertEqual(provider.args, (3, 4)) |  | ||||||
| 
 |  | ||||||
|     def test_set_kwargs(self): |  | ||||||
|         provider = self.singleton_cls(Example) \ |  | ||||||
|             .add_kwargs(init_arg3=3, init_arg4=4) \ |  | ||||||
|             .set_kwargs(init_arg3=4, init_arg4=5) |  | ||||||
|         self.assertEqual(provider.kwargs, dict(init_arg3=4, init_arg4=5)) |  | ||||||
| 
 |  | ||||||
|     def test_set_attributes(self): |  | ||||||
|         provider = self.singleton_cls(Example) \ |  | ||||||
|             .add_attributes(attribute1=5, attribute2=6) \ |  | ||||||
|             .set_attributes(attribute1=6, attribute2=7) |  | ||||||
|         self.assertEqual(provider.attributes, dict(attribute1=6, attribute2=7)) |  | ||||||
| 
 |  | ||||||
|     def test_clear_args(self): |  | ||||||
|         provider = self.singleton_cls(Example) \ |  | ||||||
|             .add_args(1, 2) \ |  | ||||||
|             .clear_args() |  | ||||||
|         self.assertEqual(provider.args, tuple()) |  | ||||||
| 
 |  | ||||||
|     def test_clear_kwargs(self): |  | ||||||
|         provider = self.singleton_cls(Example) \ |  | ||||||
|             .add_kwargs(init_arg3=3, init_arg4=4) \ |  | ||||||
|             .clear_kwargs() |  | ||||||
|         self.assertEqual(provider.kwargs, dict()) |  | ||||||
| 
 |  | ||||||
|     def test_clear_attributes(self): |  | ||||||
|         provider = self.singleton_cls(Example) \ |  | ||||||
|             .add_attributes(attribute1=5, attribute2=6) \ |  | ||||||
|             .clear_attributes() |  | ||||||
|         self.assertEqual(provider.attributes, dict()) |  | ||||||
| 
 |  | ||||||
|     def test_call_overridden(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
|         overriding_provider1 = self.singleton_cls(dict) |  | ||||||
|         overriding_provider2 = self.singleton_cls(list) |  | ||||||
| 
 |  | ||||||
|         provider.override(overriding_provider1) |  | ||||||
|         provider.override(overriding_provider2) |  | ||||||
| 
 |  | ||||||
|         instance1 = provider() |  | ||||||
|         instance2 = provider() |  | ||||||
| 
 |  | ||||||
|         self.assertIs(instance1, instance2) |  | ||||||
|         self.assertIsInstance(instance1, list) |  | ||||||
|         self.assertIsInstance(instance2, list) |  | ||||||
| 
 |  | ||||||
|     def test_deepcopy(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
| 
 |  | ||||||
|         provider_copy = providers.deepcopy(provider) |  | ||||||
| 
 |  | ||||||
|         self.assertIsNot(provider, provider_copy) |  | ||||||
|         self.assertIs(provider.cls, provider_copy.cls) |  | ||||||
|         self.assertIsInstance(provider, self.singleton_cls) |  | ||||||
| 
 |  | ||||||
|     def test_deepcopy_from_memo(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
|         provider_copy_memo = self.singleton_cls(Example) |  | ||||||
| 
 |  | ||||||
|         provider_copy = providers.deepcopy( |  | ||||||
|             provider, memo={id(provider): provider_copy_memo}) |  | ||||||
| 
 |  | ||||||
|         self.assertIs(provider_copy, provider_copy_memo) |  | ||||||
| 
 |  | ||||||
|     def test_deepcopy_args(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
|         dependent_provider1 = self.singleton_cls(list) |  | ||||||
|         dependent_provider2 = self.singleton_cls(dict) |  | ||||||
| 
 |  | ||||||
|         provider.add_args(dependent_provider1, dependent_provider2) |  | ||||||
| 
 |  | ||||||
|         provider_copy = providers.deepcopy(provider) |  | ||||||
|         dependent_provider_copy1 = provider_copy.args[0] |  | ||||||
|         dependent_provider_copy2 = provider_copy.args[1] |  | ||||||
| 
 |  | ||||||
|         self.assertNotEqual(provider.args, provider_copy.args) |  | ||||||
| 
 |  | ||||||
|         self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls) |  | ||||||
|         self.assertIsNot(dependent_provider1, dependent_provider_copy1) |  | ||||||
| 
 |  | ||||||
|         self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls) |  | ||||||
|         self.assertIsNot(dependent_provider2, dependent_provider_copy2) |  | ||||||
| 
 |  | ||||||
|     def test_deepcopy_kwargs(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
|         dependent_provider1 = self.singleton_cls(list) |  | ||||||
|         dependent_provider2 = self.singleton_cls(dict) |  | ||||||
| 
 |  | ||||||
|         provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2) |  | ||||||
| 
 |  | ||||||
|         provider_copy = providers.deepcopy(provider) |  | ||||||
|         dependent_provider_copy1 = provider_copy.kwargs['a1'] |  | ||||||
|         dependent_provider_copy2 = provider_copy.kwargs['a2'] |  | ||||||
| 
 |  | ||||||
|         self.assertNotEqual(provider.kwargs, provider_copy.kwargs) |  | ||||||
| 
 |  | ||||||
|         self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls) |  | ||||||
|         self.assertIsNot(dependent_provider1, dependent_provider_copy1) |  | ||||||
| 
 |  | ||||||
|         self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls) |  | ||||||
|         self.assertIsNot(dependent_provider2, dependent_provider_copy2) |  | ||||||
| 
 |  | ||||||
|     def test_deepcopy_attributes(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
|         dependent_provider1 = self.singleton_cls(list) |  | ||||||
|         dependent_provider2 = self.singleton_cls(dict) |  | ||||||
| 
 |  | ||||||
|         provider.add_attributes(a1=dependent_provider1, a2=dependent_provider2) |  | ||||||
| 
 |  | ||||||
|         provider_copy = providers.deepcopy(provider) |  | ||||||
|         dependent_provider_copy1 = provider_copy.attributes['a1'] |  | ||||||
|         dependent_provider_copy2 = provider_copy.attributes['a2'] |  | ||||||
| 
 |  | ||||||
|         self.assertNotEqual(provider.attributes, provider_copy.attributes) |  | ||||||
| 
 |  | ||||||
|         self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls) |  | ||||||
|         self.assertIsNot(dependent_provider1, dependent_provider_copy1) |  | ||||||
| 
 |  | ||||||
|         self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls) |  | ||||||
|         self.assertIsNot(dependent_provider2, dependent_provider_copy2) |  | ||||||
| 
 |  | ||||||
|     def test_deepcopy_overridden(self): |  | ||||||
|         provider = self.singleton_cls(Example) |  | ||||||
|         object_provider = providers.Object(object()) |  | ||||||
| 
 |  | ||||||
|         provider.override(object_provider) |  | ||||||
| 
 |  | ||||||
|         provider_copy = providers.deepcopy(provider) |  | ||||||
|         object_provider_copy = provider_copy.overridden[0] |  | ||||||
| 
 |  | ||||||
|         self.assertIsNot(provider, provider_copy) |  | ||||||
|         self.assertIs(provider.cls, provider_copy.cls) |  | ||||||
|         self.assertIsInstance(provider, self.singleton_cls) |  | ||||||
| 
 |  | ||||||
|         self.assertIsNot(object_provider, object_provider_copy) |  | ||||||
|         self.assertIsInstance(object_provider_copy, providers.Object) |  | ||||||
| 
 |  | ||||||
|     def test_deepcopy_with_sys_streams(self): |  | ||||||
|         provider = providers.Singleton(Example) |  | ||||||
|         provider.add_args(sys.stdin) |  | ||||||
|         provider.add_kwargs(a2=sys.stdout) |  | ||||||
|         provider.add_attributes(a3=sys.stderr) |  | ||||||
| 
 |  | ||||||
|         provider_copy = providers.deepcopy(provider) |  | ||||||
| 
 |  | ||||||
|         self.assertIsNot(provider, provider_copy) |  | ||||||
|         self.assertIsInstance(provider_copy, providers.Singleton) |  | ||||||
|         self.assertIs(provider.args[0], sys.stdin) |  | ||||||
|         self.assertIs(provider.kwargs['a2'], sys.stdout) |  | ||||||
|         self.assertIs(provider.attributes['a3'], sys.stderr) |  | ||||||
| 
 |  | ||||||
|     def test_reset(self): |  | ||||||
|         provider = self.singleton_cls(object) |  | ||||||
| 
 |  | ||||||
|         instance1 = provider() |  | ||||||
|         self.assertIsInstance(instance1, object) |  | ||||||
| 
 |  | ||||||
|         provider.reset() |  | ||||||
| 
 |  | ||||||
|         instance2 = provider() |  | ||||||
|         self.assertIsInstance(instance2, object) |  | ||||||
| 
 |  | ||||||
|         self.assertIsNot(instance1, instance2) |  | ||||||
| 
 |  | ||||||
|     def test_reset_with_singleton(self): |  | ||||||
|         dependent_singleton = providers.Singleton(object) |  | ||||||
|         provider = self.singleton_cls(dict, dependency=dependent_singleton) |  | ||||||
| 
 |  | ||||||
|         dependent_instance = dependent_singleton() |  | ||||||
|         instance1 = provider() |  | ||||||
|         self.assertIs(instance1['dependency'], dependent_instance) |  | ||||||
| 
 |  | ||||||
|         provider.reset() |  | ||||||
| 
 |  | ||||||
|         instance2 = provider() |  | ||||||
|         self.assertIs(instance1['dependency'], dependent_instance) |  | ||||||
| 
 |  | ||||||
|         self.assertIsNot(instance1, instance2) |  | ||||||
| 
 |  | ||||||
|     def test_reset_context_manager(self): |  | ||||||
|         singleton = self.singleton_cls(object) |  | ||||||
| 
 |  | ||||||
|         instance1 = singleton() |  | ||||||
|         with singleton.reset(): |  | ||||||
|             instance2 = singleton() |  | ||||||
|         instance3 = singleton() |  | ||||||
|         self.assertEqual(len({instance1, instance2, instance3}), 3) |  | ||||||
| 
 |  | ||||||
|     def test_reset_context_manager_as_attribute(self): |  | ||||||
|         singleton = self.singleton_cls(object) |  | ||||||
| 
 |  | ||||||
|         with singleton.reset() as alias: |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         self.assertIs(singleton, alias) |  | ||||||
| 
 |  | ||||||
|     def test_full_reset(self): |  | ||||||
|         dependent_singleton = providers.Singleton(object) |  | ||||||
|         provider = self.singleton_cls(dict, dependency=dependent_singleton) |  | ||||||
| 
 |  | ||||||
|         dependent_instance1 = dependent_singleton() |  | ||||||
|         instance1 = provider() |  | ||||||
|         self.assertIs(instance1['dependency'], dependent_instance1) |  | ||||||
| 
 |  | ||||||
|         provider.full_reset() |  | ||||||
| 
 |  | ||||||
|         dependent_instance2 = dependent_singleton() |  | ||||||
|         instance2 = provider() |  | ||||||
|         self.assertIsNot(instance2['dependency'], dependent_instance1) |  | ||||||
|         self.assertIsNot(dependent_instance1, dependent_instance2) |  | ||||||
|         self.assertIsNot(instance1, instance2) |  | ||||||
| 
 |  | ||||||
|     def test_full_reset_context_manager(self): |  | ||||||
|         class Item: |  | ||||||
|             def __init__(self, dependency): |  | ||||||
|                 self.dependency = dependency |  | ||||||
| 
 |  | ||||||
|         dependent_singleton = providers.Singleton(object) |  | ||||||
|         singleton = self.singleton_cls(Item, dependency=dependent_singleton) |  | ||||||
| 
 |  | ||||||
|         instance1 = singleton() |  | ||||||
|         with singleton.full_reset(): |  | ||||||
|             instance2 = singleton() |  | ||||||
|         instance3 = singleton() |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(len({instance1, instance2, instance3}), 3) |  | ||||||
|         self.assertEqual( |  | ||||||
|             len({instance1.dependency, instance2.dependency, instance3.dependency}), |  | ||||||
|             3, |  | ||||||
|         ) |  | ||||||
| 
 |  | ||||||
|     def test_full_reset_context_manager_as_attribute(self): |  | ||||||
|         singleton = self.singleton_cls(object) |  | ||||||
| 
 |  | ||||||
|         with singleton.full_reset() as alias: |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
|         self.assertIs(singleton, alias) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class SingletonTests(_BaseSingletonTestCase, unittest.TestCase): | class SingletonTests(_BaseSingletonTestCase, unittest.TestCase): | ||||||
|  |  | ||||||
							
								
								
									
										42
									
								
								tests/unit/providers/test_singletons_py3.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								tests/unit/providers/test_singletons_py3.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | ||||||
|  | import unittest | ||||||
|  | 
 | ||||||
|  | from dependency_injector import providers | ||||||
|  | 
 | ||||||
|  | from .singleton_common import Example, _BaseSingletonTestCase | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ContextLocalSingletonTests(_BaseSingletonTestCase, unittest.TestCase): | ||||||
|  | 
 | ||||||
|  |     singleton_cls = providers.ContextLocalSingleton | ||||||
|  | 
 | ||||||
|  |     def test_repr(self): | ||||||
|  |         provider = providers.ContextLocalSingleton(Example) | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(repr(provider), | ||||||
|  |                          '<dependency_injector.providers.' | ||||||
|  |                          'ContextLocalSingleton({0}) at {1}>'.format( | ||||||
|  |                              repr(Example), | ||||||
|  |                              hex(id(provider)))) | ||||||
|  | 
 | ||||||
|  |     def test_reset(self): | ||||||
|  |         provider = providers.ContextLocalSingleton(Example) | ||||||
|  | 
 | ||||||
|  |         instance1 = provider() | ||||||
|  |         self.assertIsInstance(instance1, Example) | ||||||
|  | 
 | ||||||
|  |         provider.reset() | ||||||
|  | 
 | ||||||
|  |         instance2 = provider() | ||||||
|  |         self.assertIsInstance(instance2, Example) | ||||||
|  | 
 | ||||||
|  |         self.assertIsNot(instance1, instance2) | ||||||
|  | 
 | ||||||
|  |     def test_reset_clean(self): | ||||||
|  |         provider = providers.ContextLocalSingleton(Example) | ||||||
|  |         instance1 = provider() | ||||||
|  | 
 | ||||||
|  |         provider.reset() | ||||||
|  |         provider.reset() | ||||||
|  | 
 | ||||||
|  |         instance2 = provider() | ||||||
|  |         self.assertIsNot(instance1, instance2) | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user