mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-10-31 16:07:51 +03:00 
			
		
		
		
	Update project structure
This commit is contained in:
		
							parent
							
								
									7bcb882425
								
							
						
					
					
						commit
						5695c781c9
					
				
							
								
								
									
										13
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								setup.py
									
									
									
									
									
								
							|  | @ -40,22 +40,15 @@ setup(name='dependency-injector', | ||||||
|       install_requires=requirements, |       install_requires=requirements, | ||||||
|       packages=[ |       packages=[ | ||||||
|           'dependency_injector', |           'dependency_injector', | ||||||
|  |           'dependency_injector.containers', | ||||||
|           'dependency_injector.providers', |           'dependency_injector.providers', | ||||||
|       ], |       ], | ||||||
|       package_dir={ |       package_dir={ | ||||||
|           '': 'src', |           '': 'src', | ||||||
|       }, |       }, | ||||||
|       ext_modules=[ |       ext_modules=[ | ||||||
|           Extension('dependency_injector.injections', |           Extension('dependency_injector.providers.injections', | ||||||
|                     ['src/dependency_injector/injections.c'], |                     ['src/dependency_injector/providers/injections.c'], | ||||||
|                     define_macros=defined_macros, |  | ||||||
|                     extra_compile_args=['-O2']), |  | ||||||
|           Extension('dependency_injector.utils', |  | ||||||
|                     ['src/dependency_injector/utils.c'], |  | ||||||
|                     define_macros=defined_macros, |  | ||||||
|                     extra_compile_args=['-O2']), |  | ||||||
|           Extension('dependency_injector.errors', |  | ||||||
|                     ['src/dependency_injector/errors.c'], |  | ||||||
|                     define_macros=defined_macros, |                     define_macros=defined_macros, | ||||||
|                     extra_compile_args=['-O2']), |                     extra_compile_args=['-O2']), | ||||||
|       ], |       ], | ||||||
|  |  | ||||||
|  | @ -1,363 +0,0 @@ | ||||||
| """Dependency injector IoC containers module.""" |  | ||||||
| 
 |  | ||||||
| import six |  | ||||||
| 
 |  | ||||||
| from dependency_injector import ( |  | ||||||
|     providers, |  | ||||||
|     utils, |  | ||||||
|     errors, |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DynamicContainer(object): |  | ||||||
|     """Dynamic inversion of control container. |  | ||||||
| 
 |  | ||||||
|     .. code-block:: python |  | ||||||
| 
 |  | ||||||
|         services = DynamicContainer() |  | ||||||
|         services.auth = providers.Factory(AuthService) |  | ||||||
|         services.users = providers.Factory(UsersService, |  | ||||||
|                                            auth_service=services.auth) |  | ||||||
| 
 |  | ||||||
|     .. py:attribute:: providers |  | ||||||
| 
 |  | ||||||
|         Read-only dictionary of all providers. |  | ||||||
| 
 |  | ||||||
|         :type: dict[str, :py:class:`dependency_injector.providers.Provider`] |  | ||||||
| 
 |  | ||||||
|     .. py:attribute:: overridden |  | ||||||
| 
 |  | ||||||
|         Tuple of overriding containers. |  | ||||||
| 
 |  | ||||||
|         :type: tuple[:py:class:`DynamicContainer`] |  | ||||||
| 
 |  | ||||||
|     .. py:attribute:: provider_type |  | ||||||
| 
 |  | ||||||
|         Type of providers that could be placed in container. |  | ||||||
| 
 |  | ||||||
|         :type: type |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     __IS_CONTAINER__ = True |  | ||||||
| 
 |  | ||||||
|     def __init__(self): |  | ||||||
|         """Initializer. |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         self.provider_type = providers.Provider |  | ||||||
|         self.providers = dict() |  | ||||||
|         self.overridden = tuple() |  | ||||||
|         super(DynamicContainer, self).__init__() |  | ||||||
| 
 |  | ||||||
|     def __setattr__(self, name, value): |  | ||||||
|         """Set instance attribute. |  | ||||||
| 
 |  | ||||||
|         If value of attribute is provider, it will be added into providers |  | ||||||
|         dictionary. |  | ||||||
| 
 |  | ||||||
|         :param name: Attribute's name |  | ||||||
|         :type name: str |  | ||||||
| 
 |  | ||||||
|         :param value: Attribute's value |  | ||||||
|         :type value: object |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         if utils.is_provider(value): |  | ||||||
|             _check_provider_type(self, value) |  | ||||||
|             self.providers[name] = value |  | ||||||
|         super(DynamicContainer, self).__setattr__(name, value) |  | ||||||
| 
 |  | ||||||
|     def __delattr__(self, name): |  | ||||||
|         """Delete instance attribute. |  | ||||||
| 
 |  | ||||||
|         If value of attribute is provider, it will be deleted from providers |  | ||||||
|         dictionary. |  | ||||||
| 
 |  | ||||||
|         :param name: Attribute's name |  | ||||||
|         :type name: str |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         if name in self.providers: |  | ||||||
|             del self.providers[name] |  | ||||||
|         super(DynamicContainer, self).__delattr__(name) |  | ||||||
| 
 |  | ||||||
|     def override(self, overriding): |  | ||||||
|         """Override current container by overriding container. |  | ||||||
| 
 |  | ||||||
|         :param overriding: Overriding container. |  | ||||||
|         :type overriding: :py:class:`DynamicContainer` |  | ||||||
| 
 |  | ||||||
|         :raise: :py:exc:`dependency_injector.errors.Error` if trying to |  | ||||||
|                 override container by itself |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         if overriding is self: |  | ||||||
|             raise errors.Error('Container {0} could not be overridden ' |  | ||||||
|                                'with itself'.format(self)) |  | ||||||
| 
 |  | ||||||
|         self.overridden += (overriding,) |  | ||||||
| 
 |  | ||||||
|         for name, provider in six.iteritems(overriding.providers): |  | ||||||
|             try: |  | ||||||
|                 getattr(self, name).override(provider) |  | ||||||
|             except AttributeError: |  | ||||||
|                 pass |  | ||||||
| 
 |  | ||||||
|     def reset_last_overriding(self): |  | ||||||
|         """Reset last overriding provider for each container providers. |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         if not self.overridden: |  | ||||||
|             raise errors.Error('Container {0} is not overridden'.format(self)) |  | ||||||
| 
 |  | ||||||
|         self.overridden = self.overridden[:-1] |  | ||||||
| 
 |  | ||||||
|         for provider in six.itervalues(self.providers): |  | ||||||
|             provider.reset_last_overriding() |  | ||||||
| 
 |  | ||||||
|     def reset_override(self): |  | ||||||
|         """Reset all overridings for each container providers. |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         self.overridden = tuple() |  | ||||||
| 
 |  | ||||||
|         for provider in six.itervalues(self.providers): |  | ||||||
|             provider.reset_override() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DeclarativeContainerMetaClass(type): |  | ||||||
|     """Declarative inversion of control container meta class.""" |  | ||||||
| 
 |  | ||||||
|     def __new__(mcs, class_name, bases, attributes): |  | ||||||
|         """Declarative container class factory.""" |  | ||||||
|         cls_providers = tuple((name, provider) |  | ||||||
|                               for name, provider in six.iteritems(attributes) |  | ||||||
|                               if utils.is_provider(provider)) |  | ||||||
| 
 |  | ||||||
|         inherited_providers = tuple((name, provider) |  | ||||||
|                                     for base in bases if utils.is_container( |  | ||||||
|                                         base) and base is not DynamicContainer |  | ||||||
|                                     for name, provider in six.iteritems( |  | ||||||
|                                         base.cls_providers)) |  | ||||||
| 
 |  | ||||||
|         attributes['cls_providers'] = dict(cls_providers) |  | ||||||
|         attributes['inherited_providers'] = dict(inherited_providers) |  | ||||||
|         attributes['providers'] = dict(cls_providers + inherited_providers) |  | ||||||
| 
 |  | ||||||
|         cls = type.__new__(mcs, class_name, bases, attributes) |  | ||||||
| 
 |  | ||||||
|         for provider in six.itervalues(cls.providers): |  | ||||||
|             _check_provider_type(cls, provider) |  | ||||||
| 
 |  | ||||||
|         return cls |  | ||||||
| 
 |  | ||||||
|     def __setattr__(cls, name, value): |  | ||||||
|         """Set class attribute. |  | ||||||
| 
 |  | ||||||
|         If value of attribute is provider, it will be added into providers |  | ||||||
|         dictionary. |  | ||||||
| 
 |  | ||||||
|         :param name: Attribute's name |  | ||||||
|         :type name: str |  | ||||||
| 
 |  | ||||||
|         :param value: Attribute's value |  | ||||||
|         :type value: object |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         if utils.is_provider(value): |  | ||||||
|             _check_provider_type(cls, value) |  | ||||||
|             cls.providers[name] = value |  | ||||||
|             cls.cls_providers[name] = value |  | ||||||
|         super(DeclarativeContainerMetaClass, cls).__setattr__(name, value) |  | ||||||
| 
 |  | ||||||
|     def __delattr__(cls, name): |  | ||||||
|         """Delete class attribute. |  | ||||||
| 
 |  | ||||||
|         If value of attribute is provider, it will be deleted from providers |  | ||||||
|         dictionary. |  | ||||||
| 
 |  | ||||||
|         :param name: Attribute's name |  | ||||||
|         :type name: str |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         if name in cls.providers and name in cls.cls_providers: |  | ||||||
|             del cls.providers[name] |  | ||||||
|             del cls.cls_providers[name] |  | ||||||
|         super(DeclarativeContainerMetaClass, cls).__delattr__(name) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @six.add_metaclass(DeclarativeContainerMetaClass) |  | ||||||
| class DeclarativeContainer(object): |  | ||||||
|     """Declarative inversion of control container. |  | ||||||
| 
 |  | ||||||
|     .. code-block:: python |  | ||||||
| 
 |  | ||||||
|         class Services(DeclarativeContainer): |  | ||||||
|             auth = providers.Factory(AuthService) |  | ||||||
|             users = providers.Factory(UsersService, |  | ||||||
|                                       auth_service=auth) |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     __IS_CONTAINER__ = True |  | ||||||
| 
 |  | ||||||
|     provider_type = providers.Provider |  | ||||||
|     """Type of providers that could be placed in container. |  | ||||||
| 
 |  | ||||||
|     :type: type |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     instance_type = DynamicContainer |  | ||||||
|     """Type of container that is returned on instantiating declarative |  | ||||||
|     container. |  | ||||||
| 
 |  | ||||||
|     :type: type |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     providers = dict() |  | ||||||
|     """Read-only dictionary of all providers. |  | ||||||
| 
 |  | ||||||
|     :type: dict[str, :py:class:`dependency_injector.providers.Provider`] |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     cls_providers = dict() |  | ||||||
|     """Read-only dictionary of current container providers. |  | ||||||
| 
 |  | ||||||
|     :type: dict[str, :py:class:`dependency_injector.providers.Provider`] |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     inherited_providers = dict() |  | ||||||
|     """Read-only dictionary of inherited providers. |  | ||||||
| 
 |  | ||||||
|     :type: dict[str, :py:class:`dependency_injector.providers.Provider`] |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     overridden = tuple() |  | ||||||
|     """Tuple of overriding containers. |  | ||||||
| 
 |  | ||||||
|     :type: tuple[:py:class:`DeclarativeContainer`] |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     def __new__(cls, *args, **kwargs): |  | ||||||
|         """Constructor. |  | ||||||
| 
 |  | ||||||
|         :return: Dynamic container with copy of all providers. |  | ||||||
|         :rtype: :py:class:`DynamicContainer` |  | ||||||
|         """ |  | ||||||
|         container = cls.instance_type(*args, **kwargs) |  | ||||||
|         container.provider_type = cls.provider_type |  | ||||||
| 
 |  | ||||||
|         for name, provider in six.iteritems(utils.deepcopy(cls.providers)): |  | ||||||
|             setattr(container, name, provider) |  | ||||||
| 
 |  | ||||||
|         return container |  | ||||||
| 
 |  | ||||||
|     @classmethod |  | ||||||
|     def override(cls, overriding): |  | ||||||
|         """Override current container by overriding container. |  | ||||||
| 
 |  | ||||||
|         :param overriding: Overriding container. |  | ||||||
|         :type overriding: :py:class:`DeclarativeContainer` |  | ||||||
| 
 |  | ||||||
|         :raise: :py:exc:`dependency_injector.errors.Error` if trying to |  | ||||||
|                 override container by itself or its subclasses |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         if issubclass(cls, overriding): |  | ||||||
|             raise errors.Error('Container {0} could not be overridden ' |  | ||||||
|                                'with itself or its subclasses'.format(cls)) |  | ||||||
| 
 |  | ||||||
|         cls.overridden += (overriding,) |  | ||||||
| 
 |  | ||||||
|         for name, provider in six.iteritems(overriding.cls_providers): |  | ||||||
|             try: |  | ||||||
|                 getattr(cls, name).override(provider) |  | ||||||
|             except AttributeError: |  | ||||||
|                 pass |  | ||||||
| 
 |  | ||||||
|     @classmethod |  | ||||||
|     def reset_last_overriding(cls): |  | ||||||
|         """Reset last overriding provider for each container providers. |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         if not cls.overridden: |  | ||||||
|             raise errors.Error('Container {0} is not overridden'.format(cls)) |  | ||||||
| 
 |  | ||||||
|         cls.overridden = cls.overridden[:-1] |  | ||||||
| 
 |  | ||||||
|         for provider in six.itervalues(cls.providers): |  | ||||||
|             provider.reset_last_overriding() |  | ||||||
| 
 |  | ||||||
|     @classmethod |  | ||||||
|     def reset_override(cls): |  | ||||||
|         """Reset all overridings for each container providers. |  | ||||||
| 
 |  | ||||||
|         :rtype: None |  | ||||||
|         """ |  | ||||||
|         cls.overridden = tuple() |  | ||||||
| 
 |  | ||||||
|         for provider in six.itervalues(cls.providers): |  | ||||||
|             provider.reset_override() |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def override(container): |  | ||||||
|     """:py:class:`DeclarativeContainer` overriding decorator. |  | ||||||
| 
 |  | ||||||
|     :param container: Container that should be overridden by decorated |  | ||||||
|                       container. |  | ||||||
|     :type container: :py:class:`DeclarativeContainer` |  | ||||||
| 
 |  | ||||||
|     :return: Declarative container's overriding decorator. |  | ||||||
|     :rtype: callable(:py:class:`DeclarativeContainer`) |  | ||||||
|     """ |  | ||||||
|     def _decorator(overriding_container): |  | ||||||
|         """Overriding decorator.""" |  | ||||||
|         container.override(overriding_container) |  | ||||||
|         return overriding_container |  | ||||||
|     return _decorator |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def copy(container): |  | ||||||
|     """:py:class:`DeclarativeContainer` copying decorator. |  | ||||||
| 
 |  | ||||||
|     This decorator copy all providers from provided container to decorated one. |  | ||||||
|     If one of the decorated container providers matches to source container |  | ||||||
|     providers by name, it would be replaced by reference. |  | ||||||
| 
 |  | ||||||
|     :param container: Container that should be copied by decorated container. |  | ||||||
|     :type container: :py:class:`DeclarativeContainer` |  | ||||||
| 
 |  | ||||||
|     :return: Declarative container's copying decorator. |  | ||||||
|     :rtype: callable(:py:class:`DeclarativeContainer`) |  | ||||||
|     """ |  | ||||||
|     def _decorator(copied_container): |  | ||||||
|         memo = dict() |  | ||||||
|         for name, provider in six.iteritems(copied_container.cls_providers): |  | ||||||
|             try: |  | ||||||
|                 source_provider = getattr(container, name) |  | ||||||
|             except AttributeError: |  | ||||||
|                 pass |  | ||||||
|             else: |  | ||||||
|                 memo[id(source_provider)] = provider |  | ||||||
| 
 |  | ||||||
|         providers_copy = utils.deepcopy(container.providers, memo) |  | ||||||
|         for name, provider in six.iteritems(providers_copy): |  | ||||||
|             setattr(copied_container, name, provider) |  | ||||||
| 
 |  | ||||||
|         return copied_container |  | ||||||
|     return _decorator |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def _check_provider_type(cls, provider): |  | ||||||
|     if not isinstance(provider, cls.provider_type): |  | ||||||
|         raise errors.Error('{0} can contain only {1} ' |  | ||||||
|                            'instances'.format(cls, cls.provider_type)) |  | ||||||
							
								
								
									
										26
									
								
								src/dependency_injector/containers/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/dependency_injector/containers/__init__.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | ||||||
|  | """Dependency injector containers.""" | ||||||
|  | 
 | ||||||
|  | from .declarative import ( | ||||||
|  |     DeclarativeContainerMetaClass, | ||||||
|  |     DeclarativeContainer, | ||||||
|  | ) | ||||||
|  | from .dynamic import ( | ||||||
|  |     DynamicContainer, | ||||||
|  | ) | ||||||
|  | from .utils import ( | ||||||
|  |     is_container, | ||||||
|  |     override, | ||||||
|  |     copy, | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | __all__ = ( | ||||||
|  |     'DeclarativeContainerMetaClass', | ||||||
|  |     'DeclarativeContainer', | ||||||
|  | 
 | ||||||
|  |     'DynamicContainer', | ||||||
|  | 
 | ||||||
|  |     'is_container', | ||||||
|  |     'override', | ||||||
|  |     'copy', | ||||||
|  | ) | ||||||
							
								
								
									
										191
									
								
								src/dependency_injector/containers/declarative.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								src/dependency_injector/containers/declarative.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,191 @@ | ||||||
|  | """Dependency injector declarative container.""" | ||||||
|  | 
 | ||||||
|  | import six | ||||||
|  | 
 | ||||||
|  | from dependency_injector.providers import Provider | ||||||
|  | from dependency_injector.errors import Error | ||||||
|  | 
 | ||||||
|  | from .dynamic import DynamicContainer | ||||||
|  | from .utils import ( | ||||||
|  |     is_container, | ||||||
|  |     deepcopy, | ||||||
|  |     _check_provider_type, | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DeclarativeContainerMetaClass(type): | ||||||
|  |     """Declarative inversion of control container meta class.""" | ||||||
|  | 
 | ||||||
|  |     def __new__(mcs, class_name, bases, attributes): | ||||||
|  |         """Declarative container class factory.""" | ||||||
|  |         cls_providers = tuple((name, provider) | ||||||
|  |                               for name, provider in six.iteritems(attributes) | ||||||
|  |                               if isinstance(provider, Provider)) | ||||||
|  | 
 | ||||||
|  |         inherited_providers = tuple((name, provider) | ||||||
|  |                                     for base in bases if is_container( | ||||||
|  |                                         base) and base is not DynamicContainer | ||||||
|  |                                     for name, provider in six.iteritems( | ||||||
|  |                                         base.cls_providers)) | ||||||
|  | 
 | ||||||
|  |         attributes['cls_providers'] = dict(cls_providers) | ||||||
|  |         attributes['inherited_providers'] = dict(inherited_providers) | ||||||
|  |         attributes['providers'] = dict(cls_providers + inherited_providers) | ||||||
|  | 
 | ||||||
|  |         cls = type.__new__(mcs, class_name, bases, attributes) | ||||||
|  | 
 | ||||||
|  |         for provider in six.itervalues(cls.providers): | ||||||
|  |             _check_provider_type(cls, provider) | ||||||
|  | 
 | ||||||
|  |         return cls | ||||||
|  | 
 | ||||||
|  |     def __setattr__(cls, name, value): | ||||||
|  |         """Set class attribute. | ||||||
|  | 
 | ||||||
|  |         If value of attribute is provider, it will be added into providers | ||||||
|  |         dictionary. | ||||||
|  | 
 | ||||||
|  |         :param name: Attribute's name | ||||||
|  |         :type name: str | ||||||
|  | 
 | ||||||
|  |         :param value: Attribute's value | ||||||
|  |         :type value: object | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         if isinstance(value, Provider): | ||||||
|  |             _check_provider_type(cls, value) | ||||||
|  |             cls.providers[name] = value | ||||||
|  |             cls.cls_providers[name] = value | ||||||
|  |         super(DeclarativeContainerMetaClass, cls).__setattr__(name, value) | ||||||
|  | 
 | ||||||
|  |     def __delattr__(cls, name): | ||||||
|  |         """Delete class attribute. | ||||||
|  | 
 | ||||||
|  |         If value of attribute is provider, it will be deleted from providers | ||||||
|  |         dictionary. | ||||||
|  | 
 | ||||||
|  |         :param name: Attribute's name | ||||||
|  |         :type name: str | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         if name in cls.providers and name in cls.cls_providers: | ||||||
|  |             del cls.providers[name] | ||||||
|  |             del cls.cls_providers[name] | ||||||
|  |         super(DeclarativeContainerMetaClass, cls).__delattr__(name) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @six.add_metaclass(DeclarativeContainerMetaClass) | ||||||
|  | class DeclarativeContainer(object): | ||||||
|  |     """Declarative inversion of control container. | ||||||
|  | 
 | ||||||
|  |     .. code-block:: python | ||||||
|  | 
 | ||||||
|  |         class Services(DeclarativeContainer): | ||||||
|  |             auth = providers.Factory(AuthService) | ||||||
|  |             users = providers.Factory(UsersService, | ||||||
|  |                                       auth_service=auth) | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     __IS_CONTAINER__ = True | ||||||
|  | 
 | ||||||
|  |     provider_type = Provider | ||||||
|  |     """Type of providers that could be placed in container. | ||||||
|  | 
 | ||||||
|  |     :type: type | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     instance_type = DynamicContainer | ||||||
|  |     """Type of container that is returned on instantiating declarative | ||||||
|  |     container. | ||||||
|  | 
 | ||||||
|  |     :type: type | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     providers = dict() | ||||||
|  |     """Read-only dictionary of all providers. | ||||||
|  | 
 | ||||||
|  |     :type: dict[str, :py:class:`dependency_injector.providers.Provider`] | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     cls_providers = dict() | ||||||
|  |     """Read-only dictionary of current container providers. | ||||||
|  | 
 | ||||||
|  |     :type: dict[str, :py:class:`dependency_injector.providers.Provider`] | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     inherited_providers = dict() | ||||||
|  |     """Read-only dictionary of inherited providers. | ||||||
|  | 
 | ||||||
|  |     :type: dict[str, :py:class:`dependency_injector.providers.Provider`] | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     overridden = tuple() | ||||||
|  |     """Tuple of overriding containers. | ||||||
|  | 
 | ||||||
|  |     :type: tuple[:py:class:`DeclarativeContainer`] | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def __new__(cls, *args, **kwargs): | ||||||
|  |         """Constructor. | ||||||
|  | 
 | ||||||
|  |         :return: Dynamic container with copy of all providers. | ||||||
|  |         :rtype: :py:class:`DynamicContainer` | ||||||
|  |         """ | ||||||
|  |         container = cls.instance_type(*args, **kwargs) | ||||||
|  |         container.provider_type = cls.provider_type | ||||||
|  | 
 | ||||||
|  |         for name, provider in six.iteritems(deepcopy(cls.providers)): | ||||||
|  |             setattr(container, name, provider) | ||||||
|  | 
 | ||||||
|  |         return container | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def override(cls, overriding): | ||||||
|  |         """Override current container by overriding container. | ||||||
|  | 
 | ||||||
|  |         :param overriding: Overriding container. | ||||||
|  |         :type overriding: :py:class:`DeclarativeContainer` | ||||||
|  | 
 | ||||||
|  |         :raise: :py:exc:`dependency_injector.errors.Error` if trying to | ||||||
|  |                 override container by itself or its subclasses | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         if issubclass(cls, overriding): | ||||||
|  |             raise Error('Container {0} could not be overridden ' | ||||||
|  |                         'with itself or its subclasses'.format(cls)) | ||||||
|  | 
 | ||||||
|  |         cls.overridden += (overriding,) | ||||||
|  | 
 | ||||||
|  |         for name, provider in six.iteritems(overriding.cls_providers): | ||||||
|  |             try: | ||||||
|  |                 getattr(cls, name).override(provider) | ||||||
|  |             except AttributeError: | ||||||
|  |                 pass | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def reset_last_overriding(cls): | ||||||
|  |         """Reset last overriding provider for each container providers. | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         if not cls.overridden: | ||||||
|  |             raise Error('Container {0} is not overridden'.format(cls)) | ||||||
|  | 
 | ||||||
|  |         cls.overridden = cls.overridden[:-1] | ||||||
|  | 
 | ||||||
|  |         for provider in six.itervalues(cls.providers): | ||||||
|  |             provider.reset_last_overriding() | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def reset_override(cls): | ||||||
|  |         """Reset all overridings for each container providers. | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         cls.overridden = tuple() | ||||||
|  | 
 | ||||||
|  |         for provider in six.itervalues(cls.providers): | ||||||
|  |             provider.reset_override() | ||||||
							
								
								
									
										130
									
								
								src/dependency_injector/containers/dynamic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/dependency_injector/containers/dynamic.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,130 @@ | ||||||
|  | """Dependency injector dynamic container.""" | ||||||
|  | 
 | ||||||
|  | import six | ||||||
|  | 
 | ||||||
|  | from dependency_injector.providers import Provider | ||||||
|  | from dependency_injector.errors import Error | ||||||
|  | 
 | ||||||
|  | from .utils import _check_provider_type | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DynamicContainer(object): | ||||||
|  |     """Dynamic inversion of control container. | ||||||
|  | 
 | ||||||
|  |     .. code-block:: python | ||||||
|  | 
 | ||||||
|  |         services = DynamicContainer() | ||||||
|  |         services.auth = providers.Factory(AuthService) | ||||||
|  |         services.users = providers.Factory(UsersService, | ||||||
|  |                                            auth_service=services.auth) | ||||||
|  | 
 | ||||||
|  |     .. py:attribute:: providers | ||||||
|  | 
 | ||||||
|  |         Read-only dictionary of all providers. | ||||||
|  | 
 | ||||||
|  |         :type: dict[str, :py:class:`dependency_injector.providers.Provider`] | ||||||
|  | 
 | ||||||
|  |     .. py:attribute:: overridden | ||||||
|  | 
 | ||||||
|  |         Tuple of overriding containers. | ||||||
|  | 
 | ||||||
|  |         :type: tuple[:py:class:`DynamicContainer`] | ||||||
|  | 
 | ||||||
|  |     .. py:attribute:: provider_type | ||||||
|  | 
 | ||||||
|  |         Type of providers that could be placed in container. | ||||||
|  | 
 | ||||||
|  |         :type: type | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     __IS_CONTAINER__ = True | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         """Initializer. | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         self.provider_type = Provider | ||||||
|  |         self.providers = dict() | ||||||
|  |         self.overridden = tuple() | ||||||
|  |         super(DynamicContainer, self).__init__() | ||||||
|  | 
 | ||||||
|  |     def __setattr__(self, name, value): | ||||||
|  |         """Set instance attribute. | ||||||
|  | 
 | ||||||
|  |         If value of attribute is provider, it will be added into providers | ||||||
|  |         dictionary. | ||||||
|  | 
 | ||||||
|  |         :param name: Attribute's name | ||||||
|  |         :type name: str | ||||||
|  | 
 | ||||||
|  |         :param value: Attribute's value | ||||||
|  |         :type value: object | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         if isinstance(value, Provider): | ||||||
|  |             _check_provider_type(self, value) | ||||||
|  |             self.providers[name] = value | ||||||
|  |         super(DynamicContainer, self).__setattr__(name, value) | ||||||
|  | 
 | ||||||
|  |     def __delattr__(self, name): | ||||||
|  |         """Delete instance attribute. | ||||||
|  | 
 | ||||||
|  |         If value of attribute is provider, it will be deleted from providers | ||||||
|  |         dictionary. | ||||||
|  | 
 | ||||||
|  |         :param name: Attribute's name | ||||||
|  |         :type name: str | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         if name in self.providers: | ||||||
|  |             del self.providers[name] | ||||||
|  |         super(DynamicContainer, self).__delattr__(name) | ||||||
|  | 
 | ||||||
|  |     def override(self, overriding): | ||||||
|  |         """Override current container by overriding container. | ||||||
|  | 
 | ||||||
|  |         :param overriding: Overriding container. | ||||||
|  |         :type overriding: :py:class:`DynamicContainer` | ||||||
|  | 
 | ||||||
|  |         :raise: :py:exc:`dependency_injector.errors.Error` if trying to | ||||||
|  |                 override container by itself | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         if overriding is self: | ||||||
|  |             raise Error('Container {0} could not be overridden ' | ||||||
|  |                         'with itself'.format(self)) | ||||||
|  | 
 | ||||||
|  |         self.overridden += (overriding,) | ||||||
|  | 
 | ||||||
|  |         for name, provider in six.iteritems(overriding.providers): | ||||||
|  |             try: | ||||||
|  |                 getattr(self, name).override(provider) | ||||||
|  |             except AttributeError: | ||||||
|  |                 pass | ||||||
|  | 
 | ||||||
|  |     def reset_last_overriding(self): | ||||||
|  |         """Reset last overriding provider for each container providers. | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         if not self.overridden: | ||||||
|  |             raise Error('Container {0} is not overridden'.format(self)) | ||||||
|  | 
 | ||||||
|  |         self.overridden = self.overridden[:-1] | ||||||
|  | 
 | ||||||
|  |         for provider in six.itervalues(self.providers): | ||||||
|  |             provider.reset_last_overriding() | ||||||
|  | 
 | ||||||
|  |     def reset_override(self): | ||||||
|  |         """Reset all overridings for each container providers. | ||||||
|  | 
 | ||||||
|  |         :rtype: None | ||||||
|  |         """ | ||||||
|  |         self.overridden = tuple() | ||||||
|  | 
 | ||||||
|  |         for provider in six.itervalues(self.providers): | ||||||
|  |             provider.reset_override() | ||||||
							
								
								
									
										85
									
								
								src/dependency_injector/containers/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/dependency_injector/containers/utils.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,85 @@ | ||||||
|  | """Dependency injector container utils.""" | ||||||
|  | 
 | ||||||
|  | import copy as _copy | ||||||
|  | import types | ||||||
|  | 
 | ||||||
|  | import six | ||||||
|  | 
 | ||||||
|  | from dependency_injector.errors import Error | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if six.PY2:  # pragma: no cover | ||||||
|  |     _copy._deepcopy_dispatch[types.MethodType] = \ | ||||||
|  |         lambda obj, memo: type(obj)(obj.im_func, | ||||||
|  |                                     _copy.deepcopy(obj.im_self, memo), | ||||||
|  |                                     obj.im_class) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def is_container(instance): | ||||||
|  |     """Check if instance is container instance. | ||||||
|  | 
 | ||||||
|  |     :param instance: Instance to be checked. | ||||||
|  |     :type instance: object | ||||||
|  | 
 | ||||||
|  |     :rtype: bool | ||||||
|  |     """ | ||||||
|  |     return getattr(instance, '__IS_CONTAINER__', False) is True | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def override(container): | ||||||
|  |     """:py:class:`DeclarativeContainer` overriding decorator. | ||||||
|  | 
 | ||||||
|  |     :param container: Container that should be overridden by decorated | ||||||
|  |                       container. | ||||||
|  |     :type container: :py:class:`DeclarativeContainer` | ||||||
|  | 
 | ||||||
|  |     :return: Declarative container's overriding decorator. | ||||||
|  |     :rtype: callable(:py:class:`DeclarativeContainer`) | ||||||
|  |     """ | ||||||
|  |     def _decorator(overriding_container): | ||||||
|  |         """Overriding decorator.""" | ||||||
|  |         container.override(overriding_container) | ||||||
|  |         return overriding_container | ||||||
|  |     return _decorator | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def copy(container): | ||||||
|  |     """:py:class:`DeclarativeContainer` copying decorator. | ||||||
|  | 
 | ||||||
|  |     This decorator copy all providers from provided container to decorated one. | ||||||
|  |     If one of the decorated container providers matches to source container | ||||||
|  |     providers by name, it would be replaced by reference. | ||||||
|  | 
 | ||||||
|  |     :param container: Container that should be copied by decorated container. | ||||||
|  |     :type container: :py:class:`DeclarativeContainer` | ||||||
|  | 
 | ||||||
|  |     :return: Declarative container's copying decorator. | ||||||
|  |     :rtype: callable(:py:class:`DeclarativeContainer`) | ||||||
|  |     """ | ||||||
|  |     def _decorator(copied_container): | ||||||
|  |         memo = dict() | ||||||
|  |         for name, provider in six.iteritems(copied_container.cls_providers): | ||||||
|  |             try: | ||||||
|  |                 source_provider = getattr(container, name) | ||||||
|  |             except AttributeError: | ||||||
|  |                 pass | ||||||
|  |             else: | ||||||
|  |                 memo[id(source_provider)] = provider | ||||||
|  | 
 | ||||||
|  |         providers_copy = deepcopy(container.providers, memo) | ||||||
|  |         for name, provider in six.iteritems(providers_copy): | ||||||
|  |             setattr(copied_container, name, provider) | ||||||
|  | 
 | ||||||
|  |         return copied_container | ||||||
|  |     return _decorator | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def deepcopy(instance, memo=None): | ||||||
|  |     """Make full copy of instance.""" | ||||||
|  |     return _copy.deepcopy(instance, memo) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _check_provider_type(cls, provider): | ||||||
|  |     if not isinstance(provider, cls.provider_type): | ||||||
|  |         raise Error('{0} can contain only {1} ' | ||||||
|  |                     'instances'.format(cls, cls.provider_type)) | ||||||
|  | @ -1,8 +0,0 @@ | ||||||
| """Dependency injector errors. |  | ||||||
| 
 |  | ||||||
| Powered by Cython. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| cdef class Error(Exception): |  | ||||||
|     pass |  | ||||||
|  | @ -1,10 +1,7 @@ | ||||||
| """Dependency injector errors. | """Dependency injector errors.""" | ||||||
| 
 |  | ||||||
| Powered by Cython. |  | ||||||
| """ |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| cdef class Error(Exception): | class Error(Exception): | ||||||
|     """Base error. |     """Base error. | ||||||
| 
 | 
 | ||||||
|     All dependency injector errors extend this error class. |     All dependency injector errors extend this error class. | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| """Dependency injector providers package.""" | """Dependency injector providers.""" | ||||||
| 
 | 
 | ||||||
| from dependency_injector.providers.base import ( | from .base import ( | ||||||
|     Provider, |     Provider, | ||||||
|     Delegate, |     Delegate, | ||||||
|     Object, |     Object, | ||||||
|  | @ -8,17 +8,22 @@ from dependency_injector.providers.base import ( | ||||||
|     OverridingContext, |     OverridingContext, | ||||||
|     override, |     override, | ||||||
| ) | ) | ||||||
| from dependency_injector.providers.callable import ( | from .callable import ( | ||||||
|     Callable, |     Callable, | ||||||
|     DelegatedCallable, |     DelegatedCallable, | ||||||
| ) | ) | ||||||
| from dependency_injector.providers.creational import ( | from .creational import ( | ||||||
|     Factory, |     Factory, | ||||||
|     DelegatedFactory, |     DelegatedFactory, | ||||||
|     Singleton, |     Singleton, | ||||||
|     DelegatedSingleton, |     DelegatedSingleton, | ||||||
|     ThreadLocalSingleton, |     ThreadLocalSingleton, | ||||||
|     DelegatedThreadLocalSingleton |     DelegatedThreadLocalSingleton, | ||||||
|  | ) | ||||||
|  | from .injections import ( | ||||||
|  |     Injection, | ||||||
|  |     PositionalInjection, | ||||||
|  |     NamedInjection, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -42,4 +47,8 @@ __all__ = ( | ||||||
| 
 | 
 | ||||||
|     'ThreadLocalSingleton', |     'ThreadLocalSingleton', | ||||||
|     'DelegatedThreadLocalSingleton', |     'DelegatedThreadLocalSingleton', | ||||||
|  | 
 | ||||||
|  |     'Injection', | ||||||
|  |     'PositionalInjection', | ||||||
|  |     'NamedInjection', | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ Powered by Cython. | ||||||
| 
 | 
 | ||||||
| cimport cython | cimport cython | ||||||
| 
 | 
 | ||||||
| from .utils cimport ( | from dependency_injector.utils import ( | ||||||
|     is_provider, |     is_provider, | ||||||
|     is_delegated, |     is_delegated, | ||||||
| ) | ) | ||||||
							
								
								
									
										0
									
								
								src/dependency_injector/providers/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/dependency_injector/providers/utils.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -1,16 +0,0 @@ | ||||||
| """Dependency injector utils. |  | ||||||
| 
 |  | ||||||
| Powered by Cython. |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| cpdef bint is_provider(object instance) |  | ||||||
| 
 |  | ||||||
| cpdef object ensure_is_provider(object instance) |  | ||||||
| 
 |  | ||||||
| cpdef bint is_delegated(object instance) |  | ||||||
| 
 |  | ||||||
| cpdef bint is_container(object instance) |  | ||||||
| 
 |  | ||||||
| cpdef str represent_provider(object provider, object provides) |  | ||||||
| 
 |  | ||||||
| cpdef object deepcopy(object instance, dict memo=*) |  | ||||||
|  | @ -1,36 +1,19 @@ | ||||||
| """Dependency injector utils. | """Dependency injector utils.""" | ||||||
| 
 | 
 | ||||||
| Powered by Cython. | import six | ||||||
| """ |  | ||||||
| 
 | 
 | ||||||
| cimport cpython.version |  | ||||||
| 
 |  | ||||||
| from dependency_injector cimport errors |  | ||||||
| 
 |  | ||||||
| import copy as _copy |  | ||||||
| import types |  | ||||||
| import threading | import threading | ||||||
| 
 | 
 | ||||||
|  | from .errors import Error | ||||||
| 
 | 
 | ||||||
| GLOBAL_LOCK = threading.RLock() | GLOBAL_LOCK = threading.RLock() | ||||||
| """Dependency injector global reentrant lock. | """Global reentrant lock. | ||||||
| 
 | 
 | ||||||
| :type: :py:class:`threading.RLock` | :type: :py:class:`threading.RLock` | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| if cpython.version.PY_MAJOR_VERSION < 3:  # pragma: no cover |  | ||||||
|     CLASS_TYPES = (type, types.ClassType) |  | ||||||
| 
 | 
 | ||||||
|     _copy._deepcopy_dispatch[types.MethodType] = \ | def is_provider(instance): | ||||||
|         lambda obj, memo: type(obj)(obj.im_func, |  | ||||||
|                                     _copy.deepcopy(obj.im_self, memo), |  | ||||||
|                                     obj.im_class) |  | ||||||
| else:  # pragma: no cover |  | ||||||
|     CLASS_TYPES = (type,) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| cpdef bint is_provider(object instance): |  | ||||||
|     """Check if instance is provider instance. |     """Check if instance is provider instance. | ||||||
| 
 | 
 | ||||||
|     :param instance: Instance to be checked. |     :param instance: Instance to be checked. | ||||||
|  | @ -38,11 +21,11 @@ cpdef bint is_provider(object instance): | ||||||
| 
 | 
 | ||||||
|     :rtype: bool |     :rtype: bool | ||||||
|     """ |     """ | ||||||
|     return (not isinstance(instance, CLASS_TYPES) and |     return (not isinstance(instance, six.class_types) and | ||||||
|             getattr(instance, '__IS_PROVIDER__', False) is True) |             getattr(instance, '__IS_PROVIDER__', False) is True) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| cpdef object ensure_is_provider(object instance): | def ensure_is_provider(instance): | ||||||
|     """Check if instance is provider instance and return it. |     """Check if instance is provider instance and return it. | ||||||
| 
 | 
 | ||||||
|     :param instance: Instance to be checked. |     :param instance: Instance to be checked. | ||||||
|  | @ -54,12 +37,12 @@ cpdef object ensure_is_provider(object instance): | ||||||
|     :rtype: :py:class:`dependency_injector.providers.Provider` |     :rtype: :py:class:`dependency_injector.providers.Provider` | ||||||
|     """ |     """ | ||||||
|     if not is_provider(instance): |     if not is_provider(instance): | ||||||
|         raise errors.Error('Expected provider instance, ' |         raise Error('Expected provider instance, ' | ||||||
|                     'got {0}'.format(str(instance))) |                     'got {0}'.format(str(instance))) | ||||||
|     return instance |     return instance | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| cpdef bint is_delegated(object instance): | def is_delegated(instance): | ||||||
|     """Check if instance is delegated provider. |     """Check if instance is delegated provider. | ||||||
| 
 | 
 | ||||||
|     :param instance: Instance to be checked. |     :param instance: Instance to be checked. | ||||||
|  | @ -67,22 +50,11 @@ cpdef bint is_delegated(object instance): | ||||||
| 
 | 
 | ||||||
|     :rtype: bool |     :rtype: bool | ||||||
|     """ |     """ | ||||||
|     return (not isinstance(instance, CLASS_TYPES) and |     return (not isinstance(instance, six.class_types) and | ||||||
|             getattr(instance, '__IS_DELEGATED__', False) is True) |             getattr(instance, '__IS_DELEGATED__', False) is True) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| cpdef bint is_container(object instance): | def represent_provider(provider, provides): | ||||||
|     """Check if instance is container instance. |  | ||||||
| 
 |  | ||||||
|     :param instance: Instance to be checked. |  | ||||||
|     :type instance: object |  | ||||||
| 
 |  | ||||||
|     :rtype: bool |  | ||||||
|     """ |  | ||||||
|     return getattr(instance, '__IS_CONTAINER__', False) is True |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| cpdef str represent_provider(object provider, object provides): |  | ||||||
|     """Return string representation of provider. |     """Return string representation of provider. | ||||||
| 
 | 
 | ||||||
|     :param provider: Provider object |     :param provider: Provider object | ||||||
|  | @ -99,9 +71,3 @@ cpdef str represent_provider(object provider, object provides): | ||||||
|                            provider.__class__.__name__)), |                            provider.__class__.__name__)), | ||||||
|         provides=repr(provides) if provides is not None else '', |         provides=repr(provides) if provides is not None else '', | ||||||
|         address=hex(id(provider))) |         address=hex(id(provider))) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| cpdef object deepcopy(object instance, dict memo=None): |  | ||||||
|     """Make full copy of instance.""" |  | ||||||
|     return _copy.deepcopy(instance, memo) |  | ||||||
| 
 |  | ||||||
							
								
								
									
										1
									
								
								tests/unit/containers/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								tests/unit/containers/__init__.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | """Dependency injector container unit tests.""" | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| """Dependency injector container unit tests.""" | """Dependency injector declarative container unit tests.""" | ||||||
