mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +03:00 
			
		
		
		
	Merge branch 'release/4.28.0' into master
This commit is contained in:
		
						commit
						25c966f7af
					
				| 
						 | 
					@ -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.28.0
 | 
				
			||||||
 | 
					------
 | 
				
			||||||
 | 
					- Add wiring injections into modules and class attributes.
 | 
				
			||||||
 | 
					  See issue: `#411 <https://github.com/ets-labs/python-dependency-injector/issues/411>`_.
 | 
				
			||||||
 | 
					  Many thanks to `@brunopereira27 <https://github.com/brunopereira27>`_ for submitting
 | 
				
			||||||
 | 
					  the use case.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
4.27.0
 | 
					4.27.0
 | 
				
			||||||
------
 | 
					------
 | 
				
			||||||
- Introduce wiring inspect filter to filter out ``flask.request`` and other local proxy objects
 | 
					- Introduce wiring inspect filter to filter out ``flask.request`` and other local proxy objects
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,6 +164,29 @@ To inject a container use special identifier ``<container>``:
 | 
				
			||||||
   def foo(container: Container = Provide['<container>']) -> None:
 | 
					   def foo(container: Container = Provide['<container>']) -> None:
 | 
				
			||||||
       ...
 | 
					       ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Making injections into modules and class attributes
 | 
				
			||||||
 | 
					---------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can use wiring to make injections into modules and class attributes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../examples/wiring/example_attribute.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :lines: 3-
 | 
				
			||||||
 | 
					   :emphasize-lines: 16,21
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You could also use string identifiers to avoid a dependency on a container:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					   :emphasize-lines: 1,6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   service: Service = Provide['service']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   class Main:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       service: Service = Provide['service']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Wiring with modules and packages
 | 
					Wiring with modules and packages
 | 
				
			||||||
--------------------------------
 | 
					--------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								examples/wiring/example_attribute.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								examples/wiring/example_attribute.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					"""Wiring attribute example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import containers, providers
 | 
				
			||||||
 | 
					from dependency_injector.wiring import Provide
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Service:
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Container(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    service = providers.Factory(Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					service: Service = Provide[Container.service]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Main:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    service: Service = Provide[Container.service]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    container = Container()
 | 
				
			||||||
 | 
					    container.wire(modules=[sys.modules[__name__]])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert isinstance(service, Service)
 | 
				
			||||||
 | 
					    assert isinstance(Main.service, Service)
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
"""Top-level package."""
 | 
					"""Top-level package."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__version__ = '4.27.0'
 | 
					__version__ = '4.28.0'
 | 
				
			||||||
