mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +03:00 
			
		
		
		
	Add dependencies attribute to declarative and dynamic containers (#359)
* Add .dependencies attribute to declarative and dynamic containers * Update changelog * Add typing tests
This commit is contained in:
		
							parent
							
								
									3e207a4f21
								
							
						
					
					
						commit
						907a4f1887
					
				| 
						 | 
				
			
			@ -7,6 +7,13 @@ that were made in every particular version.
 | 
			
		|||
From version 0.7.6 *Dependency Injector* framework strictly 
 | 
			
		||||
follows `Semantic versioning`_
 | 
			
		||||
 | 
			
		||||
Development version
 | 
			
		||||
-------------------
 | 
			
		||||
- Add ``.dependencies`` attribute to the ``DeclarativeContainer`` and ``DynamicContainer``.
 | 
			
		||||
  It returns dictionary of container ``Dependency`` and ``DependenciesContainer`` providers.
 | 
			
		||||
  See issue `#357 <https://github.com/ets-labs/python-dependency-injector/issues/357>`_.
 | 
			
		||||
  Many thanks to `Shaun Cutts <https://github.com/shaunc>`_ for suggesting the feature.
 | 
			
		||||
 | 
			
		||||
4.8.3
 | 
			
		||||
-----
 | 
			
		||||
- Fix a bug in the ``Configuration`` provider to correctly handle overriding by ``None``.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -24,6 +24,7 @@ C_Overriding = TypeVar('C_Overriding', bound='DeclarativeContainer')
 | 
			
		|||
class Container:
 | 
			
		||||
    provider_type: Type[Provider] = Provider
 | 
			
		||||
    providers: Dict[str, Provider]
 | 
			
		||||
    dependencies: Dict[str, Provider]
 | 
			
		||||
    overridden: Tuple[Provider]
 | 
			
		||||
    __self__: Provider
 | 
			
		||||
    def __init__(self) -> None: ...
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,8 @@ from .providers cimport (
 | 
			
		|||
    Provider,
 | 
			
		||||
    Object,
 | 
			
		||||
    Resource,
 | 
			
		||||
    Dependency,
 | 
			
		||||
    DependenciesContainer,
 | 
			
		||||
    Container as ContainerProvider,
 | 
			
		||||
    deepcopy,
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +127,22 @@ class DynamicContainer(object):
 | 
			
		|||
            del self.providers[name]
 | 
			
		||||
        super(DynamicContainer, self).__delattr__(name)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def dependencies(self):
 | 
			
		||||
        """Return dependency providers dictionary.
 | 
			
		||||
 | 
			
		||||
        Dependency providers can be both of :py:class:`dependency_injector.providers.Dependency` and
 | 
			
		||||
        :py:class:`dependency_injector.providers.DependenciesContainer`.
 | 
			
		||||
 | 
			
		||||
        :rtype:
 | 
			
		||||
            dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
        return {
 | 
			
		||||
            name: provider
 | 
			
		||||
            for name, provider in self.providers.items()
 | 
			
		||||
            if isinstance(provider, (Dependency, DependenciesContainer))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def set_providers(self, **providers):
 | 
			
		||||
        """Set container providers.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -340,6 +358,22 @@ class DeclarativeContainerMetaClass(type):
 | 
			
		|||
            del cls.cls_providers[name]
 | 
			
		||||
        super(DeclarativeContainerMetaClass, cls).__delattr__(name)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def dependencies(cls):
 | 
			
		||||
        """Return dependency providers dictionary.
 | 
			
		||||
 | 
			
		||||
        Dependency providers can be both of :py:class:`dependency_injector.providers.Dependency` and
 | 
			
		||||
        :py:class:`dependency_injector.providers.DependenciesContainer`.
 | 
			
		||||
 | 
			
		||||
        :rtype:
 | 
			
		||||
            dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
        return {
 | 
			
		||||
            name: provider
 | 
			
		||||
            for name, provider in cls.providers.items()
 | 
			
		||||
            if isinstance(provider, (Dependency, DependenciesContainer))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@six.add_metaclass(DeclarativeContainerMetaClass)
 | 
			
		||||
class DeclarativeContainer(object):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
from typing import Dict
 | 
			
		||||
 | 
			
		||||
from dependency_injector import containers, providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -38,3 +40,11 @@ class Container4(containers.DeclarativeContainer):
 | 
			
		|||
 | 
			
		||||
container4 = Container4()
 | 
			
		||||
container4.override(Container4())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Test 5: to check .dependencies attribute
 | 
			
		||||
class Container5(containers.DeclarativeContainer):
 | 
			
		||||
    provider = providers.Factory(int)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dependencies: Dict[str, providers.Provider] = Container5.dependencies
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
from typing import Dict
 | 
			
		||||
 | 
			
		||||
from dependency_injector import containers, providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -16,3 +18,7 @@ container3.override_providers(a=providers.Provider())
 | 
			
		|||
# Test 4: to check set_providers()
 | 
			
		||||
container4 = containers.DynamicContainer()
 | 
			
		||||
container4.set_providers(a=providers.Provider())
 | 
			
		||||
 | 
			
		||||
# Test 5: to check .dependencies attribute
 | 
			
		||||
container5 = containers.DynamicContainer()
 | 
			
		||||
dependencies: Dict[str, providers.Provider] = container5.dependencies
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,6 +60,32 @@ class DeclarativeContainerTests(unittest.TestCase):
 | 
			
		|||
                              p21=ContainerB.p21,
 | 
			
		||||
                              p22=ContainerB.p22))
 | 
			
		||||
 | 
			
		||||
    def test_dependencies_attribute(self):
 | 
			
		||||
        class ContainerD(ContainerC):
 | 
			
		||||
            p41 = providers.Dependency()
 | 
			
		||||
            p42 = providers.DependenciesContainer()
 | 
			
		||||
 | 
			
		||||
        class ContainerE(ContainerD):
 | 
			
		||||
            p51 = providers.Dependency()
 | 
			
		||||
            p52 = providers.DependenciesContainer()
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            ContainerD.dependencies,
 | 
			
		||||
            {
 | 
			
		||||
                'p41': ContainerD.p41,
 | 
			
		||||
                'p42': ContainerD.p42,
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            ContainerE.dependencies,
 | 
			
		||||
            {
 | 
			
		||||
                'p41': ContainerD.p41,
 | 
			
		||||
                'p42': ContainerD.p42,
 | 
			
		||||
                'p51': ContainerE.p51,
 | 
			
		||||
                'p52': ContainerE.p52,
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_set_get_del_providers(self):
 | 
			
		||||
        a_p13 = providers.Provider()
 | 
			
		||||
        b_p23 = providers.Provider()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,12 @@ class DeclarativeContainerInstanceTests(unittest.TestCase):
 | 
			
		|||
        self.assertIsNot(container_a1.p12, container_a2.p12)
 | 
			
		||||
        self.assertNotEqual(container_a1.providers, container_a2.providers)
 | 
			
		||||
 | 
			
		||||
    def test_dependencies_attribute(self):
 | 
			
		||||
        container = ContainerA()
 | 
			
		||||
        container.a1 = providers.Dependency()
 | 
			
		||||
        container.a2 = providers.DependenciesContainer()
 | 
			
		||||
        self.assertEqual(container.dependencies, {'a1': container.a1, 'a2': container.a2})
 | 
			
		||||
 | 
			
		||||
    def test_set_get_del_providers(self):
 | 
			
		||||
        p13 = providers.Provider()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user