| 
 | 
 | ||||||
| import unittest2 as unittest | import unittest2 as unittest | ||||||
| 
 | 
 | ||||||
|  | @ -10,27 +10,18 @@ from dependency_injector import ( | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ContainerA(containers.DeclarativeContainer): | class ContainerA(containers.DeclarativeContainer): | ||||||
|     """Declarative IoC container A.""" |  | ||||||
| 
 |  | ||||||
|     p11 = providers.Provider() |     p11 = providers.Provider() | ||||||
|     p12 = providers.Provider() |     p12 = providers.Provider() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ContainerB(ContainerA): | class ContainerB(ContainerA): | ||||||
|     """Declarative IoC container B. |  | ||||||
| 
 |  | ||||||
|     Extends container A. |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     p21 = providers.Provider() |     p21 = providers.Provider() | ||||||
|     p22 = providers.Provider() |     p22 = providers.Provider() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class DeclarativeContainerTests(unittest.TestCase): | class DeclarativeContainerTests(unittest.TestCase): | ||||||
|     """Declarative container tests.""" |  | ||||||
| 
 | 
 | ||||||
|     def test_providers_attribute(self): |     def test_providers_attribute(self): | ||||||
|         """Test providers attribute.""" |  | ||||||
|         self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11, |         self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11, | ||||||
|                                                     p12=ContainerA.p12)) |                                                     p12=ContainerA.p12)) | ||||||
|         self.assertEqual(ContainerB.providers, dict(p11=ContainerA.p11, |         self.assertEqual(ContainerB.providers, dict(p11=ContainerA.p11, | ||||||
|  | @ -39,21 +30,18 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|                                                     p22=ContainerB.p22)) |                                                     p22=ContainerB.p22)) | ||||||
| 
 | 
 | ||||||
|     def test_cls_providers_attribute(self): |     def test_cls_providers_attribute(self): | ||||||
|         """Test cls_providers attribute.""" |  | ||||||
|         self.assertEqual(ContainerA.cls_providers, dict(p11=ContainerA.p11, |         self.assertEqual(ContainerA.cls_providers, dict(p11=ContainerA.p11, | ||||||
|                                                         p12=ContainerA.p12)) |                                                         p12=ContainerA.p12)) | ||||||
|         self.assertEqual(ContainerB.cls_providers, dict(p21=ContainerB.p21, |         self.assertEqual(ContainerB.cls_providers, dict(p21=ContainerB.p21, | ||||||
|                                                         p22=ContainerB.p22)) |                                                         p22=ContainerB.p22)) | ||||||
| 
 | 
 | ||||||
|     def test_inherited_providers_attribute(self): |     def test_inherited_providers_attribute(self): | ||||||
|         """Test inherited_providers attribute.""" |  | ||||||
|         self.assertEqual(ContainerA.inherited_providers, dict()) |         self.assertEqual(ContainerA.inherited_providers, dict()) | ||||||
|         self.assertEqual(ContainerB.inherited_providers, |         self.assertEqual(ContainerB.inherited_providers, | ||||||
|                          dict(p11=ContainerA.p11, |                          dict(p11=ContainerA.p11, | ||||||
|                               p12=ContainerA.p12)) |                               p12=ContainerA.p12)) | ||||||
| 
 | 
 | ||||||
|     def test_set_get_del_providers(self): |     def test_set_get_del_providers(self): | ||||||
|         """Test set/get/del provider attributes.""" |  | ||||||
|         a_p13 = providers.Provider() |         a_p13 = providers.Provider() | ||||||
|         b_p23 = providers.Provider() |         b_p23 = providers.Provider() | ||||||
| 
 | 
 | ||||||
|  | @ -92,7 +80,6 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|                                                         p22=ContainerB.p22)) |                                                         p22=ContainerB.p22)) | ||||||
| 
 | 
 | ||||||
|     def test_declare_with_valid_provider_type(self): |     def test_declare_with_valid_provider_type(self): | ||||||
|         """Test declaration of container with valid provider type.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |         class _Container(containers.DeclarativeContainer): | ||||||
|             provider_type = providers.Object |             provider_type = providers.Object | ||||||
|             px = providers.Object(object()) |             px = providers.Object(object()) | ||||||
|  | @ -100,14 +87,12 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|         self.assertIsInstance(_Container.px, providers.Object) |         self.assertIsInstance(_Container.px, providers.Object) | ||||||
| 
 | 
 | ||||||
|     def test_declare_with_invalid_provider_type(self): |     def test_declare_with_invalid_provider_type(self): | ||||||
|         """Test declaration of container with invalid provider type.""" |  | ||||||
|         with self.assertRaises(errors.Error): |         with self.assertRaises(errors.Error): | ||||||
|             class _Container(containers.DeclarativeContainer): |             class _Container(containers.DeclarativeContainer): | ||||||
|                 provider_type = providers.Object |                 provider_type = providers.Object | ||||||
|                 px = providers.Provider() |                 px = providers.Provider() | ||||||
| 
 | 
 | ||||||
|     def test_seth_valid_provider_type(self): |     def test_seth_valid_provider_type(self): | ||||||
|         """Test setting of valid provider.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |         class _Container(containers.DeclarativeContainer): | ||||||
|             provider_type = providers.Object |             provider_type = providers.Object | ||||||
| 
 | 
 | ||||||
|  | @ -116,7 +101,6 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|         self.assertIsInstance(_Container.px, providers.Object) |         self.assertIsInstance(_Container.px, providers.Object) | ||||||
| 
 | 
 | ||||||
|     def test_set_invalid_provider_type(self): |     def test_set_invalid_provider_type(self): | ||||||
|         """Test setting of invalid provider.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |         class _Container(containers.DeclarativeContainer): | ||||||
|             provider_type = providers.Object |             provider_type = providers.Object | ||||||
| 
 | 
 | ||||||
|  | @ -124,7 +108,6 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|             _Container.px = providers.Provider() |             _Container.px = providers.Provider() | ||||||
| 
 | 
 | ||||||
|     def test_override(self): |     def test_override(self): | ||||||
|         """Test override.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |         class _Container(containers.DeclarativeContainer): | ||||||
|             p11 = providers.Provider() |             p11 = providers.Provider() | ||||||
| 
 | 
 | ||||||
|  | @ -146,17 +129,14 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|                           _OverridingContainer2.p11)) |                           _OverridingContainer2.p11)) | ||||||
| 
 | 
 | ||||||
|     def test_override_with_itself(self): |     def test_override_with_itself(self): | ||||||
|         """Test override with itself.""" |  | ||||||
|         with self.assertRaises(errors.Error): |         with self.assertRaises(errors.Error): | ||||||
|             ContainerA.override(ContainerA) |             ContainerA.override(ContainerA) | ||||||
| 
 | 
 | ||||||
|     def test_override_with_parent(self): |     def test_override_with_parent(self): | ||||||
|         """Test override with parent.""" |  | ||||||
|         with self.assertRaises(errors.Error): |         with self.assertRaises(errors.Error): | ||||||
|             ContainerB.override(ContainerA) |             ContainerB.override(ContainerA) | ||||||
| 
 | 
 | ||||||
|     def test_override_decorator(self): |     def test_override_decorator(self): | ||||||
|         """Test override decorator.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |         class _Container(containers.DeclarativeContainer): | ||||||
|             p11 = providers.Provider() |             p11 = providers.Provider() | ||||||
| 
 | 
 | ||||||
|  | @ -177,7 +157,6 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|                           _OverridingContainer2.p11)) |                           _OverridingContainer2.p11)) | ||||||
| 
 | 
 | ||||||