"""Version number.
 | 
					"""Version number.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:type: str
 | 
					:type: str
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ from typing import (
 | 
				
			||||||
    TypeVar,
 | 
					    TypeVar,
 | 
				
			||||||
    Type,
 | 
					    Type,
 | 
				
			||||||
    Union,
 | 
					    Union,
 | 
				
			||||||
 | 
					    Set,
 | 
				
			||||||
    cast,
 | 
					    cast,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,22 +83,53 @@ F = TypeVar('F', bound=Callable[..., Any])
 | 
				
			||||||
Container = Any
 | 
					Container = Any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Registry:
 | 
					class PatchedRegistry:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        self._storage = set()
 | 
					        self._callables: Set[Callable[..., Any]] = set()
 | 
				
			||||||
 | 
					        self._attributes: Set[PatchedAttribute] = set()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def add(self, patched: Callable[..., Any]) -> None:
 | 
					    def add_callable(self, patched: Callable[..., Any]) -> None:
 | 
				
			||||||
        self._storage.add(patched)
 | 
					        self._callables.add(patched)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_from_module(self, module: ModuleType) -> Iterator[Callable[..., Any]]:
 | 
					    def get_callables_from_module(self, module: ModuleType) -> Iterator[Callable[..., Any]]:
 | 
				
			||||||
        for patched in self._storage:
 | 
					        for patched in self._callables:
 | 
				
			||||||
            if patched.__module__ != module.__name__:
 | 
					            if patched.__module__ != module.__name__:
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            yield patched
 | 
					            yield patched
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_attribute(self, patched: 'PatchedAttribute'):
 | 
				
			||||||
 | 
					        self._attributes.add(patched)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_patched_registry = Registry()
 | 
					    def get_attributes_from_module(self, module: ModuleType) -> Iterator['PatchedAttribute']:
 | 
				
			||||||
 | 
					        for attribute in self._attributes:
 | 
				
			||||||
 | 
					            if not attribute.is_in_module(module):
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            yield attribute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear_module_attributes(self, module: ModuleType):
 | 
				
			||||||
 | 
					        for attribute in self._attributes.copy():
 | 
				
			||||||
 | 
					            if not attribute.is_in_module(module):
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            self._attributes.remove(attribute)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PatchedAttribute:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, member: Any, name: str, marker: '_Marker'):
 | 
				
			||||||
 | 
					        self.member = member
 | 
				
			||||||
 | 
					        self.name = name
 | 
				
			||||||
 | 
					        self.marker = marker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def module_name(self) -> str:
 | 
				
			||||||
 | 
					        if isinstance(self.member, ModuleType):
 | 
				
			||||||
 | 
					            return self.member.__name__
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return self.member.__module__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def is_in_module(self, module: ModuleType) -> bool:
 | 
				
			||||||
 | 
					        return self.module_name == module.__name__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProvidersMap:
 | 
					class ProvidersMap:
 | 
				
			||||||
