python-dependency-injector/dependency_injector/catalogs/utils.py
2016-04-10 16:52:37 +03:00

64 lines
1.9 KiB
Python

"""Dependency injector catalog utils."""
import six
from copy import deepcopy
from dependency_injector.errors import UndefinedProviderError
def copy(catalog):
""":py:class:`DeclarativeCatalog` copying decorator.
This decorator copy all providers from provided catalog to decorated one.
If one of the decorated catalog providers matches to source catalog
providers by name, it would be replaced by reference.
:param catalog: Catalog that should be copied by decorated catalog.
:type catalog: :py:class:`dependency_injector.catalogs.DeclarativeCatalog`
:return: Declarative catalog's copying decorator.
:rtype:
callable(:py:class:`DeclarativeCatalog`)
"""
def decorator(copied_catalog):
"""Copying decorator.
:param copied_catalog: Decorated catalog.
:type copied_catalog: :py:class:`DeclarativeCatalog`
:return: Decorated catalog.
:rtype:
:py:class:`DeclarativeCatalog`
"""
memo = dict()
for name, provider in six.iteritems(copied_catalog.cls_providers):
try:
source_provider = catalog.get_provider(name)
except UndefinedProviderError:
pass
else:
memo[id(source_provider)] = provider
copied_catalog.bind_providers(deepcopy(catalog.providers, memo),
force=True)
return copied_catalog
return decorator
def override(catalog):
""":py:class:`DeclarativeCatalog` overriding decorator.
:param catalog: Catalog that should be overridden by decorated catalog.
:type catalog: :py:class:`DeclarativeCatalog`
:return: Declarative catalog's overriding decorator.
:rtype: callable(:py:class:`DeclarativeCatalog`)
"""
def decorator(overriding_catalog):
"""Overriding decorator."""
catalog.override(overriding_catalog)
return overriding_catalog
return decorator