|     def test_reset_last_overridding(self): |     def test_reset_last_overridding(self): | ||||||
|         """Test reset of last overriding.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |         class _Container(containers.DeclarativeContainer): | ||||||
|             p11 = providers.Provider() |             p11 = providers.Provider() | ||||||
| 
 | 
 | ||||||
|  | @ -198,12 +177,10 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|                          (_OverridingContainer1.p11,)) |                          (_OverridingContainer1.p11,)) | ||||||
| 
 | 
 | ||||||
|     def test_reset_last_overridding_when_not_overridden(self): |     def test_reset_last_overridding_when_not_overridden(self): | ||||||
|         """Test reset of last overriding.""" |  | ||||||
|         with self.assertRaises(errors.Error): |         with self.assertRaises(errors.Error): | ||||||
|             ContainerA.reset_last_overriding() |             ContainerA.reset_last_overriding() | ||||||
| 
 | 
 | ||||||
|     def test_reset_override(self): |     def test_reset_override(self): | ||||||
|         """Test reset all overridings.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |         class _Container(containers.DeclarativeContainer): | ||||||
|             p11 = providers.Provider() |             p11 = providers.Provider() | ||||||
| 
 | 
 | ||||||
|  | @ -222,7 +199,6 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|         self.assertEqual(_Container.p11.overridden, tuple()) |         self.assertEqual(_Container.p11.overridden, tuple()) | ||||||
| 
 | 
 | ||||||
