Merge branch 'release/4.24.0' into master

This commit is contained in:
Roman Mogylatov 2021-02-18 08:51:24 -05:00
commit c0d1e48f7b
9 changed files with 8556 additions and 682 deletions

View 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::

View File

@ -23,6 +23,7 @@ Containers module API docs - :py:mod:`dependency_injector.containers`.
dynamic
specialization
overriding
copying
reset_singletons
check_dependencies
traversal

View File

@ -7,6 +7,12 @@ that were made in every particular version.
From version 0.7.6 *Dependency Injector* framework strictly
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
------
- Fix docs publishing.

View 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)

View File

@ -1,4 +1,4 @@
"""Declarative container provider overriding with `@override()` decorator."""
"""Declarative container provider overriding with ``@override()`` decorator."""
import sqlite3
from unittest import mock
@ -11,7 +11,7 @@ class Container(containers.DeclarativeContainer):
database = providers.Singleton(sqlite3.connect, ':memory:')
# Overriding `Container` with `OverridingContainer`:
# Overriding ``Container`` with ``OverridingContainer``:
@containers.override(Container)
class OverridingContainer(containers.DeclarativeContainer):

View File

@ -1,6 +1,6 @@
"""Top-level package."""
__version__ = '4.23.5'
__version__ = '4.24.0'
"""Version number.
:type: str

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,3 @@ cpdef bint is_container(object instance)
cpdef object _check_provider_type(object container, object provider)
cpdef bint _isawaitable(object instance)

View File

@ -1,6 +1,5 @@
"""Containers module."""
import inspect
import sys
try:
@ -11,6 +10,7 @@ except ImportError:
import six
from . import providers, errors
from .providers cimport __is_future_or_coroutine
if sys.version_info[:2] >= (3, 6):
@ -276,7 +276,7 @@ class DynamicContainer(Container):
for provider in self.traverse(types=[providers.Resource]):
resource = provider.init()
if _isawaitable(resource):
if __is_future_or_coroutine(resource):
futures.append(resource)
if futures:
@ -289,7 +289,7 @@ class DynamicContainer(Container):
for provider in self.traverse(types=[providers.Resource]):
shutdown = provider.shutdown()
if _isawaitable(shutdown):
if __is_future_or_coroutine(shutdown):
futures.append(shutdown)
if futures:
@ -659,7 +659,7 @@ def override(object container):
def copy(object container):
""":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
providers by name, it would be replaced by reference.
@ -676,7 +676,7 @@ def copy(object container):
try:
source_provider = source_providers[name]
except KeyError:
...
continue
else:
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):
raise errors.Error('{0} can contain only {1} '
'instances'.format(container, container.provider_type))
cpdef bint _isawaitable(object instance):
try:
return <bint> inspect.isawaitable(instance)
except AttributeError:
return <bint> False