mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 11:04:01 +03:00
Merge branch 'release/4.24.0' into master
This commit is contained in:
commit
c0d1e48f7b
14
docs/containers/copying.rst
Normal file
14
docs/containers/copying.rst
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
Container copying
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
You can create declarative container copies using ``@containers.copy()`` decorator.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/containers/declarative_copy_decorator.py
|
||||||
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
:emphasize-lines: 18-22
|
||||||
|
|
||||||
|
Decorator ``@containers.copy()`` copies providers from source container to destination container.
|
||||||
|
Destination container provider will replace source provider, if names match.
|
||||||
|
|
||||||
|
.. disqus::
|
|
@ -23,6 +23,7 @@ Containers module API docs - :py:mod:`dependency_injector.containers`.
|
||||||
dynamic
|
dynamic
|
||||||
specialization
|
specialization
|
||||||
overriding
|
overriding
|
||||||
|
copying
|
||||||
reset_singletons
|
reset_singletons
|
||||||
check_dependencies
|
check_dependencies
|
||||||
traversal
|
traversal
|
||||||
|
|
|
@ -7,6 +7,12 @@ 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.24.0
|
||||||
|
------
|
||||||
|
- Add docs on ``@containers.copy()`` decorator.
|
||||||
|
- Refactor ``@containers.copy()`` decorator.
|
||||||
|
- Refactor async mode support in containers module.
|
||||||
|
|
||||||
4.23.5
|
4.23.5
|
||||||
------
|
------
|
||||||
- Fix docs publishing.
|
- Fix docs publishing.
|
||||||
|
|
31
examples/containers/declarative_copy_decorator.py
Normal file
31
examples/containers/declarative_copy_decorator.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
"""Declarative container provider copying with ``@copy()`` decorator."""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
|
||||||
|
class Service:
|
||||||
|
def __init__(self, db):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
|
||||||
|
class SourceContainer(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
database = providers.Singleton(sqlite3.connect, ':memory:')
|
||||||
|
service = providers.Factory(Service, db=database)
|
||||||
|
|
||||||
|
|
||||||
|
# Copy ``SourceContainer`` providers into ``DestinationContainer``:
|
||||||
|
@containers.copy(SourceContainer)
|
||||||
|
class DestinationContainer(SourceContainer):
|
||||||
|
|
||||||
|
database = providers.Singleton(mock.Mock)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
container = DestinationContainer()
|
||||||
|
|
||||||
|
service = container.service()
|
||||||
|
assert isinstance(service.db, mock.Mock)
|
|
@ -1,4 +1,4 @@
|
||||||
"""Declarative container provider overriding with `@override()` decorator."""
|
"""Declarative container provider overriding with ``@override()`` decorator."""
|
||||||
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
@ -11,7 +11,7 @@ class Container(containers.DeclarativeContainer):
|
||||||
database = providers.Singleton(sqlite3.connect, ':memory:')
|
database = providers.Singleton(sqlite3.connect, ':memory:')
|
||||||
|
|
||||||
|
|
||||||
# Overriding `Container` with `OverridingContainer`:
|
# Overriding ``Container`` with ``OverridingContainer``:
|
||||||
@containers.override(Container)
|
@containers.override(Container)
|
||||||
class OverridingContainer(containers.DeclarativeContainer):
|
class OverridingContainer(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
"""Top-level package."""
|
"""Top-level package."""
|
||||||
|
|
||||||
__version__ = '4.23.5'
|
__version__ = '4.24.0'
|
||||||
"""Version number.
|
"""Version number.
|
||||||
|
|
||||||
:type: str
|
:type: str
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,3 @@ cpdef bint is_container(object instance)
|
||||||
|
|
||||||
|
|
||||||
cpdef object _check_provider_type(object container, object provider)
|
cpdef object _check_provider_type(object container, object provider)
|
||||||
|
|
||||||
|
|
||||||
cpdef bint _isawaitable(object instance)
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
"""Containers module."""
|
"""Containers module."""
|
||||||
|
|
||||||
import inspect
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -11,6 +10,7 @@ except ImportError:
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from . import providers, errors
|
from . import providers, errors
|
||||||
|
from .providers cimport __is_future_or_coroutine
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info[:2] >= (3, 6):
|
if sys.version_info[:2] >= (3, 6):
|
||||||
|
@ -276,7 +276,7 @@ class DynamicContainer(Container):
|
||||||
for provider in self.traverse(types=[providers.Resource]):
|
for provider in self.traverse(types=[providers.Resource]):
|
||||||
resource = provider.init()
|
resource = provider.init()
|
||||||
|
|
||||||
if _isawaitable(resource):
|
if __is_future_or_coroutine(resource):
|
||||||
futures.append(resource)
|
futures.append(resource)
|
||||||
|
|
||||||
if futures:
|
if futures:
|
||||||
|
@ -289,7 +289,7 @@ class DynamicContainer(Container):
|
||||||
for provider in self.traverse(types=[providers.Resource]):
|
for provider in self.traverse(types=[providers.Resource]):
|
||||||
shutdown = provider.shutdown()
|
shutdown = provider.shutdown()
|
||||||
|
|
||||||
if _isawaitable(shutdown):
|
if __is_future_or_coroutine(shutdown):
|
||||||
futures.append(shutdown)
|
futures.append(shutdown)
|
||||||
|
|
||||||
if futures:
|
if futures:
|
||||||
|
@ -659,7 +659,7 @@ def override(object container):
|
||||||
def copy(object container):
|
def copy(object container):
|
||||||
""":py:class:`DeclarativeContainer` copying decorator.
|
""":py:class:`DeclarativeContainer` copying decorator.
|
||||||
|
|
||||||
This decorator copy all providers from provided container to decorated one.
|
This decorator copies all providers from provided container to decorated one.
|
||||||
If one of the decorated container providers matches to source container
|
If one of the decorated container providers matches to source container
|
||||||
providers by name, it would be replaced by reference.
|
providers by name, it would be replaced by reference.
|
||||||
|
|
||||||
|
@ -676,7 +676,7 @@ def copy(object container):
|
||||||
try:
|
try:
|
||||||
source_provider = source_providers[name]
|
source_provider = source_providers[name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
...
|
continue
|
||||||
else:
|
else:
|
||||||
memo[id(source_provider)] = provider
|
memo[id(source_provider)] = provider
|
||||||
|
|
||||||
|
@ -711,10 +711,3 @@ cpdef object _check_provider_type(object container, object provider):
|
||||||
if not isinstance(provider, container.provider_type):
|
if not isinstance(provider, container.provider_type):
|
||||||
raise errors.Error('{0} can contain only {1} '
|
raise errors.Error('{0} can contain only {1} '
|
||||||
'instances'.format(container, container.provider_type))
|
'instances'.format(container, container.provider_type))
|
||||||
|
|
||||||
|
|
||||||
cpdef bint _isawaitable(object instance):
|
|
||||||
try:
|
|
||||||
return <bint> inspect.isawaitable(instance)
|
|
||||||
except AttributeError:
|
|
||||||
return <bint> False
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user