|     def test_copy(self): |     def test_copy(self): | ||||||
|         """Test copy decorator.""" |  | ||||||
|         @containers.copy(ContainerA) |         @containers.copy(ContainerA) | ||||||
|         class _Container1(ContainerA): |         class _Container1(ContainerA): | ||||||
|             pass |             pass | ||||||
|  | @ -241,7 +217,6 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
|         self.assertIsNot(_Container1.p12, _Container2.p12) |         self.assertIsNot(_Container1.p12, _Container2.p12) | ||||||
| 
 | 
 | ||||||
|     def test_copy_with_replacing(self): |     def test_copy_with_replacing(self): | ||||||
|         """Test copy decorator with providers replacement.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |         class _Container(containers.DeclarativeContainer): | ||||||
|             p11 = providers.Object(0) |             p11 = providers.Object(0) | ||||||
|             p12 = providers.Factory(dict, p11=p11) |             p12 = providers.Factory(dict, p11=p11) | ||||||
|  | @ -275,163 +250,3 @@ class DeclarativeContainerTests(unittest.TestCase): | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(_Container1.p13(), 11) |         self.assertEqual(_Container1.p13(), 11) | ||||||
|         self.assertEqual(_Container2.p13(), 22) |         self.assertEqual(_Container2.p13(), 22) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class DeclarativeContainerInstanceTests(unittest.TestCase): |  | ||||||
|     """Declarative container instance tests.""" |  | ||||||
| 
 |  | ||||||
|     def test_providers_attribute(self): |  | ||||||
|         """Test providers attribute.""" |  | ||||||
|         container_a1 = ContainerA() |  | ||||||
|         container_a2 = ContainerA() |  | ||||||
| 
 |  | ||||||
|         self.assertIsNot(container_a1.p11, container_a2.p11) |  | ||||||
|         self.assertIsNot(container_a1.p12, container_a2.p12) |  | ||||||
|         self.assertNotEqual(container_a1.providers, container_a2.providers) |  | ||||||
| 
 |  | ||||||
|     def test_set_get_del_providers(self): |  | ||||||
|         """Test set/get/del provider attributes.""" |  | ||||||
|         p13 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         container_a1 = ContainerA() |  | ||||||
|         container_a2 = ContainerA() |  | ||||||
| 
 |  | ||||||
|         container_a1.p13 = p13 |  | ||||||
|         container_a2.p13 = p13 |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11, |  | ||||||
|                                                     p12=ContainerA.p12)) |  | ||||||
|         self.assertEqual(ContainerA.cls_providers, dict(p11=ContainerA.p11, |  | ||||||
|                                                         p12=ContainerA.p12)) |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(container_a1.providers, dict(p11=container_a1.p11, |  | ||||||
|                                                       p12=container_a1.p12, |  | ||||||
|                                                       p13=p13)) |  | ||||||
|         self.assertEqual(container_a2.providers, dict(p11=container_a2.p11, |  | ||||||
|                                                       p12=container_a2.p12, |  | ||||||
|                                                       p13=p13)) |  | ||||||
| 
 |  | ||||||
|         del container_a1.p13 |  | ||||||
|         self.assertEqual(container_a1.providers, dict(p11=container_a1.p11, |  | ||||||
|                                                       p12=container_a1.p12)) |  | ||||||
| 
 |  | ||||||
|         del container_a2.p13 |  | ||||||
|         self.assertEqual(container_a2.providers, dict(p11=container_a2.p11, |  | ||||||
|                                                       p12=container_a2.p12)) |  | ||||||
| 
 |  | ||||||
|         del container_a1.p11 |  | ||||||
|         del container_a1.p12 |  | ||||||
|         self.assertEqual(container_a1.providers, dict()) |  | ||||||
|         self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11, |  | ||||||
|                                                     p12=ContainerA.p12)) |  | ||||||
| 
 |  | ||||||
|         del container_a2.p11 |  | ||||||
|         del container_a2.p12 |  | ||||||
|         self.assertEqual(container_a2.providers, dict()) |  | ||||||
|         self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11, |  | ||||||
|                                                     p12=ContainerA.p12)) |  | ||||||
| 
 |  | ||||||
|     def test_set_invalid_provider_type(self): |  | ||||||
|         """Test setting of invalid provider.""" |  | ||||||
|         container_a = ContainerA() |  | ||||||
|         container_a.provider_type = providers.Object |  | ||||||
| 
 |  | ||||||
|         with self.assertRaises(errors.Error): |  | ||||||
|             container_a.px = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         self.assertIs(ContainerA.provider_type, |  | ||||||
|                       containers.DeclarativeContainer.provider_type) |  | ||||||
| 
 |  | ||||||
|     def test_override(self): |  | ||||||
|         """Test override.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         class _OverridingContainer1(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         class _OverridingContainer2(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
|             p12 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         container = _Container() |  | ||||||
|         overriding_container1 = _OverridingContainer1() |  | ||||||
|         overriding_container2 = _OverridingContainer2() |  | ||||||
| 
 |  | ||||||
|         container.override(overriding_container1) |  | ||||||
|         container.override(overriding_container2) |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(container.overridden, |  | ||||||
|                          (overriding_container1, |  | ||||||
|                           overriding_container2)) |  | ||||||
|         self.assertEqual(container.p11.overridden, |  | ||||||
|                          (overriding_container1.p11, |  | ||||||
|                           overriding_container2.p11)) |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(_Container.overridden, tuple()) |  | ||||||
|         self.assertEqual(_Container.p11.overridden, tuple()) |  | ||||||
| 
 |  | ||||||
|     def test_override_with_itself(self): |  | ||||||
|         """Test override container with itself.""" |  | ||||||
|         container = ContainerA() |  | ||||||
|         with self.assertRaises(errors.Error): |  | ||||||
|             container.override(container) |  | ||||||
| 
 |  | ||||||
|     def test_reset_last_overridding(self): |  | ||||||
|         """Test reset of last overriding.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         class _OverridingContainer1(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         class _OverridingContainer2(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
|             p12 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         container = _Container() |  | ||||||
|         overriding_container1 = _OverridingContainer1() |  | ||||||
|         overriding_container2 = _OverridingContainer2() |  | ||||||
| 
 |  | ||||||
|         container.override(overriding_container1) |  | ||||||
|         container.override(overriding_container2) |  | ||||||
|         container.reset_last_overriding() |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(container.overridden, |  | ||||||
|                          (overriding_container1,)) |  | ||||||
|         self.assertEqual(container.p11.overridden, |  | ||||||
|                          (overriding_container1.p11,)) |  | ||||||
| 
 |  | ||||||
|     def test_reset_last_overridding_when_not_overridden(self): |  | ||||||
|         """Test reset of last overriding.""" |  | ||||||
|         container = ContainerA() |  | ||||||
| 
 |  | ||||||
|         with self.assertRaises(errors.Error): |  | ||||||
|             container.reset_last_overriding() |  | ||||||
| 
 |  | ||||||
|     def test_reset_override(self): |  | ||||||
|         """Test reset all overridings.""" |  | ||||||
|         class _Container(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         class _OverridingContainer1(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         class _OverridingContainer2(containers.DeclarativeContainer): |  | ||||||
|             p11 = providers.Provider() |  | ||||||
|             p12 = providers.Provider() |  | ||||||
| 
 |  | ||||||
|         container = _Container() |  | ||||||
|         overriding_container1 = _OverridingContainer1() |  | ||||||
|         overriding_container2 = _OverridingContainer2() |  | ||||||
| 
 |  | ||||||
|         container.override(overriding_container1) |  | ||||||
|         container.override(overriding_container2) |  | ||||||
|         container.reset_override() |  | ||||||
| 
 |  | ||||||
|         self.assertEqual(container.overridden, tuple()) |  | ||||||
|         self.assertEqual(container.p11.overridden, tuple()) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     unittest.main() |  | ||||||
							
								
								
									
										165
									
								
								tests/unit/containers/test_dynamic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								tests/unit/containers/test_dynamic.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,165 @@ | ||||||
|  | """Dependency injector dynamic container unit tests.""" | ||||||
|  | 
 | ||||||
|  | import unittest2 as unittest | ||||||
|  | 
 | ||||||
|  | from dependency_injector import ( | ||||||
|  |     containers, | ||||||
|  |     providers, | ||||||
|  |     errors, | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ContainerA(containers.DeclarativeContainer): | ||||||
|  |     p11 = providers.Provider() | ||||||
|  |     p12 = providers.Provider() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DeclarativeContainerInstanceTests(unittest.TestCase): | ||||||
|  | 
 | ||||||
|  |     def test_providers_attribute(self): | ||||||
|  |         container_a1 = ContainerA() | ||||||
|  |         container_a2 = ContainerA() | ||||||
|  | 
 | ||||||
|  |         self.assertIsNot(container_a1.p11, container_a2.p11) | ||||||
|  |         self.assertIsNot(container_a1.p12, container_a2.p12) | ||||||
|  |         self.assertNotEqual(container_a1.providers, container_a2.providers) | ||||||
|  | 
 | ||||||
|  |     def test_set_get_del_providers(self): | ||||||
|  |         p13 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         container_a1 = ContainerA() | ||||||
|  |         container_a2 = ContainerA() | ||||||
|  | 
 | ||||||
|  |         container_a1.p13 = p13 | ||||||
|  |         container_a2.p13 = p13 | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11, | ||||||
|  |                                                     p12=ContainerA.p12)) | ||||||
|  |         self.assertEqual(ContainerA.cls_providers, dict(p11=ContainerA.p11, | ||||||
|  |                                                         p12=ContainerA.p12)) | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(container_a1.providers, dict(p11=container_a1.p11, | ||||||
|  |                                                       p12=container_a1.p12, | ||||||
|  |                                                       p13=p13)) | ||||||
|  |         self.assertEqual(container_a2.providers, dict(p11=container_a2.p11, | ||||||
|  |                                                       p12=container_a2.p12, | ||||||
|  |                                                       p13=p13)) | ||||||
|  | 
 | ||||||
|  |         del container_a1.p13 | ||||||
|  |         self.assertEqual(container_a1.providers, dict(p11=container_a1.p11, | ||||||
|  |                                                       p12=container_a1.p12)) | ||||||
|  | 
 | ||||||
|  |         del container_a2.p13 | ||||||
|  |         self.assertEqual(container_a2.providers, dict(p11=container_a2.p11, | ||||||
|  |                                                       p12=container_a2.p12)) | ||||||
|  | 
 | ||||||
|  |         del container_a1.p11 | ||||||
|  |         del container_a1.p12 | ||||||
|  |         self.assertEqual(container_a1.providers, dict()) | ||||||
|  |         self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11, | ||||||
|  |                                                     p12=ContainerA.p12)) | ||||||
|  | 
 | ||||||
|  |         del container_a2.p11 | ||||||
|  |         del container_a2.p12 | ||||||
|  |         self.assertEqual(container_a2.providers, dict()) | ||||||
|  |         self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11, | ||||||
|  |                                                     p12=ContainerA.p12)) | ||||||
|  | 
 | ||||||
|  |     def test_set_invalid_provider_type(self): | ||||||
|  |         container_a = ContainerA() | ||||||
|  |         container_a.provider_type = providers.Object | ||||||
|  | 
 | ||||||
|  |         with self.assertRaises(errors.Error): | ||||||
|  |             container_a.px = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         self.assertIs(ContainerA.provider_type, | ||||||
|  |                       containers.DeclarativeContainer.provider_type) | ||||||
|  | 
 | ||||||
|  |     def test_override(self): | ||||||
|  |         class _Container(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         class _OverridingContainer1(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         class _OverridingContainer2(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  |             p12 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         container = _Container() | ||||||
|  |         overriding_container1 = _OverridingContainer1() | ||||||
|  |         overriding_container2 = _OverridingContainer2() | ||||||
|  | 
 | ||||||
|  |         container.override(overriding_container1) | ||||||
|  |         container.override(overriding_container2) | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(container.overridden, | ||||||
|  |                          (overriding_container1, | ||||||
|  |                           overriding_container2)) | ||||||
|  |         self.assertEqual(container.p11.overridden, | ||||||
|  |                          (overriding_container1.p11, | ||||||
|  |                           overriding_container2.p11)) | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(_Container.overridden, tuple()) | ||||||
|  |         self.assertEqual(_Container.p11.overridden, tuple()) | ||||||
|  | 
 | ||||||
|  |     def test_override_with_itself(self): | ||||||
|  |         container = ContainerA() | ||||||
|  |         with self.assertRaises(errors.Error): | ||||||
|  |             container.override(container) | ||||||
|  | 
 | ||||||
|  |     def test_reset_last_overridding(self): | ||||||
|  |         class _Container(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         class _OverridingContainer1(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         class _OverridingContainer2(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  |             p12 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         container = _Container() | ||||||
|  |         overriding_container1 = _OverridingContainer1() | ||||||
|  |         overriding_container2 = _OverridingContainer2() | ||||||
|  | 
 | ||||||
|  |         container.override(overriding_container1) | ||||||
|  |         container.override(overriding_container2) | ||||||
|  |         container.reset_last_overriding() | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(container.overridden, | ||||||
|  |                          (overriding_container1,)) | ||||||
|  |         self.assertEqual(container.p11.overridden, | ||||||
|  |                          (overriding_container1.p11,)) | ||||||
|  | 
 | ||||||
|  |     def test_reset_last_overridding_when_not_overridden(self): | ||||||
|  |         container = ContainerA() | ||||||
|  | 
 | ||||||
|  |         with self.assertRaises(errors.Error): | ||||||
|  |             container.reset_last_overriding() | ||||||
|  | 
 | ||||||
|  |     def test_reset_override(self): | ||||||
|  |         class _Container(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         class _OverridingContainer1(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         class _OverridingContainer2(containers.DeclarativeContainer): | ||||||
|  |             p11 = providers.Provider() | ||||||
|  |             p12 = providers.Provider() | ||||||
|  | 
 | ||||||
|  |         container = _Container() | ||||||
|  |         overriding_container1 = _OverridingContainer1() | ||||||
|  |         overriding_container2 = _OverridingContainer2() | ||||||
|  | 
 | ||||||
|  |         container.override(overriding_container1) | ||||||
|  |         container.override(overriding_container2) | ||||||
|  |         container.reset_override() | ||||||
|  | 
 | ||||||
|  |         self.assertEqual(container.overridden, tuple()) | ||||||
|  |         self.assertEqual(container.p11.overridden, tuple()) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     unittest.main() | ||||||
|  | @ -2,22 +2,21 @@ | ||||||
| 
 | 
 | ||||||
| import unittest2 as unittest | import unittest2 as unittest | ||||||
| 
 | 
 | ||||||
| from dependency_injector import injections |  | ||||||
| from dependency_injector import providers | from dependency_injector import providers | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class PositionalInjectionTests(unittest.TestCase): | class PositionalInjectionTests(unittest.TestCase): | ||||||
| 
 | 
 | ||||||
|     def test_isinstance(self): |     def test_isinstance(self): | ||||||
|         injection = injections.PositionalInjection(1) |         injection = providers.PositionalInjection(1) | ||||||
|         self.assertIsInstance(injection, injections.Injection) |         self.assertIsInstance(injection, providers.Injection) | ||||||
| 
 | 
 | ||||||
|     def test_get_value_with_not_provider(self): |     def test_get_value_with_not_provider(self): | ||||||
|         injection = injections.PositionalInjection(123) |         injection = providers.PositionalInjection(123) | ||||||
|         self.assertEquals(injection.get_value(), 123) |         self.assertEquals(injection.get_value(), 123) | ||||||
| 
 | 
 | ||||||
|     def test_get_value_with_factory(self): |     def test_get_value_with_factory(self): | ||||||
|         injection = injections.PositionalInjection(providers.Factory(object)) |         injection = providers.PositionalInjection(providers.Factory(object)) | ||||||
| 
 | 
 | ||||||
|         obj1 = injection.get_value() |         obj1 = injection.get_value() | ||||||
|         obj2 = injection.get_value() |         obj2 = injection.get_value() | ||||||
|  | @ -30,19 +29,19 @@ class PositionalInjectionTests(unittest.TestCase): | ||||||
| class NamedInjectionTests(unittest.TestCase): | class NamedInjectionTests(unittest.TestCase): | ||||||
| 
 | 
 | ||||||
|     def test_isinstance(self): |     def test_isinstance(self): | ||||||
|         injection = injections.NamedInjection('name', 1) |         injection = providers.NamedInjection('name', 1) | ||||||
|         self.assertIsInstance(injection, injections.Injection) |         self.assertIsInstance(injection, providers.Injection) | ||||||
| 
 | 
 | ||||||
|     def test_get_name(self): |     def test_get_name(self): | ||||||
|         injection = injections.NamedInjection('name', 123) |         injection = providers.NamedInjection('name', 123) | ||||||
|         self.assertEquals(injection.get_name(), 'name') |         self.assertEquals(injection.get_name(), 'name') | ||||||
| 
 | 
 | ||||||
|     def test_get_value_with_not_provider(self): |     def test_get_value_with_not_provider(self): | ||||||
|         injection = injections.NamedInjection('name', 123) |         injection = providers.NamedInjection('name', 123) | ||||||
|         self.assertEquals(injection.get_value(), 123) |         self.assertEquals(injection.get_value(), 123) | ||||||
| 
 | 
 | ||||||
|     def test_get_value_with_factory(self): |     def test_get_value_with_factory(self): | ||||||
|         injection = injections.NamedInjection('name', |         injection = providers.NamedInjection('name', | ||||||
|                                              providers.Factory(object)) |                                              providers.Factory(object)) | ||||||
| 
 | 
 | ||||||
|         obj1 = injection.get_value() |         obj1 = injection.get_value() | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user