mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-27 12:04:00 +03:00
119 lines
3.6 KiB
Python
119 lines
3.6 KiB
Python
|
"""Dependency injector catalogs bundle module."""
|
||
|
|
||
|
import six
|
||
|
|
||
|
from dependency_injector.errors import (
|
||
|
Error,
|
||
|
UndefinedProviderError,
|
||
|
)
|
||
|
|
||
|
|
||
|
@six.python_2_unicode_compatible
|
||
|
class CatalogBundle(object):
|
||
|
"""Bundle of catalog providers.
|
||
|
|
||
|
:py:class:`CatalogBundle` is a frozen, limited collection of catalog
|
||
|
providers. While catalog could be used as a centralized place for
|
||
|
particular providers group, such bundles of catalog providers can be used
|
||
|
for creating several frozen, limited scopes that could be passed to
|
||
|
different subsystems.
|
||
|
|
||
|
:py:class:`CatalogBundle` has API's parity with catalogs
|
||
|
(:py:class:`DeclarativeCatalog` or :py:class:`DynamicCatalog`) in terms of
|
||
|
retrieving the providers, but it is "frozen" in terms of modification
|
||
|
provider's list.
|
||
|
|
||
|
:py:class:`CatalogBundle` is considered to be dependable on catalogs
|
||
|
(:py:class:`DeclarativeCatalog` or :py:class:`DynamicCatalog`) entity by
|
||
|
its design.
|
||
|
|
||
|
.. py:attribute:: catalog
|
||
|
|
||
|
Bundle's catalog.
|
||
|
|
||
|
:type: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog`
|
||
|
|
||
|
.. py:attribute:: providers
|
||
|
|
||
|
Dictionary of all providers.
|
||
|
|
||
|
:type: dict[str, :py:class:`dependency_injector.providers.Provider`]
|
||
|
"""
|
||
|
|
||
|
catalog = None
|
||
|
|
||
|
__IS_CATALOG_BUNDLE__ = True
|
||
|
__slots__ = ('providers', '__dict__')
|
||
|
|
||
|
@classmethod
|
||
|
def sub_cls_factory(cls, catalog):
|
||
|
"""Create bundle subclass for catalog.
|
||
|
|
||
|
:return: Subclass of :py:class:`CatalogBundle`.
|
||
|
:rtype: :py:class:`CatalogBundle`
|
||
|
"""
|
||
|
return type('BundleSubclass', (cls,), dict(catalog=catalog))
|
||
|
|
||
|
def __init__(self, *providers):
|
||
|
"""Initializer.
|
||
|
|
||
|
:param providers: Tuple of catalog's bundle providers.
|
||
|
:type providers: tuple[
|
||
|
:py:class:`dependency_injector.providers.Provider`]
|
||
|
"""
|
||
|
self.providers = dict((self.catalog.get_provider_bind_name(provider),
|
||
|
provider)
|
||
|
for provider in providers)
|
||
|
self.__dict__.update(self.providers)
|
||
|
super(CatalogBundle, self).__init__()
|
||
|
|
||
|
def get_provider(self, name):
|
||
|
"""Return provider with specified name or raise an error.
|
||
|
|
||
|
:param name: Provider's name.
|
||
|
:type name: str
|
||
|
|
||
|
:raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
|
||
|
|
||
|
:return: Provider with specified name.
|
||
|
:rtype: :py:class:`dependency_injector.providers.Provider`
|
||
|
"""
|
||
|
try:
|
||
|
return self.providers[name]
|
||
|
except KeyError:
|
||
|
raise Error('Provider "{0}" is not a part of {1}'.format(name,
|
||
|
self))
|
||
|
|
||
|
def has_provider(self, name):
|
||
|
"""Check if there is provider with certain name.
|
||
|
|
||
|
:param name: Provider's name.
|
||
|
:type name: str
|
||
|
|
||
|
:rtype: bool
|
||
|
"""
|
||
|
return name in self.providers
|
||
|
|
||
|
def __getattr__(self, item):
|
||
|
"""Return provider with specified name or raise en error.
|
||
|
|
||
|
:param name: Attribute's name.
|
||
|
:type name: str
|
||
|
|
||
|
:raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
|
||
|
"""
|
||
|
if item.startswith('__') and item.endswith('__'):
|
||
|
return super(CatalogBundle, self).__getattr__(item)
|
||
|
raise UndefinedProviderError('Provider "{0}" is not a part '
|
||
|
'of {1}'.format(item, self))
|
||
|
|
||
|
def __repr__(self):
|
||
|
"""Return string representation of catalog's bundle.
|
||
|
|
||
|
:rtype: str
|
||
|
"""
|
||
|
return '<{0}.Bundle({1})>'.format(
|
||
|
self.catalog.name, ', '.join(six.iterkeys(self.providers)))
|
||
|
|
||
|
__str__ = __repr__
|