| 
						 | 
					@ -278,9 +310,6 @@ class InspectFilter:
 | 
				
			||||||
               and issubclass(instance, starlette.requests.Request)
 | 
					               and issubclass(instance, starlette.requests.Request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inspect_filter = InspectFilter()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def wire(  # noqa: C901
 | 
					def wire(  # noqa: C901
 | 
				
			||||||
        container: Container,
 | 
					        container: Container,
 | 
				
			||||||
        *,
 | 
					        *,
 | 
				
			||||||
| 
						 | 
					@ -301,20 +330,27 @@ def wire(  # noqa: C901
 | 
				
			||||||
    providers_map = ProvidersMap(container)
 | 
					    providers_map = ProvidersMap(container)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for module in modules:
 | 
					    for module in modules:
 | 
				
			||||||
        for name, member in inspect.getmembers(module):
 | 
					        for member_name, member in inspect.getmembers(module):
 | 
				
			||||||
            if inspect_filter.is_excluded(member):
 | 
					            if _inspect_filter.is_excluded(member):
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            if inspect.isfunction(member):
 | 
					 | 
				
			||||||
                _patch_fn(module, name, member, providers_map)
 | 
					 | 
				
			||||||
            elif inspect.isclass(member):
 | 
					 | 
				
			||||||
                for method_name, method in inspect.getmembers(member, _is_method):
 | 
					 | 
				
			||||||
                    _patch_method(member, method_name, method, providers_map)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for patched in _patched_registry.get_from_module(module):
 | 
					            if _is_marker(member):
 | 
				
			||||||
 | 
					                _patch_attribute(module, member_name, member, providers_map)
 | 
				
			||||||
 | 
					            elif inspect.isfunction(member):
 | 
				
			||||||
 | 
					                _patch_fn(module, member_name, member, providers_map)
 | 
				
			||||||
 | 
					            elif inspect.isclass(member):
 | 
				
			||||||
 | 
					                cls = member
 | 
				
			||||||
 | 
					                for cls_member_name, cls_member in inspect.getmembers(cls):
 | 
				
			||||||
 | 
					                    if _is_marker(cls_member):
 | 
				
			||||||
 | 
					                        _patch_attribute(cls, cls_member_name, cls_member, providers_map)
 | 
				
			||||||
 | 
					                    elif _is_method(cls_member):
 | 
				
			||||||
 | 
					                        _patch_method(cls, cls_member_name, cls_member, providers_map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for patched in _patched_registry.get_callables_from_module(module):
 | 
				
			||||||
            _bind_injections(patched, providers_map)
 | 
					            _bind_injections(patched, providers_map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def unwire(
 | 
					def unwire(  # noqa: C901
 | 
				
			||||||
        *,
 | 
					        *,
 | 
				
			||||||
        modules: Optional[Iterable[ModuleType]] = None,
 | 
					        modules: Optional[Iterable[ModuleType]] = None,
 | 
				
			||||||
        packages: Optional[Iterable[ModuleType]] = None,
 | 
					        packages: Optional[Iterable[ModuleType]] = None,
 | 
				
			||||||
| 
						 | 
					@ -335,15 +371,19 @@ def unwire(
 | 
				
			||||||
                for method_name, method in inspect.getmembers(member, inspect.isfunction):
 | 
					                for method_name, method in inspect.getmembers(member, inspect.isfunction):
 | 
				
			||||||
                    _unpatch(member, method_name, method)
 | 
					                    _unpatch(member, method_name, method)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for patched in _patched_registry.get_from_module(module):
 | 
					        for patched in _patched_registry.get_callables_from_module(module):
 | 
				
			||||||
            _unbind_injections(patched)
 | 
					            _unbind_injections(patched)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for patched_attribute in _patched_registry.get_attributes_from_module(module):
 | 
				
			||||||
 | 
					            _unpatch_attribute(patched_attribute)
 | 
				
			||||||
 | 
					        _patched_registry.clear_module_attributes(module)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def inject(fn: F) -> F:
 | 
					def inject(fn: F) -> F:
 | 
				
			||||||
    """Decorate callable with injecting decorator."""
 | 
					    """Decorate callable with injecting decorator."""
 | 
				
			||||||
    reference_injections, reference_closing = _fetch_reference_injections(fn)
 | 
					    reference_injections, reference_closing = _fetch_reference_injections(fn)
 | 
				
			||||||
    patched = _get_patched(fn, reference_injections, reference_closing)
 | 
					    patched = _get_patched(fn, reference_injections, reference_closing)
 | 
				
			||||||
    _patched_registry.add(patched)
 | 
					    _patched_registry.add_callable(patched)
 | 
				
			||||||
    return cast(F, patched)
 | 
					    return cast(F, patched)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -358,7 +398,7 @@ def _patch_fn(
 | 
				
			||||||
        if not reference_injections:
 | 
					        if not reference_injections:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        fn = _get_patched(fn, reference_injections, reference_closing)
 | 
					        fn = _get_patched(fn, reference_injections, reference_closing)
 | 
				
			||||||
        _patched_registry.add(fn)
 | 
					        _patched_registry.add_callable(fn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _bind_injections(fn, providers_map)
 | 
					    _bind_injections(fn, providers_map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -384,7 +424,7 @@ def _patch_method(
 | 
				
			||||||
        if not reference_injections:
 | 
					        if not reference_injections:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        fn = _get_patched(fn, reference_injections, reference_closing)
 | 
					        fn = _get_patched(fn, reference_injections, reference_closing)
 | 
				
			||||||
        _patched_registry.add(fn)
 | 
					        _patched_registry.add_callable(fn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _bind_injections(fn, providers_map)
 | 
					    _bind_injections(fn, providers_map)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -411,6 +451,31 @@ def _unpatch(
 | 
				
			||||||
    _unbind_injections(fn)
 | 
					    _unbind_injections(fn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _patch_attribute(
 | 
				
			||||||
 | 
					        member: Any,
 | 
				
			||||||
 | 
					        name: str,
 | 
				
			||||||
 | 
					        marker: '_Marker',
 | 
				
			||||||
 | 
					        providers_map: ProvidersMap,
 | 
				
			||||||
 | 
					) -> None:
 | 
				
			||||||
 | 
					    provider = providers_map.resolve_provider(marker.provider, marker.modifier)
 | 
				
			||||||
 | 
					    if provider is None:
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _patched_registry.add_attribute(PatchedAttribute(member, name, marker))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if isinstance(marker, Provide):
 | 
				
			||||||
 | 
					        instance = provider()
 | 
				
			||||||
 | 
					        setattr(member, name, instance)
 | 
				
			||||||
 | 
					    elif isinstance(marker, Provider):
 | 
				
			||||||
 | 
					        setattr(member, name, provider)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        raise Exception(f'Unknown type of marker {marker}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _unpatch_attribute(patched: PatchedAttribute) -> None:
 | 
				
			||||||
 | 
					    setattr(patched.member, patched.name, patched.marker)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _fetch_reference_injections(
 | 
					def _fetch_reference_injections(
 | 
				
			||||||
        fn: Callable[..., Any],
 | 
					        fn: Callable[..., Any],
 | 
				
			||||||
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
 | 
					) -> Tuple[Dict[str, Any], Dict[str, Any]]:
 | 
				
			||||||
| 
						 | 
					@ -484,6 +549,10 @@ def _is_method(member):
 | 
				
			||||||
    return inspect.ismethod(member) or inspect.isfunction(member)
 | 
					    return inspect.ismethod(member) or inspect.isfunction(member)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _is_marker(member):
 | 
				
			||||||
 | 
					    return isinstance(member, _Marker)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _get_patched(fn, reference_injections, reference_closing):
 | 
					def _get_patched(fn, reference_injections, reference_closing):
 | 
				
			||||||
    if inspect.iscoroutinefunction(fn):
 | 
					    if inspect.iscoroutinefunction(fn):
 | 
				
			||||||
        patched = _get_async_patched(fn)
 | 
					        patched = _get_async_patched(fn)
 | 
				
			||||||
| 
						 | 
					@ -825,9 +894,6 @@ class AutoLoader:
 | 
				
			||||||
        importlib.invalidate_caches()
 | 
					        importlib.invalidate_caches()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_loader = AutoLoader()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def register_loader_containers(*containers: Container) -> None:
 | 
					def register_loader_containers(*containers: Container) -> None:
 | 
				
			||||||
    """Register containers in auto-wiring module loader."""
 | 
					    """Register containers in auto-wiring module loader."""
 | 
				
			||||||
    _loader.register_containers(*containers)
 | 
					    _loader.register_containers(*containers)
 | 
				
			||||||
| 
						 | 
					@ -851,3 +917,8 @@ def uninstall_loader() -> None:
 | 
				
			||||||
def is_loader_installed() -> bool:
 | 
					def is_loader_installed() -> bool:
 | 
				
			||||||
    """Check if auto-wiring module loader hook is installed."""
 | 
					    """Check if auto-wiring module loader hook is installed."""
 | 
				
			||||||
    return _loader.installed
 | 
					    return _loader.installed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_patched_registry = PatchedRegistry()
 | 
				
			||||||
 | 
					_inspect_filter = InspectFilter()
 | 
				
			||||||
 | 
					_loader = AutoLoader()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,14 +3,24 @@
 | 
				
			||||||
from decimal import Decimal
 | 
					from decimal import Decimal
 | 
				
			||||||
from typing import Callable
 | 
					from typing import Callable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import providers
 | 
				
			||||||
from dependency_injector.wiring import inject, Provide, Provider
 | 
					from dependency_injector.wiring import inject, Provide, Provider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .container import Container, SubContainer
 | 
					from .container import Container, SubContainer
 | 
				
			||||||
from .service import Service
 | 
					from .service import Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					service: Service = Provide[Container.service]
 | 
				
			||||||
 | 
					service_provider: Callable[..., Service] = Provider[Container.service]
 | 
				
			||||||
 | 
					undefined: Callable = Provide[providers.Provider()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestClass:
 | 
					class TestClass:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    service: Service = Provide[Container.service]
 | 
				
			||||||
 | 
					    service_provider: Callable[..., Service] = Provider[Container.service]
 | 
				
			||||||
 | 
					    undefined: Callable = Provide[providers.Provider()]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @inject
 | 
					    @inject
 | 
				
			||||||
    def __init__(self, service: Service = Provide[Container.service]):
 | 
					    def __init__(self, service: Service = Provide[Container.service]):
 | 
				
			||||||
        self.service = service
 | 
					        self.service = service
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					"""Test module for wiring with invalid type of marker for attribute injection."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector.wiring import Closing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .container import Container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					service = Closing[Container.service]
 | 
				
			||||||
| 
						 | 
					@ -19,8 +19,17 @@ from .container import Container
 | 
				
			||||||
from .service import Service
 | 
					from .service import Service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					service: Service = Provide['service']
 | 
				
			||||||
 | 
					service_provider: Callable[..., Service] = Provider['service']
 | 
				
			||||||
 | 
					undefined: Callable = Provide['undefined']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestClass:
 | 
					class TestClass:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    service: Service = Provide['service']
 | 
				
			||||||
 | 
					    service_provider: Callable[..., Service] = Provider['service']
 | 
				
			||||||
 | 
					    undefined: Callable = Provide['undefined']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @inject
 | 
					    @inject
 | 
				
			||||||
    def __init__(self, service: Service = Provide['service']):
 | 
					    def __init__(self, service: Service = Provide['service']):
 | 
				
			||||||
        self.service = service
 | 
					        self.service = service
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ import unittest
 | 
				
			||||||
from dependency_injector.wiring import (
 | 
					from dependency_injector.wiring import (
 | 
				
			||||||
    wire,
 | 
					    wire,
 | 
				
			||||||
    Provide,
 | 
					    Provide,
 | 
				
			||||||
 | 
					    Provider,
 | 
				
			||||||
    Closing,
 | 
					    Closing,
 | 
				
			||||||
    register_loader_containers,
 | 
					    register_loader_containers,
 | 
				
			||||||
    unregister_loader_containers,
 | 
					    unregister_loader_containers,
 | 
				
			||||||
| 
						 | 
					@ -64,6 +65,20 @@ class WiringTest(unittest.TestCase):
 | 
				
			||||||
        service = test_function()
 | 
					        service = test_function()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_module_attributes_wiring(self):
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.service, Service)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.service_provider(), Service)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.undefined, Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_module_attribute_wiring_with_invalid_marker(self):
 | 
				
			||||||
 | 
					        from wiringsamples import module_invalid_attr_injection
 | 
				
			||||||
 | 
					        with self.assertRaises(Exception) as context:
 | 
				
			||||||
 | 
					            self.container.wire(modules=[module_invalid_attr_injection])
 | 
				
			||||||
 | 
					        self.assertEqual(
 | 
				
			||||||
 | 
					            str(context.exception),
 | 
				
			||||||
 | 
					            'Unknown type of marker {0}'.format(module_invalid_attr_injection.service),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_class_wiring(self):
 | 
					    def test_class_wiring(self):
 | 
				
			||||||
        test_class_object = module.TestClass()
 | 
					        test_class_object = module.TestClass()
 | 
				
			||||||
        self.assertIsInstance(test_class_object.service, Service)
 | 
					        self.assertIsInstance(test_class_object.service, Service)
 | 
				
			||||||
| 
						 | 
					@ -97,6 +112,11 @@ class WiringTest(unittest.TestCase):
 | 
				
			||||||
        service = instance.static_method()
 | 
					        service = instance.static_method()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_class_attribute_wiring(self):
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.service, Service)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.service_provider(), Service)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.undefined, Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_function_wiring(self):
 | 
					    def test_function_wiring(self):
 | 
				
			||||||
        service = module.test_function()
 | 
					        service = module.test_function()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
| 
						 | 
					@ -215,6 +235,18 @@ class WiringTest(unittest.TestCase):
 | 
				
			||||||
        self.container.unwire()
 | 
					        self.container.unwire()
 | 
				
			||||||
        self.assertIsInstance(submodule.test_function(), Provide)
 | 
					        self.assertIsInstance(submodule.test_function(), Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_unwire_module_attributes(self):
 | 
				
			||||||
 | 
					        self.container.unwire()
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.service, Provide)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.service_provider, Provider)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.undefined, Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_unwire_class_attributes(self):
 | 
				
			||||||
 | 
					        self.container.unwire()
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.service, Provide)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.service_provider, Provider)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.undefined, Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_wire_multiple_containers(self):
 | 
					    def test_wire_multiple_containers(self):
 | 
				
			||||||
        sub_container = SubContainer()
 | 
					        sub_container = SubContainer()
 | 
				
			||||||
        sub_container.wire(
 | 
					        sub_container.wire(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,9 @@ import unittest
 | 
				
			||||||
from dependency_injector.wiring import (
 | 
					from dependency_injector.wiring import (
 | 
				
			||||||
    wire,
 | 
					    wire,
 | 
				
			||||||
    Provide,
 | 
					    Provide,
 | 
				
			||||||
    Closing)
 | 
					    Provider,
 | 
				
			||||||
 | 
					    Closing,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from dependency_injector import errors
 | 
					from dependency_injector import errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Runtime import to avoid syntax errors in samples on Python < 3.5
 | 
					# Runtime import to avoid syntax errors in samples on Python < 3.5
 | 
				
			||||||
| 
						 | 
					@ -59,6 +61,11 @@ class WiringTest(unittest.TestCase):
 | 
				
			||||||
        service = test_function()
 | 
					        service = test_function()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_module_attributes_wiring(self):
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.service, Service)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.service_provider(), Service)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.undefined, Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_class_wiring(self):
 | 
					    def test_class_wiring(self):
 | 
				
			||||||
        test_class_object = module.TestClass()
 | 
					        test_class_object = module.TestClass()
 | 
				
			||||||
        self.assertIsInstance(test_class_object.service, Service)
 | 
					        self.assertIsInstance(test_class_object.service, Service)
 | 
				
			||||||
| 
						 | 
					@ -92,6 +99,11 @@ class WiringTest(unittest.TestCase):
 | 
				
			||||||
        service = instance.static_method()
 | 
					        service = instance.static_method()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_class_attribute_wiring(self):
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.service, Service)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.service_provider(), Service)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.undefined, Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_function_wiring(self):
 | 
					    def test_function_wiring(self):
 | 
				
			||||||
        service = module.test_function()
 | 
					        service = module.test_function()
 | 
				
			||||||
        self.assertIsInstance(service, Service)
 | 
					        self.assertIsInstance(service, Service)
 | 
				
			||||||
| 
						 | 
					@ -210,6 +222,18 @@ class WiringTest(unittest.TestCase):
 | 
				
			||||||
        self.container.unwire()
 | 
					        self.container.unwire()
 | 
				
			||||||
        self.assertIsInstance(submodule.test_function(), Provide)
 | 
					        self.assertIsInstance(submodule.test_function(), Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_unwire_module_attributes(self):
 | 
				
			||||||
 | 
					        self.container.unwire()
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.service, Provide)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.service_provider, Provider)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.undefined, Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_unwire_class_attributes(self):
 | 
				
			||||||
 | 
					        self.container.unwire()
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.service, Provide)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.service_provider, Provider)
 | 
				
			||||||
 | 
					        self.assertIsInstance(module.TestClass.undefined, Provide)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_wire_multiple_containers(self):
 | 
					    def test_wire_multiple_containers(self):
 | 
				
			||||||
        sub_container = SubContainer()
 | 
					        sub_container = SubContainer()
 | 
				
			||||||
        sub_container.wire(
 | 
					        sub_container.wire(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user