Merge remote-tracking branch 'origin/docs_update_for_0.11'
							
								
								
									
										31
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						| 
						 | 
				
			
			@ -67,7 +67,10 @@ Examples
 | 
			
		|||
    """Concept example of `Dependency Injector`."""
 | 
			
		||||
 | 
			
		||||
    import sqlite3
 | 
			
		||||
    import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
    from dependency_injector import catalogs
 | 
			
		||||
    from dependency_injector import providers
 | 
			
		||||
    from dependency_injector import injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class UsersService(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -87,20 +90,20 @@ Examples
 | 
			
		|||
            self.users_service = users_service
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    class Services(di.DeclarativeCatalog):
 | 
			
		||||
    class Services(catalogs.DeclarativeCatalog):
 | 
			
		||||
        """Catalog of service providers."""
 | 
			
		||||
 | 
			
		||||
        database = di.Singleton(sqlite3.connect, ':memory:')
 | 
			
		||||
        """:type: di.Provider -> sqlite3.Connection"""
 | 
			
		||||
        database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
			
		||||
        """:type: providers.Provider -> sqlite3.Connection"""
 | 
			
		||||
 | 
			
		||||
        users = di.Factory(UsersService,
 | 
			
		||||
                           db=database)
 | 
			
		||||
        """:type: di.Provider -> UsersService"""
 | 
			
		||||
        users = providers.Factory(UsersService,
 | 
			
		||||
                                  db=database)
 | 
			
		||||
        """:type: providers.Provider -> UsersService"""
 | 
			
		||||
 | 
			
		||||
        auth = di.Factory(AuthService,
 | 
			
		||||
                          db=database,
 | 
			
		||||
                          users_service=users)
 | 
			
		||||
        """:type: di.Provider -> AuthService"""
 | 
			
		||||
        auth = providers.Factory(AuthService,
 | 
			
		||||
                                 db=database,
 | 
			
		||||
                                 users_service=users)
 | 
			
		||||
        """:type: providers.Provider -> AuthService"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # Retrieving catalog providers:
 | 
			
		||||
| 
						 | 
				
			
			@ -115,9 +118,9 @@ Examples
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    # Making some "inline" injections:
 | 
			
		||||
    @di.inject(users_service=Services.users)
 | 
			
		||||
    @di.inject(auth_service=Services.auth)
 | 
			
		||||
    @di.inject(database=Services.database)
 | 
			
		||||
    @injections.inject(users_service=Services.users)
 | 
			
		||||
    @injections.inject(auth_service=Services.auth)
 | 
			
		||||
    @injections.inject(database=Services.database)
 | 
			
		||||
    def example(users_service, auth_service, database):
 | 
			
		||||
        """Example callback."""
 | 
			
		||||
        assert users_service.db is auth_service.db
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,11 @@ from .errors import UndefinedProviderError
 | 
			
		|||
from . import catalogs
 | 
			
		||||
catalog = catalogs
 | 
			
		||||
 | 
			
		||||
VERSION = '0.10.5'
 | 
			
		||||
VERSION = '0.11.0'
 | 
			
		||||
"""Version number that follows semantic versioning.
 | 
			
		||||
 | 
			
		||||
:type: str
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__all__ = (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,40 +7,79 @@ from .errors import UndefinedProviderError
 | 
			
		|||
 | 
			
		||||
from .utils import is_provider
 | 
			
		||||
from .utils import is_catalog
 | 
			
		||||
from .utils import is_declarative_catalog
 | 
			
		||||
from .utils import ensure_is_provider
 | 
			
		||||
from .utils import ensure_is_catalog_bundle
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@six.python_2_unicode_compatible
 | 
			
		||||
class CatalogBundle(object):
 | 
			
		||||
    """Bundle of catalog providers."""
 | 
			
		||||
    """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.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    catalog = None
 | 
			
		||||
    """:type: DeclarativeCatalog"""
 | 
			
		||||
    """Bundle's catalog.
 | 
			
		||||
 | 
			
		||||
    :type: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog`
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __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."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param providers: Tuple of catalog's bundle providers.
 | 
			
		||||
        :type providers: tuple[
 | 
			
		||||
            :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
        self.providers = dict()
 | 
			
		||||
        """Dictionary of all providers.
 | 
			
		||||
 | 
			
		||||
        :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        for provider in providers:
 | 
			
		||||
            provider_name = self.catalog.get_provider_bind_name(provider)
 | 
			
		||||
            self.providers[provider_name] = provider
 | 
			
		||||
        self.__dict__.update(self.providers)
 | 
			
		||||
        super(CatalogBundle, self).__init__()
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def sub_cls_factory(cls, catalog):
 | 
			
		||||
        """Create bundle class for catalog.
 | 
			
		||||
 | 
			
		||||
        :rtype: CatalogBundle
 | 
			
		||||
        :return: Subclass of CatalogBundle
 | 
			
		||||
        """
 | 
			
		||||
        return type('BundleSubclass', (cls,), dict(catalog=catalog))
 | 
			
		||||
 | 
			
		||||
    def get_provider(self, name):
 | 
			
		||||
        """Return provider with specified name or raise an error."""
 | 
			
		||||
        """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:
 | 
			
		||||
| 
						 | 
				
			
			@ -48,18 +87,33 @@ class CatalogBundle(object):
 | 
			
		|||
                                                                     self))
 | 
			
		||||
 | 
			
		||||
    def has_provider(self, name):
 | 
			
		||||
        """Check if there is provider with certain 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):
 | 
			
		||||
        """Raise an error on every attempt to get undefined provider."""
 | 
			
		||||
        """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 bundle."""
 | 
			
		||||
        """Return string representation of catalog's bundle.
 | 
			
		||||
 | 
			
		||||
        :rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return '<{0}.Bundle({1})>'.format(
 | 
			
		||||
            self.catalog.name, ', '.join(six.iterkeys(self.providers)))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +122,22 @@ class CatalogBundle(object):
 | 
			
		|||
 | 
			
		||||
@six.python_2_unicode_compatible
 | 
			
		||||
class DynamicCatalog(object):
 | 
			
		||||
    """Catalog of providers."""
 | 
			
		||||
    """Dynamic catalog of providers.
 | 
			
		||||
 | 
			
		||||
    :py:class:`DynamicCatalog` is a catalog of providers that could be created
 | 
			
		||||
    in application's runtime. It should cover most of the cases when list of
 | 
			
		||||
    providers that would be included in catalog is non-deterministic in terms
 | 
			
		||||
    of apllication code (catalog's structure could be determined just after
 | 
			
		||||
    application will be started and will do some initial work, like parsing
 | 
			
		||||
    list of catalog's providers from the configuration).
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        services = DynamicCatalog(auth=providers.Factory(AuthService),
 | 
			
		||||
                                  users=providers.Factory(UsersService))
 | 
			
		||||
 | 
			
		||||
        users_service = services.users()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __IS_CATALOG__ = True
 | 
			
		||||
    __slots__ = ('name', 'providers', 'provider_names', 'overridden_by',
 | 
			
		||||
| 
						 | 
				
			
			@ -77,64 +146,132 @@ class DynamicCatalog(object):
 | 
			
		|||
    def __init__(self, **providers):
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :type providers: dict[str, dependency_injector.providers.Provider]
 | 
			
		||||
        :param providers: Dictionary of catalog providers.
 | 
			
		||||
        :type providers:
 | 
			
		||||
            dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
        self.Bundle = CatalogBundle.sub_cls_factory(self)
 | 
			
		||||
        """Catalog's bundle class.
 | 
			
		||||
 | 
			
		||||
        :type: :py:class:`CatalogBundle`
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.name = '.'.join((self.__class__.__module__,
 | 
			
		||||
                              self.__class__.__name__))
 | 
			
		||||
        self.providers = dict()
 | 
			
		||||
        self.provider_names = dict()
 | 
			
		||||
        self.overridden_by = tuple()
 | 
			
		||||
        """Catalog's name.
 | 
			
		||||
 | 
			
		||||
        self.Bundle = CatalogBundle.sub_cls_factory(self)
 | 
			
		||||
        By default, it is catalog's module + catalog's class name.
 | 
			
		||||
 | 
			
		||||
        :type: str
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.providers = dict()
 | 
			
		||||
        """Dictionary of all providers.
 | 
			
		||||
 | 
			
		||||
        :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.provider_names = dict()
 | 
			
		||||
 | 
			
		||||
        self.overridden_by = tuple()
 | 
			
		||||
        """Tuple of overriding catalogs.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[
 | 
			
		||||
            :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.bind_providers(providers)
 | 
			
		||||
        super(DynamicCatalog, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def is_bundle_owner(self, bundle):
 | 
			
		||||
        """Check if catalog is bundle owner."""
 | 
			
		||||
        """Check if catalog is bundle owner.
 | 
			
		||||
 | 
			
		||||
        :param bundle: Catalog's bundle instance.
 | 
			
		||||
        :type bundle: :py:class:`CatalogBundle`
 | 
			
		||||
 | 
			
		||||
        :rtype: bool
 | 
			
		||||
        """
 | 
			
		||||
        return ensure_is_catalog_bundle(bundle) and bundle.catalog is self
 | 
			
		||||
 | 
			
		||||
    def get_provider_bind_name(self, provider):
 | 
			
		||||
        """Return provider's name in catalog."""
 | 
			
		||||
        """Return provider's name in catalog.
 | 
			
		||||
 | 
			
		||||
        :param provider: Provider instance.
 | 
			
		||||
        :type provider: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
 | 
			
		||||
 | 
			
		||||
        :return: Provider's name.
 | 
			
		||||
        :rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        if not self.is_provider_bound(provider):
 | 
			
		||||
            raise Error('Can not find bind name for {0} in catalog {1}'.format(
 | 
			
		||||
                provider, self))
 | 
			
		||||
        return self.provider_names[provider]
 | 
			
		||||
 | 
			
		||||
    def is_provider_bound(self, provider):
 | 
			
		||||
        """Check if provider is bound to the catalog."""
 | 
			
		||||
        """Check if provider is bound to the catalog.
 | 
			
		||||
 | 
			
		||||
        :param provider: Provider instance.
 | 
			
		||||
        :type provider: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
        :rtype: bool
 | 
			
		||||
        """
 | 
			
		||||
        return provider in self.provider_names
 | 
			
		||||
 | 
			
		||||
    def filter(self, provider_type):
 | 
			
		||||
        """Return dict of providers, that are instance of provided type."""
 | 
			
		||||
        """Return dictionary of providers, that are instance of provided type.
 | 
			
		||||
 | 
			
		||||
        :param provider_type: Provider's type.
 | 
			
		||||
        :type provider_type: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
        :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
        return dict((name, provider)
 | 
			
		||||
                    for name, provider in six.iteritems(self.providers)
 | 
			
		||||
                    if isinstance(provider, provider_type))
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_overridden(self):
 | 
			
		||||
        """Check if catalog is overridden by another catalog."""
 | 
			
		||||
        """Read-only property that is set to ``True`` if catalog is overridden.
 | 
			
		||||
 | 
			
		||||
        :rtype: bool
 | 
			
		||||
        """
 | 
			
		||||
        return bool(self.overridden_by)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def last_overriding(self):
 | 
			
		||||
        """Return last overriding catalog."""
 | 
			
		||||
        try:
 | 
			
		||||
            return self.overridden_by[-1]
 | 
			
		||||
        except (TypeError, IndexError):
 | 
			
		||||
            raise Error('Catalog {0} is not overridden'.format(self))
 | 
			
		||||
        """Read-only reference to the last overriding catalog, if any.
 | 
			
		||||
 | 
			
		||||
        :type: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog` |
 | 
			
		||||
               None
 | 
			
		||||
        """
 | 
			
		||||
        return self.overridden_by[-1] if self.overridden_by else None
 | 
			
		||||
 | 
			
		||||
    def override(self, overriding):
 | 
			
		||||
        """Override current catalog providers by overriding catalog providers.
 | 
			
		||||
 | 
			
		||||
        :type overriding: DynamicCatalog
 | 
			
		||||
        :param overriding: Overriding catalog.
 | 
			
		||||
        :type overriding: :py:class:`DeclarativeCatalog` |
 | 
			
		||||
                          :py:class:`DynamicCatalog`
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error` if trying to
 | 
			
		||||
                override catalog by itself
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        if overriding is self:
 | 
			
		||||
            raise Error('Catalog {0} could not be overridden '
 | 
			
		||||
                        'with itself'.format(self))
 | 
			
		||||
        self.overridden_by += (overriding,)
 | 
			
		||||
        for name, provider in six.iteritems(overriding.providers):
 | 
			
		||||
            self.get_provider(name).override(provider)
 | 
			
		||||
 | 
			
		||||
    def reset_last_overriding(self):
 | 
			
		||||
        """Reset last overriding catalog."""
 | 
			
		||||
        """Reset last overriding catalog.
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        if not self.is_overridden:
 | 
			
		||||
            raise Error('Catalog {0} is not overridden'.format(self))
 | 
			
		||||
        self.overridden_by = self.overridden_by[:-1]
 | 
			
		||||
| 
						 | 
				
			
			@ -142,13 +279,25 @@ class DynamicCatalog(object):
 | 
			
		|||
            provider.reset_last_overriding()
 | 
			
		||||
 | 
			
		||||
    def reset_override(self):
 | 
			
		||||
        """Reset all overridings for all catalog providers."""
 | 
			
		||||
        """Reset all overridings for all catalog providers.
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        self.overridden_by = tuple()
 | 
			
		||||
        for provider in six.itervalues(self.providers):
 | 
			
		||||
            provider.reset_override()
 | 
			
		||||
 | 
			
		||||
    def get_provider(self, name):
 | 
			
		||||
        """Return provider with specified name or raise an error."""
 | 
			
		||||
        """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:
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +305,18 @@ class DynamicCatalog(object):
 | 
			
		|||
                                         'name - {1}'.format(self, name))
 | 
			
		||||
 | 
			
		||||
    def bind_provider(self, name, provider):
 | 
			
		||||
        """Bind provider to catalog with specified name."""
 | 
			
		||||
        """Bind provider to catalog with specified name.
 | 
			
		||||
 | 
			
		||||
        :param name: Name of the provider.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :param provider: Provider instance.
 | 
			
		||||
        :type provider: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        provider = ensure_is_provider(provider)
 | 
			
		||||
 | 
			
		||||
        if name in self.providers:
 | 
			
		||||
| 
						 | 
				
			
			@ -170,29 +330,66 @@ class DynamicCatalog(object):
 | 
			
		|||
        self.provider_names[provider] = name
 | 
			
		||||
 | 
			
		||||
    def bind_providers(self, providers):
 | 
			
		||||
        """Bind providers dictionary to catalog."""
 | 
			
		||||
        """Bind providers dictionary to catalog.
 | 
			
		||||
 | 
			
		||||
        :param providers: Dictionary of providers, where key is a name
 | 
			
		||||
            and value is a provider.
 | 
			
		||||
        :type providers:
 | 
			
		||||
            dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        for name, provider in six.iteritems(providers):
 | 
			
		||||
            self.bind_provider(name, provider)
 | 
			
		||||
 | 
			
		||||
    def has_provider(self, name):
 | 
			
		||||
        """Check if there is provider with certain 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 unbind_provider(self, name):
 | 
			
		||||
        """Remove provider binding."""
 | 
			
		||||
        """Remove provider binding.
 | 
			
		||||
 | 
			
		||||
        :param name: Provider's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        provider = self.get_provider(name)
 | 
			
		||||
        del self.providers[name]
 | 
			
		||||
        del self.provider_names[provider]
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, name):
 | 
			
		||||
        """Return provider with specified name or raise en error."""
 | 
			
		||||
        """Return provider with specified name or raise en error.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
 | 
			
		||||
        """
 | 
			
		||||
        return self.get_provider(name)
 | 
			
		||||
 | 
			
		||||
    def __setattr__(self, name, value):
 | 
			
		||||
        """Handle setting of catalog attributes.
 | 
			
		||||
 | 
			
		||||
        Setting of attributes works as usual, but if value of attribute is
 | 
			
		||||
        provider, this provider will be bound to catalog correctly.
 | 
			
		||||
        provider, this provider will be bound to catalog.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :param value: Attribute's value.
 | 
			
		||||
        :type value: :py:class:`dependency_injector.providers.Provider` |
 | 
			
		||||
                     object
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        if is_provider(value):
 | 
			
		||||
            return self.bind_provider(name, value)
 | 
			
		||||
| 
						 | 
				
			
			@ -202,12 +399,20 @@ class DynamicCatalog(object):
 | 
			
		|||
        """Handle deleting of catalog attibute.
 | 
			
		||||
 | 
			
		||||
        Deleting of attributes works as usual, but if value of attribute is
 | 
			
		||||
        provider, this provider will be unbound from catalog correctly.
 | 
			
		||||
        provider, this provider will be unbound from catalog.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        self.unbind_provider(name)
 | 
			
		||||
 | 
			
		||||
    def __repr__(self):
 | 
			
		||||
        """Return Python representation of catalog."""
 | 
			
		||||
        """Return Python representation of catalog.
 | 
			
		||||
 | 
			
		||||
        :rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return '<{0}({1})>'.format(self.name,
 | 
			
		||||
                                   ', '.join(six.iterkeys(self.providers)))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -233,44 +438,70 @@ class DeclarativeCatalogMetaClass(type):
 | 
			
		|||
 | 
			
		||||
        cls = type.__new__(mcs, class_name, bases, attributes)
 | 
			
		||||
 | 
			
		||||
        cls.catalog = DynamicCatalog()
 | 
			
		||||
        cls.catalog.name = '.'.join((cls.__module__, cls.__name__))
 | 
			
		||||
        cls.catalog.bind_providers(dict(providers))
 | 
			
		||||
        cls._catalog = DynamicCatalog()
 | 
			
		||||
        cls._catalog.name = '.'.join((cls.__module__, cls.__name__))
 | 
			
		||||
        cls._catalog.bind_providers(dict(providers))
 | 
			
		||||
 | 
			
		||||
        cls.cls_providers = dict(cls_providers)
 | 
			
		||||
        cls.inherited_providers = dict(inherited_providers)
 | 
			
		||||
 | 
			
		||||
        cls.Bundle = cls.catalog.Bundle
 | 
			
		||||
        cls.Bundle = cls._catalog.Bundle
 | 
			
		||||
 | 
			
		||||
        return cls
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def name(cls):
 | 
			
		||||
        """Return catalog's name."""
 | 
			
		||||
        return cls.catalog.name
 | 
			
		||||
        """Read-only property that represents catalog's name.
 | 
			
		||||
 | 
			
		||||
        Catalog's name is catalog's module + catalog's class name.
 | 
			
		||||
 | 
			
		||||
        :type: str
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.name
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def providers(cls):
 | 
			
		||||
        """Return dict of catalog's providers."""
 | 
			
		||||
        return cls.catalog.providers
 | 
			
		||||
        """Read-only dictionary of all providers.
 | 
			
		||||
 | 
			
		||||
        :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.providers
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def overridden_by(cls):
 | 
			
		||||
        """Return tuple of overriding catalogs."""
 | 
			
		||||
        return cls.catalog.overridden_by
 | 
			
		||||
        """Tuple of overriding catalogs.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[
 | 
			
		||||
            :py:class:`DeclarativeCatalog` |
 | 
			
		||||
            :py:class:`DynamicCatalog`]
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.overridden_by
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_overridden(cls):
 | 
			
		||||
        """Check if catalog is overridden by another catalog."""
 | 
			
		||||
        return cls.catalog.is_overridden
 | 
			
		||||
        """Read-only property that is set to ``True`` if catalog is overridden.
 | 
			
		||||
 | 
			
		||||
        :rtype: bool
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.is_overridden
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def last_overriding(cls):
 | 
			
		||||
        """Return last overriding catalog."""
 | 
			
		||||
        return cls.catalog.last_overriding
 | 
			
		||||
        """Read-only reference to the last overriding catalog, if any.
 | 
			
		||||
 | 
			
		||||
        :type: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog` |
 | 
			
		||||
               None
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.last_overriding
 | 
			
		||||
 | 
			
		||||
    def __getattr__(cls, name):
 | 
			
		||||
        """Return provider with specified name or raise en error."""
 | 
			
		||||
        """Return provider with specified name or raise en error.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
 | 
			
		||||
        """
 | 
			
		||||
        raise UndefinedProviderError('There is no provider "{0}" in '
 | 
			
		||||
                                     'catalog {1}'.format(name, cls))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -278,24 +509,41 @@ class DeclarativeCatalogMetaClass(type):
 | 
			
		|||
        """Handle setting of catalog attributes.
 | 
			
		||||
 | 
			
		||||
        Setting of attributes works as usual, but if value of attribute is
 | 
			
		||||
        provider, this provider will be bound to catalog correctly.
 | 
			
		||||
        provider, this provider will be bound to catalog.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :param value: Attribute's value.
 | 
			
		||||
        :type value: :py:class:`dependency_injector.providers.Provider` |
 | 
			
		||||
                     object
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        if is_provider(value):
 | 
			
		||||
            setattr(cls.catalog, name, value)
 | 
			
		||||
            setattr(cls._catalog, name, value)
 | 
			
		||||
        return super(DeclarativeCatalogMetaClass, cls).__setattr__(name, value)
 | 
			
		||||
 | 
			
		||||
    def __delattr__(cls, name):
 | 
			
		||||
        """Handle deleting of catalog attibute.
 | 
			
		||||
 | 
			
		||||
        Deleting of attributes works as usual, but if value of attribute is
 | 
			
		||||
        provider, this provider will be unbound from catalog correctly.
 | 
			
		||||
        provider, this provider will be unbound from catalog.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        if is_provider(getattr(cls, name)):
 | 
			
		||||
            delattr(cls.catalog, name)
 | 
			
		||||
            delattr(cls._catalog, name)
 | 
			
		||||
        return super(DeclarativeCatalogMetaClass, cls).__delattr__(name)
 | 
			
		||||
 | 
			
		||||
    def __repr__(cls):
 | 
			
		||||
        """Return string representation of the catalog."""
 | 
			
		||||
        """Return string representation of the catalog.
 | 
			
		||||
 | 
			
		||||
        :rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return '<{0}({1})>'.format(cls.name,
 | 
			
		||||
                                   ', '.join(six.iterkeys(cls.providers)))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -304,121 +552,274 @@ class DeclarativeCatalogMetaClass(type):
 | 
			
		|||
 | 
			
		||||
@six.add_metaclass(DeclarativeCatalogMetaClass)
 | 
			
		||||
class DeclarativeCatalog(object):
 | 
			
		||||
    """Declarative catalog catalog of providers.
 | 
			
		||||
    """Declarative catalog of providers.
 | 
			
		||||
 | 
			
		||||
    :type name: str
 | 
			
		||||
    :param name: Catalog's name
 | 
			
		||||
    :py:class:`DeclarativeCatalog` is a catalog of providers that could be
 | 
			
		||||
    defined in declarative manner. It should cover most of the cases when list
 | 
			
		||||
    of providers that would be included in catalog is deterministic (catalog
 | 
			
		||||
    will not change its structure in runtime).
 | 
			
		||||
 | 
			
		||||
    :type catalog: DynamicCatalog
 | 
			
		||||
    :param catalog: Instance of dynamic catalog
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
    :type Bundle: CatalogBundle
 | 
			
		||||
    :param Bundle: Catalog's bundle class
 | 
			
		||||
        class Services(DeclarativeCatalog):
 | 
			
		||||
 | 
			
		||||
    :type providers: dict[str, dependency_injector.Provider]
 | 
			
		||||
    :param providers: Dict of all catalog providers, including inherited from
 | 
			
		||||
        parent catalogs
 | 
			
		||||
            auth = providers.Factory(AuthService)
 | 
			
		||||
 | 
			
		||||
    :type cls_providers: dict[str, dependency_injector.Provider]
 | 
			
		||||
    :param cls_providers: Dict of current catalog providers
 | 
			
		||||
            users = providers.Factory(UsersService)
 | 
			
		||||
 | 
			
		||||
    :type inherited_providers: dict[str, dependency_injector.Provider]
 | 
			
		||||
    :param inherited_providers: Dict of providers, that are inherited from
 | 
			
		||||
        parent catalogs
 | 
			
		||||
 | 
			
		||||
    :type overridden_by: tuple[DeclarativeCatalog]
 | 
			
		||||
    :param overridden_by: Tuple of overriding catalogs
 | 
			
		||||
 | 
			
		||||
    :type is_overridden: bool
 | 
			
		||||
    :param is_overridden: Read-only, evaluated in runtime, property that is
 | 
			
		||||
        set to True if catalog is overridden
 | 
			
		||||
 | 
			
		||||
    :type last_overriding: DeclarativeCatalog | None
 | 
			
		||||
    :param last_overriding: Reference to the last overriding catalog, if any
 | 
			
		||||
        users_service = Services.users()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    Bundle = CatalogBundle
 | 
			
		||||
    """Catalog's bundle class.
 | 
			
		||||
 | 
			
		||||
    :type: :py:class:`CatalogBundle`
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    name = str()
 | 
			
		||||
    """Read-only property that represents catalog's name.
 | 
			
		||||
 | 
			
		||||
    Catalog's name is catalog's module + catalog's class name.
 | 
			
		||||
 | 
			
		||||
    :type: str
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    cls_providers = dict()
 | 
			
		||||
    """Read-only dictionary of current catalog providers.
 | 
			
		||||
 | 
			
		||||
    :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    inherited_providers = dict()
 | 
			
		||||
    """Read-only dictionary of inherited providers.
 | 
			
		||||
 | 
			
		||||
    :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    providers = dict()
 | 
			
		||||
    """Read-only dictionary of all providers.
 | 
			
		||||
 | 
			
		||||
    :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    overridden_by = tuple()
 | 
			
		||||
    is_overridden = bool
 | 
			
		||||
    last_overriding = None
 | 
			
		||||
    """Tuple of overriding catalogs.
 | 
			
		||||
 | 
			
		||||
    catalog = DynamicCatalog
 | 
			
		||||
    :type: tuple[:py:class:`DeclarativeCatalog` |
 | 
			
		||||
                 :py:class:`DynamicCatalog`]
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    is_overridden = bool
 | 
			
		||||
    """Read-only property that is set to ``True`` if catalog is overridden.
 | 
			
		||||
 | 
			
		||||
    :type: bool
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    last_overriding = None
 | 
			
		||||
    """Read-only reference to the last overriding catalog, if any.
 | 
			
		||||
 | 
			
		||||
    :type: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog` | None
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    _catalog = DynamicCatalog
 | 
			
		||||
 | 
			
		||||
    __IS_CATALOG__ = True
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def is_bundle_owner(cls, bundle):
 | 
			
		||||
        """Check if catalog is bundle owner."""
 | 
			
		||||
        return cls.catalog.is_bundle_owner(bundle)
 | 
			
		||||
        """Check if catalog is bundle owner.
 | 
			
		||||
 | 
			
		||||
        :param bundle: Catalog's bundle instance.
 | 
			
		||||
        :type bundle: :py:class:`CatalogBundle`
 | 
			
		||||
 | 
			
		||||
        :rtype: bool
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.is_bundle_owner(bundle)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_provider_bind_name(cls, provider):
 | 
			
		||||
        """Return provider's name in catalog."""
 | 
			
		||||
        return cls.catalog.get_provider_bind_name(provider)
 | 
			
		||||
        """Return provider's name in catalog.
 | 
			
		||||
 | 
			
		||||
        :param provider: Provider instance.
 | 
			
		||||
        :type provider: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
 | 
			
		||||
 | 
			
		||||
        :return: Provider's name.
 | 
			
		||||
        :rtype: str
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.get_provider_bind_name(provider)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def is_provider_bound(cls, provider):
 | 
			
		||||
        """Check if provider is bound to the catalog."""
 | 
			
		||||
        return cls.catalog.is_provider_bound(provider)
 | 
			
		||||
        """Check if provider is bound to the catalog.
 | 
			
		||||
 | 
			
		||||
        :param provider: Provider instance.
 | 
			
		||||
        :type provider: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
        :rtype: bool
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.is_provider_bound(provider)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def filter(cls, provider_type):
 | 
			
		||||
        """Return dict of providers, that are instance of provided type."""
 | 
			
		||||
        return cls.catalog.filter(provider_type)
 | 
			
		||||
        """Return dictionary of providers, that are instance of provided type.
 | 
			
		||||
 | 
			
		||||
        :param provider_type: Provider's type.
 | 
			
		||||
        :type provider_type: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
        :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.filter(provider_type)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def override(cls, overriding):
 | 
			
		||||
        """Override current catalog providers by overriding catalog providers.
 | 
			
		||||
 | 
			
		||||
        :type overriding: DeclarativeCatalog | DynamicCatalog
 | 
			
		||||
        :param overriding: Overriding catalog.
 | 
			
		||||
        :type overriding: :py:class:`DeclarativeCatalog` |
 | 
			
		||||
                          :py:class:`DynamicCatalog`
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error` if trying to
 | 
			
		||||
                override catalog by itself or its subclasses
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        return cls.catalog.override(overriding)
 | 
			
		||||
        if is_declarative_catalog(overriding) and issubclass(cls, overriding):
 | 
			
		||||
            raise Error('Catalog {0} could not be overridden '
 | 
			
		||||
                        'with itself or its subclasses'.format(cls))
 | 
			
		||||
        return cls._catalog.override(overriding)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def reset_last_overriding(cls):
 | 
			
		||||
        """Reset last overriding catalog."""
 | 
			
		||||
        cls.catalog.reset_last_overriding()
 | 
			
		||||
        """Reset last overriding catalog.
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        cls._catalog.reset_last_overriding()
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def reset_override(cls):
 | 
			
		||||
        """Reset all overridings for all catalog providers."""
 | 
			
		||||
        cls.catalog.reset_override()
 | 
			
		||||
        """Reset all overridings for all catalog providers.
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        cls._catalog.reset_override()
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_provider(cls, name):
 | 
			
		||||
        """Return provider with specified name or raise an error."""
 | 
			
		||||
        return cls.catalog.get_provider(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`
 | 
			
		||||
        """
 | 
			
		||||
        return cls._catalog.get_provider(name)
 | 
			
		||||
 | 
			
		||||
    get = get_provider  # Backward compatibility for versions < 0.11.*
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def bind_provider(cls, name, provider):
 | 
			
		||||
        """Bind provider to catalog with specified name."""
 | 
			
		||||
        """Bind provider to catalog with specified name.
 | 
			
		||||
 | 
			
		||||
        :param name: Name of the provider.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :param provider: Provider instance.
 | 
			
		||||
        :type provider: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        setattr(cls, name, provider)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def bind_providers(cls, providers):
 | 
			
		||||
        """Bind providers dictionary to catalog."""
 | 
			
		||||
        """Bind providers dictionary to catalog.
 | 
			
		||||
 | 
			
		||||
        :param providers: Dictionary of providers, where key is a name
 | 
			
		||||
            and value is a provider.
 | 
			
		||||
        :type providers:
 | 
			
		||||
            dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        for name, provider in six.iteritems(providers):
 | 
			
		||||
            setattr(cls, name, provider)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def has_provider(cls, name):
 | 
			
		||||
        """Check if there is provider with certain name."""
 | 
			
		||||
        """Check if there is provider with certain name.
 | 
			
		||||
 | 
			
		||||
        :param name: Provider's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :rtype: bool
 | 
			
		||||
        """
 | 
			
		||||
        return hasattr(cls, name)
 | 
			
		||||
 | 
			
		||||
    has = has_provider  # Backward compatibility for versions < 0.11.*
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def unbind_provider(cls, name):
 | 
			
		||||
        """Remove provider binding."""
 | 
			
		||||
        """Remove provider binding.
 | 
			
		||||
 | 
			
		||||
        :param name: Provider's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        delattr(cls, name)
 | 
			
		||||
 | 
			
		||||
    get = get_provider  # Backward compatibility for versions < 0.11.*
 | 
			
		||||
    has = has_provider  # Backward compatibility for versions < 0.11.*
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def __getattr__(cls, name):  # pragma: no cover
 | 
			
		||||
        """Return provider with specified name or raise en error.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError('Implementated in metaclass')
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def __setattr__(cls, name, value):  # pragma: no cover
 | 
			
		||||
        """Handle setting of catalog attributes.
 | 
			
		||||
 | 
			
		||||
        Setting of attributes works as usual, but if value of attribute is
 | 
			
		||||
        provider, this provider will be bound to catalog.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :param value: Attribute's value.
 | 
			
		||||
        :type value: :py:class:`dependency_injector.providers.Provider` |
 | 
			
		||||
                     object
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError('Implementated in metaclass')
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def __delattr__(cls, name):  # pragma: no cover
 | 
			
		||||
        """Handle deleting of catalog attibute.
 | 
			
		||||
 | 
			
		||||
        Deleting of attributes works as usual, but if value of attribute is
 | 
			
		||||
        provider, this provider will be unbound from catalog.
 | 
			
		||||
 | 
			
		||||
        :param name: Attribute's name.
 | 
			
		||||
        :type name: str
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError('Implementated in metaclass')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Backward compatibility for versions < 0.11.*
 | 
			
		||||
| 
						 | 
				
			
			@ -426,7 +827,14 @@ AbstractCatalog = DeclarativeCatalog
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def override(catalog):
 | 
			
		||||
    """Catalog overriding decorator."""
 | 
			
		||||
    """:py:class:`DeclarativeCatalog` overriding decorator.
 | 
			
		||||
 | 
			
		||||
    :param catalog: Catalog that should be overridden by decorated catalog.
 | 
			
		||||
    :type catalog: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog`
 | 
			
		||||
 | 
			
		||||
    :return: Declarative catalog's overriding decorator.
 | 
			
		||||
    :rtype: callable(:py:class:`DeclarativeCatalog`)
 | 
			
		||||
    """
 | 
			
		||||
    def decorator(overriding_catalog):
 | 
			
		||||
        """Overriding decorator."""
 | 
			
		||||
        catalog.override(overriding_catalog)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,21 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class Error(Exception):
 | 
			
		||||
    """Base error."""
 | 
			
		||||
    """Base error.
 | 
			
		||||
 | 
			
		||||
    All dependency injector errors extend this error class.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UndefinedProviderError(Error, AttributeError):
 | 
			
		||||
    """Undefined provider error."""
 | 
			
		||||
    """Undefined provider error.
 | 
			
		||||
 | 
			
		||||
    This error is used when provider could not be defined, for example:
 | 
			
		||||
 | 
			
		||||
        - provider with certain name could not be defined
 | 
			
		||||
        - catalog's name of the certain provider could not be defined
 | 
			
		||||
        - etc...
 | 
			
		||||
 | 
			
		||||
    Also this error extends standard :py:class:`AttributeError`. This gives
 | 
			
		||||
    possibility to use it correctly with ``__getattr__()``.
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,33 +13,60 @@ from .utils import is_kwarg_injection
 | 
			
		|||
from .errors import Error
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IS_PYPY = '__pypy__' in sys.builtin_module_names
 | 
			
		||||
if IS_PYPY or six.PY3:  # pragma: no cover
 | 
			
		||||
    OBJECT_INIT = six.get_unbound_function(object.__init__)
 | 
			
		||||
_IS_PYPY = '__pypy__' in sys.builtin_module_names
 | 
			
		||||
if _IS_PYPY or six.PY3:  # pragma: no cover
 | 
			
		||||
    _OBJECT_INIT = six.get_unbound_function(object.__init__)
 | 
			
		||||
else:  # pragma: no cover
 | 
			
		||||
    OBJECT_INIT = None
 | 
			
		||||
    _OBJECT_INIT = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Injection(object):
 | 
			
		||||
    """Base injection class."""
 | 
			
		||||
    """Base injection class.
 | 
			
		||||
 | 
			
		||||
    All injections extend this class.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __IS_INJECTION__ = True
 | 
			
		||||
    __slots__ = ('injectable', 'is_provider')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, injectable):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param injectable: Injectable value, could be provider or any
 | 
			
		||||
                           other object.
 | 
			
		||||
        :type injectable: object |
 | 
			
		||||
                          :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
        """
 | 
			
		||||
        self.injectable = injectable
 | 
			
		||||
        """Injectable value, could be provider or any other object.
 | 
			
		||||
 | 
			
		||||
        :type: object | :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.is_provider = is_provider(injectable)
 | 
			
		||||
        """Flag that is set to ``True`` if injectable value is provider.
 | 
			
		||||
 | 
			
		||||
        :type: bool
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        super(Injection, self).__init__()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def value(self):
 | 
			
		||||
        """Return injectable value."""
 | 
			
		||||
        """Read-only property that represents injectable value.
 | 
			
		||||
 | 
			
		||||
        Injectable values are provided "as is", except of providers
 | 
			
		||||
        (subclasses of :py:class:`dependency_injector.providers.Provider`).
 | 
			
		||||
        Providers will be called every time, when injection needs to be done.
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        if self.is_provider:
 | 
			
		||||
            return self.injectable()
 | 
			
		||||
        return self.injectable
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NamedInjection(Injection):
 | 
			
		||||
class _NamedInjection(Injection):
 | 
			
		||||
    """Base class of named injections."""
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('name',)
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +74,7 @@ class NamedInjection(Injection):
 | 
			
		|||
    def __init__(self, name, injectable):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.name = name
 | 
			
		||||
        super(NamedInjection, self).__init__(injectable)
 | 
			
		||||
        super(_NamedInjection, self).__init__(injectable)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Arg(Injection):
 | 
			
		||||
| 
						 | 
				
			
			@ -56,19 +83,19 @@ class Arg(Injection):
 | 
			
		|||
    __IS_ARG_INJECTION__ = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class KwArg(NamedInjection):
 | 
			
		||||
class KwArg(_NamedInjection):
 | 
			
		||||
    """Keyword argument injection."""
 | 
			
		||||
 | 
			
		||||
    __IS_KWARG_INJECTION__ = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Attribute(NamedInjection):
 | 
			
		||||
class Attribute(_NamedInjection):
 | 
			
		||||
    """Attribute injection."""
 | 
			
		||||
 | 
			
		||||
    __IS_ATTRIBUTE_INJECTION__ = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Method(NamedInjection):
 | 
			
		||||
class Method(_NamedInjection):
 | 
			
		||||
    """Method injection."""
 | 
			
		||||
 | 
			
		||||
    __IS_METHOD_INJECTION__ = True
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +104,48 @@ class Method(NamedInjection):
 | 
			
		|||
def inject(*args, **kwargs):
 | 
			
		||||
    """Dependency injection decorator.
 | 
			
		||||
 | 
			
		||||
    :return: (callable) -> (callable)
 | 
			
		||||
    :py:func:`inject` decorator can be used for making inline dependency
 | 
			
		||||
    injections. It patches decorated callable in such way that dependency
 | 
			
		||||
    injection will be done during every call of decorated callable.
 | 
			
		||||
 | 
			
		||||
    :py:func:`inject` decorator supports different syntaxes of passing
 | 
			
		||||
    injections:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        # Positional arguments injections (simplified syntax):
 | 
			
		||||
        @inject(1, 2)
 | 
			
		||||
        def some_function(arg1, arg2):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        # Keyword arguments injections (simplified syntax):
 | 
			
		||||
        @inject(arg1=1)
 | 
			
		||||
        @inject(arg2=2)
 | 
			
		||||
        def some_function(arg1, arg2):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        # Keyword arguments injections (extended (full) syntax):
 | 
			
		||||
        @inject(KwArg('arg1', 1))
 | 
			
		||||
        @inject(KwArg('arg2', 2))
 | 
			
		||||
        def some_function(arg1, arg2):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        # Keyword arguments injections into class init (simplified syntax):
 | 
			
		||||
        @inject(arg1=1)
 | 
			
		||||
        @inject(arg2=2)
 | 
			
		||||
        class SomeClass(object):
 | 
			
		||||
 | 
			
		||||
            def __init__(self, arg1, arg2):
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
    :param args: Tuple of context positional arguments.
 | 
			
		||||
    :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
    :param kwargs: Dictionary of context keyword arguments.
 | 
			
		||||
    :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
    :return: Class / callable decorator
 | 
			
		||||
    :rtype: (callable) -> (type | callable)
 | 
			
		||||
    """
 | 
			
		||||
    arg_injections = _parse_args_injections(args)
 | 
			
		||||
    kwarg_injections = _parse_kwargs_injections(args, kwargs)
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +156,7 @@ def inject(*args, **kwargs):
 | 
			
		|||
            cls = callback_or_cls
 | 
			
		||||
            try:
 | 
			
		||||
                cls_init = six.get_unbound_function(cls.__init__)
 | 
			
		||||
                assert cls_init is not OBJECT_INIT
 | 
			
		||||
                assert cls_init is not _OBJECT_INIT
 | 
			
		||||
            except (AttributeError, AssertionError):
 | 
			
		||||
                raise Error(
 | 
			
		||||
                    'Class {0}.{1} has no __init__() '.format(cls.__module__,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,45 @@ from .errors import Error
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class Provider(object):
 | 
			
		||||
    """Base provider class."""
 | 
			
		||||
    """Base provider class.
 | 
			
		||||
 | 
			
		||||
    :py:class:`Provider` is callable (implements ``__call__`` method). Every
 | 
			
		||||
    call to provider object returns provided result, according to the providing
 | 
			
		||||
    strategy of particular provider. This ``callable`` functionality is a
 | 
			
		||||
    regular part of providers API and it should be the same for all provider's
 | 
			
		||||
    subclasses.
 | 
			
		||||
 | 
			
		||||
    Implementation of particular providing strategy should be done in
 | 
			
		||||
    :py:meth:`Provider._provide` of :py:class:`Provider` subclass. Current
 | 
			
		||||
    method is called every time when not overridden provider is called.
 | 
			
		||||
 | 
			
		||||
    :py:class:`Provider` implements provider overriding logic that should be
 | 
			
		||||
    also common for all providers:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        provider1 = Factory(SomeClass)
 | 
			
		||||
        provider2 = Factory(ChildSomeClass)
 | 
			
		||||
 | 
			
		||||
        provider1.override(provider2)
 | 
			
		||||
 | 
			
		||||
        some_instance = provider1()
 | 
			
		||||
        assert isinstance(some_instance, ChildSomeClass)
 | 
			
		||||
 | 
			
		||||
    Also :py:class:`Provider` implements helper function for creating its
 | 
			
		||||
    delegates:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        provider = Factory(object)
 | 
			
		||||
        delegate = provider.delegate()
 | 
			
		||||
 | 
			
		||||
        delegated = delegate()
 | 
			
		||||
 | 
			
		||||
        assert provider is delegated
 | 
			
		||||
 | 
			
		||||
    All providers should extend this class.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __IS_PROVIDER__ = True
 | 
			
		||||
    __slots__ = ('overridden_by',)
 | 
			
		||||
| 
						 | 
				
			
			@ -24,9 +62,23 @@ class Provider(object):
 | 
			
		|||
    def __init__(self):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.overridden_by = None
 | 
			
		||||
        """Tuple of overriding providers, if any.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`Provider`] | None
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        super(Provider, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def __call__(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        Implementation of current method adds ``callable`` functionality for
 | 
			
		||||
        providers API and it should be common for all provider's subclasses.
 | 
			
		||||
        Also this method implements provider overriding logic that is also
 | 
			
		||||
        common for all providers. Implementation of particular providing
 | 
			
		||||
        strategy should be done in :py:meth:`Provider._provide` of
 | 
			
		||||
        :py:class:`Provider` subclass.
 | 
			
		||||
        """
 | 
			
		||||
        if self.overridden_by:
 | 
			
		||||
            return self.last_overriding(*args, **kwargs)
 | 
			
		||||
        return self._provide(*args, **kwargs)
 | 
			
		||||
| 
						 | 
				
			
			@ -40,12 +92,30 @@ class Provider(object):
 | 
			
		|||
        """
 | 
			
		||||
        raise NotImplementedError()
 | 
			
		||||
 | 
			
		||||
    def delegate(self):
 | 
			
		||||
        """Return provider's delegate."""
 | 
			
		||||
        return Delegate(self)
 | 
			
		||||
    @property
 | 
			
		||||
    def is_overridden(self):
 | 
			
		||||
        """Read-only property that is set to ``True`` if provider is overridden.
 | 
			
		||||
 | 
			
		||||
        :rtype: bool
 | 
			
		||||
        """
 | 
			
		||||
        return bool(self.overridden_by)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def last_overriding(self):
 | 
			
		||||
        """Read-only reference to the last overriding provider, if any.
 | 
			
		||||
 | 
			
		||||
        :type: :py:class:`Provider` | None
 | 
			
		||||
        """
 | 
			
		||||
        return self.overridden_by[-1] if self.overridden_by else None
 | 
			
		||||
 | 
			
		||||
    def override(self, provider):
 | 
			
		||||
        """Override provider with another provider."""
 | 
			
		||||
        """Override provider with another provider.
 | 
			
		||||
 | 
			
		||||
        :param provider: Overriding provider.
 | 
			
		||||
        :type provider: :py:class:`Provider`
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
			
		||||
        """
 | 
			
		||||
        if provider is self:
 | 
			
		||||
            raise Error('Provider {0} could not be overridden '
 | 
			
		||||
                        'with itself'.format(self))
 | 
			
		||||
| 
						 | 
				
			
			@ -54,74 +124,174 @@ class Provider(object):
 | 
			
		|||
        else:
 | 
			
		||||
            self.overridden_by += (ensure_is_provider(provider),)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_overridden(self):
 | 
			
		||||
        """Check if provider is overridden by another provider."""
 | 
			
		||||
        return bool(self.overridden_by)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def last_overriding(self):
 | 
			
		||||
        """Return last overriding provider."""
 | 
			
		||||
        try:
 | 
			
		||||
            return self.overridden_by[-1]
 | 
			
		||||
        except (TypeError, IndexError):
 | 
			
		||||
            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
			
		||||
 | 
			
		||||
    def reset_last_overriding(self):
 | 
			
		||||
        """Reset last overriding provider."""
 | 
			
		||||
        if not self.is_overridden:
 | 
			
		||||
        """Reset last overriding provider.
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error` if provider is not
 | 
			
		||||
                overridden.
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        if not self.overridden_by:
 | 
			
		||||
            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
			
		||||
        self.overridden_by = self.overridden_by[:-1]
 | 
			
		||||
 | 
			
		||||
    def reset_override(self):
 | 
			
		||||
        """Reset all overriding providers."""
 | 
			
		||||
        """Reset all overriding providers.
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        self.overridden_by = None
 | 
			
		||||
 | 
			
		||||
    def delegate(self):
 | 
			
		||||
        """Return provider's delegate.
 | 
			
		||||
 | 
			
		||||
        :rtype: :py:class:`Delegate`
 | 
			
		||||
        """
 | 
			
		||||
        return Delegate(self)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Delegate(Provider):
 | 
			
		||||
    """Provider's delegate."""
 | 
			
		||||
    """:py:class:`Delegate` provider delegates another provider.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        provider = Factory(object)
 | 
			
		||||
        delegate = Delegate(provider)
 | 
			
		||||
 | 
			
		||||
        delegated = delegate()
 | 
			
		||||
 | 
			
		||||
        assert provider is delegated
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('delegated',)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, delegated):
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :type delegated: Provider
 | 
			
		||||
        :provider delegated: Delegated provider.
 | 
			
		||||
        :type delegated: :py:class:`Provider`
 | 
			
		||||
        """
 | 
			
		||||
        self.delegated = ensure_is_provider(delegated)
 | 
			
		||||
        super(Delegate, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of context positional arguments.
 | 
			
		||||
        :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of context keyword arguments.
 | 
			
		||||
        :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        return self.delegated
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Factory(Provider):
 | 
			
		||||
    """Factory provider.
 | 
			
		||||
    """:py:class:`Factory` provider creates new instance on every call.
 | 
			
		||||
 | 
			
		||||
    Factory provider creates new instance of specified class on every call.
 | 
			
		||||
    :py:class:`Factory` supports different syntaxes of passing injections:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        # simplified syntax for passing positional and keyword argument
 | 
			
		||||
        # injections only:
 | 
			
		||||
        factory = Factory(SomeClass, 'arg1', 'arg2', arg3=3, arg4=4)
 | 
			
		||||
 | 
			
		||||
        # extended (full) syntax for passing any type of injections:
 | 
			
		||||
        factory = Factory(SomeClass,
 | 
			
		||||
                          injections.Arg(1),
 | 
			
		||||
                          injections.Arg(2),
 | 
			
		||||
                          injections.KwArg('some_arg', 3),
 | 
			
		||||
                          injections.KwArg('other_arg', 4),
 | 
			
		||||
                          injections.Attribute('some_attribute', 5))
 | 
			
		||||
 | 
			
		||||
    Retrieving of provided instance can be performed via calling
 | 
			
		||||
    :py:class:`Factory` object:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        factory = Factory(SomeClass,
 | 
			
		||||
                          some_arg1=1,
 | 
			
		||||
                          some_arg2=2)
 | 
			
		||||
        some_object = factory()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('provides', 'args', 'kwargs', 'attributes', 'methods')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, provides, *args, **kwargs):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param provides: Class or other callable that provides object
 | 
			
		||||
            for creation.
 | 
			
		||||
        :type provides: type | callable
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of injections.
 | 
			
		||||
        :type args: tuple
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of injections.
 | 
			
		||||
        :type kwargs: dict
 | 
			
		||||
        """
 | 
			
		||||
        if not callable(provides):
 | 
			
		||||
            raise Error('Factory provider expects to get callable, ' +
 | 
			
		||||
                        'got {0} instead'.format(str(provides)))
 | 
			
		||||
        self.provides = provides
 | 
			
		||||
        """Class or other callable that provides object for creation.
 | 
			
		||||
 | 
			
		||||
        :type: type | callable
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.args = _parse_args_injections(args)
 | 
			
		||||
        """Tuple of positional argument injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.kwargs = _parse_kwargs_injections(args, kwargs)
 | 
			
		||||
        """Tuple of keyword argument injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.attributes = tuple(injection
 | 
			
		||||
                                for injection in args
 | 
			
		||||
                                if is_attribute_injection(injection))
 | 
			
		||||
        """Tuple of attribute injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.Attribute`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.methods = tuple(injection
 | 
			
		||||
                             for injection in args
 | 
			
		||||
                             if is_method_injection(injection))
 | 
			
		||||
        """Tuple of method injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.Method`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        super(Factory, self).__init__()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def injections(self):
 | 
			
		||||
        """Read-only tuple of all injections.
 | 
			
		||||
 | 
			
		||||
        :rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
 | 
			
		||||
        """
 | 
			
		||||
        return self.args + self.kwargs + self.attributes + self.methods
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of context positional arguments.
 | 
			
		||||
        :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of context keyword arguments.
 | 
			
		||||
        :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        instance = self.provides(*_get_injectable_args(args, self.args),
 | 
			
		||||
                                 **_get_injectable_kwargs(kwargs, self.kwargs))
 | 
			
		||||
        for attribute in self.attributes:
 | 
			
		||||
| 
						 | 
				
			
			@ -131,48 +301,145 @@ class Factory(Provider):
 | 
			
		|||
 | 
			
		||||
        return instance
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def injections(self):
 | 
			
		||||
        """Return tuple of all injections."""
 | 
			
		||||
        return self.args + self.kwargs + self.attributes + self.methods
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Singleton(Provider):
 | 
			
		||||
    """Singleton provider.
 | 
			
		||||
    """:py:class:`Singleton` provider returns same instance on every call.
 | 
			
		||||
 | 
			
		||||
    :py:class:`Singleton` provider creates instance once and return it on every
 | 
			
		||||
    call. :py:class:`Singleton` uses :py:class:`Factory` for creation of
 | 
			
		||||
    instance, so, please follow :py:class:`Factory` documentation to go inside
 | 
			
		||||
    with injections syntax.
 | 
			
		||||
 | 
			
		||||
    :py:class:`Singleton` is thread-safe and could be used in multithreading
 | 
			
		||||
    environment without any negative impact.
 | 
			
		||||
 | 
			
		||||
    Retrieving of provided instance can be performed via calling
 | 
			
		||||
    :py:class:`Singleton` object:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        singleton = Singleton(SomeClass,
 | 
			
		||||
                              some_arg1=1,
 | 
			
		||||
                              some_arg2=2)
 | 
			
		||||
        some_object = singleton()
 | 
			
		||||
 | 
			
		||||
    Singleton provider will create instance once and return it on every call.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('instance', 'factory')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, provides, *args, **kwargs):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param provides: Class or other callable that provides object
 | 
			
		||||
            for creation.
 | 
			
		||||
        :type provides: type | callable
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of injections.
 | 
			
		||||
        :type args: tuple
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of injections.
 | 
			
		||||
        :type kwargs: dict
 | 
			
		||||
        """
 | 
			
		||||
        self.instance = None
 | 
			
		||||
        """Read-only reference to singleton's instance.
 | 
			
		||||
 | 
			
		||||
        :type: object
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.factory = Factory(provides, *args, **kwargs)
 | 
			
		||||
        """Singleton's factory object.
 | 
			
		||||
 | 
			
		||||
        :type: :py:class:`Factory`
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        super(Singleton, self).__init__()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def provides(self):
 | 
			
		||||
        """Class or other callable that provides object for creation.
 | 
			
		||||
 | 
			
		||||
        :type: type | callable
 | 
			
		||||
        """
 | 
			
		||||
        return self.factory.provides
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def args(self):
 | 
			
		||||
        """Tuple of positional argument injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
			
		||||
        """
 | 
			
		||||
        return self.factory.args
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def kwargs(self):
 | 
			
		||||
        """Tuple of keyword argument injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
			
		||||
        """
 | 
			
		||||
        return self.factory.kwargs
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def attributes(self):
 | 
			
		||||
        """Tuple of attribute injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.Attribute`]
 | 
			
		||||
        """
 | 
			
		||||
        return self.factory.attributes
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def methods(self):
 | 
			
		||||
        """Tuple of method injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.Method`]
 | 
			
		||||
        """
 | 
			
		||||
        return self.factory.methods
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def injections(self):
 | 
			
		||||
        """Read-only tuple of all injections.
 | 
			
		||||
 | 
			
		||||
        :rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
 | 
			
		||||
        """
 | 
			
		||||
        return self.factory.injections
 | 
			
		||||
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        """Reset cached instance, if any.
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        self.instance = None
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of context positional arguments.
 | 
			
		||||
        :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of context keyword arguments.
 | 
			
		||||
        :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        with GLOBAL_LOCK:
 | 
			
		||||
            if not self.instance:
 | 
			
		||||
                self.instance = self.factory(*args, **kwargs)
 | 
			
		||||
        return self.instance
 | 
			
		||||
 | 
			
		||||
    def reset(self):
 | 
			
		||||
        """Reset instance."""
 | 
			
		||||
        self.instance = None
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def injections(self):
 | 
			
		||||
        """Return tuple of all injections."""
 | 
			
		||||
        return self.factory.injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ExternalDependency(Provider):
 | 
			
		||||
    """External dependency provider.
 | 
			
		||||
    """:py:class:`ExternalDependency` provider describes dependency interface.
 | 
			
		||||
 | 
			
		||||
    Those provider is used when dependency obviously have to be overridden by
 | 
			
		||||
    the client's code, but it's interface is known.
 | 
			
		||||
    This provider is used for description of dependency interface. That might
 | 
			
		||||
    be useful when dependency could be provided in the client's code only,
 | 
			
		||||
    but it's interface is known. Such situations could happen when required
 | 
			
		||||
    dependency has non-determenistic list of dependencies itself.
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        database_provider = ExternalDependency(sqlite3.dbapi2.Connection)
 | 
			
		||||
        database_provider.override(Factory(sqlite3.connect, ':memory:'))
 | 
			
		||||
 | 
			
		||||
        database = database_provider()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('instance_of',)
 | 
			
		||||
| 
						 | 
				
			
			@ -183,10 +450,25 @@ class ExternalDependency(Provider):
 | 
			
		|||
            raise Error('ExternalDependency provider expects to get class, ' +
 | 
			
		||||
                        'got {0} instead'.format(str(instance_of)))
 | 
			
		||||
        self.instance_of = instance_of
 | 
			
		||||
        """Class of required dependency.
 | 
			
		||||
 | 
			
		||||
        :type: type
 | 
			
		||||
        """
 | 
			
		||||
        super(ExternalDependency, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def __call__(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of context positional arguments.
 | 
			
		||||
        :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of context keyword arguments.
 | 
			
		||||
        :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        if not self.is_overridden:
 | 
			
		||||
            raise Error('Dependency is not defined')
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -199,97 +481,207 @@ class ExternalDependency(Provider):
 | 
			
		|||
        return instance
 | 
			
		||||
 | 
			
		||||
    def provided_by(self, provider):
 | 
			
		||||
        """Set external dependency provider."""
 | 
			
		||||
        """Set external dependency provider.
 | 
			
		||||
 | 
			
		||||
        :param provider: Provider that provides required dependency.
 | 
			
		||||
        :type provider: :py:class:`Provider`
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        return self.override(provider)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class StaticProvider(Provider):
 | 
			
		||||
    """Static provider.
 | 
			
		||||
    """:py:class:`StaticProvider` returns provided instance "as is".
 | 
			
		||||
 | 
			
		||||
    Static provider is base implementation that provides exactly the same as
 | 
			
		||||
    it got on input.
 | 
			
		||||
    :py:class:`StaticProvider` is base implementation that provides exactly
 | 
			
		||||
    the same as it got on input.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('provides',)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, provides):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param provides: Value that have to be provided.
 | 
			
		||||
        :type provides: object
 | 
			
		||||
        """
 | 
			
		||||
        self.provides = provides
 | 
			
		||||
        """Value that have to be provided.
 | 
			
		||||
 | 
			
		||||
        :type: object
 | 
			
		||||
        """
 | 
			
		||||
        super(StaticProvider, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of context positional arguments.
 | 
			
		||||
        :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of context keyword arguments.
 | 
			
		||||
        :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        return self.provides
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Class(StaticProvider):
 | 
			
		||||
    """Class provider provides class."""
 | 
			
		||||
    """:py:class:`Class` returns provided class "as is".
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        cls_provider = Class(object)
 | 
			
		||||
        object_cls = cls_provider()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Object(StaticProvider):
 | 
			
		||||
    """Object provider provides object."""
 | 
			
		||||
    """:py:class:`Object` returns provided object "as is".
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        object_provider = Object(object())
 | 
			
		||||
        object_instance = object_provider()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Function(StaticProvider):
 | 
			
		||||
    """Function provider provides function."""
 | 
			
		||||
    """:py:class:`Function` returns provided function "as is".
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        function_provider = Function(len)
 | 
			
		||||
        len_function = function_provider()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Value(StaticProvider):
 | 
			
		||||
    """Value provider provides value."""
 | 
			
		||||
    """:py:class:`Value` returns provided value "as is".
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        value_provider = Value(31337)
 | 
			
		||||
        value = value_provider()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Callable(Provider):
 | 
			
		||||
    """Callable provider.
 | 
			
		||||
    """:py:class:`Callable` provider calls wrapped callable on every call.
 | 
			
		||||
 | 
			
		||||
    Callable provider provides callable that is called on every provider call
 | 
			
		||||
    with some predefined dependency injections.
 | 
			
		||||
    :py:class:`Callable` provider provides callable that is called on every
 | 
			
		||||
    provider call with some predefined dependency injections.
 | 
			
		||||
 | 
			
		||||
    :py:class:`Callable` syntax of passing injections is the same like
 | 
			
		||||
    :py:class:`Factory` one:
 | 
			
		||||
 | 
			
		||||
    .. code-block:: python
 | 
			
		||||
 | 
			
		||||
        some_function = Callable(some_function, 'arg1', 'arg2', arg3=3, arg4=4)
 | 
			
		||||
        result = some_function()
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('callback', 'args', 'kwargs')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, callback, *args, **kwargs):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param callback: Wrapped callable.
 | 
			
		||||
        :type callback: callable
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of injections.
 | 
			
		||||
        :type args: tuple
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of injections.
 | 
			
		||||
        :type kwargs: dict
 | 
			
		||||
        """
 | 
			
		||||
        if not callable(callback):
 | 
			
		||||
            raise Error('Callable expected, got {0}'.format(str(callback)))
 | 
			
		||||
        self.callback = callback
 | 
			
		||||
        self.args = _parse_args_injections(args)
 | 
			
		||||
        self.kwargs = _parse_kwargs_injections(args, kwargs)
 | 
			
		||||
        super(Callable, self).__init__()
 | 
			
		||||
        """Wrapped callable.
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        return self.callback(*_get_injectable_args(args, self.args),
 | 
			
		||||
                             **_get_injectable_kwargs(kwargs, self.kwargs))
 | 
			
		||||
        :type: callable
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.args = _parse_args_injections(args)
 | 
			
		||||
        """Tuple of positional argument injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.kwargs = _parse_kwargs_injections(args, kwargs)
 | 
			
		||||
        """Tuple of keyword argument injections.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        super(Callable, self).__init__()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def injections(self):
 | 
			
		||||
        """Return tuple of all injections."""
 | 
			
		||||
        """Read-only tuple of all injections.
 | 
			
		||||
 | 
			
		||||
        :rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
 | 
			
		||||
        """
 | 
			
		||||
        return self.args + self.kwargs
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of context positional arguments.
 | 
			
		||||
        :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of context keyword arguments.
 | 
			
		||||
        :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        return self.callback(*_get_injectable_args(args, self.args),
 | 
			
		||||
                             **_get_injectable_kwargs(kwargs, self.kwargs))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Config(Provider):
 | 
			
		||||
    """Config provider.
 | 
			
		||||
    """:py:class:`Config` provider provide dict values.
 | 
			
		||||
 | 
			
		||||
    Config provider provides dict values. Also config provider creates
 | 
			
		||||
    child config objects for all undefined attribute calls. It makes possible
 | 
			
		||||
    to create deferred config value provider.
 | 
			
		||||
    :py:class:`Config` provider creates :py:class:`ChildConfig` objects for all
 | 
			
		||||
    undefined attribute calls. It makes possible to create deferred config
 | 
			
		||||
    value providers. It might be useful in cases where it is needed to
 | 
			
		||||
    define / pass some configuration in declarative manner, while
 | 
			
		||||
    configuration values will be loaded / updated in application's runtime.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('value',)
 | 
			
		||||
 | 
			
		||||
    def __init__(self, value=None):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param value: Configuration dictionary.
 | 
			
		||||
        :type value: dict[str, object]
 | 
			
		||||
        """
 | 
			
		||||
        if not value:
 | 
			
		||||
            value = dict()
 | 
			
		||||
        self.value = value
 | 
			
		||||
        super(Config, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, item):
 | 
			
		||||
        """Return instance of deferred config."""
 | 
			
		||||
        """Return instance of deferred config.
 | 
			
		||||
 | 
			
		||||
        :param item: Name of configuration option or section.
 | 
			
		||||
        :type item: str
 | 
			
		||||
 | 
			
		||||
        :rtype: :py:class:`ChildConfig`
 | 
			
		||||
        """
 | 
			
		||||
        return ChildConfig(parents=(item,), root_config=self)
 | 
			
		||||
 | 
			
		||||
    def _provide(self, paths=None):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param paths: Tuple of pieces of configuration option / section path.
 | 
			
		||||
        :type args: tuple[str]
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        value = self.value
 | 
			
		||||
        if paths:
 | 
			
		||||
            for path in paths:
 | 
			
		||||
| 
						 | 
				
			
			@ -301,30 +693,69 @@ class Config(Provider):
 | 
			
		|||
        return value
 | 
			
		||||
 | 
			
		||||
    def update_from(self, value):
 | 
			
		||||
        """Update current value from another one."""
 | 
			
		||||
        """Update current value from another one.
 | 
			
		||||
 | 
			
		||||
        :param value: Configuration dictionary.
 | 
			
		||||
        :type value: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :rtype: None
 | 
			
		||||
        """
 | 
			
		||||
        self.value.update(value)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ChildConfig(Provider):
 | 
			
		||||
    """Child config provider.
 | 
			
		||||
    """:py:class:`ChildConfig` provider provides value from :py:class:`Config`.
 | 
			
		||||
 | 
			
		||||
    Child config provide an value from the root config object according to
 | 
			
		||||
    the current path in the config tree.
 | 
			
		||||
    :py:class:`ChildConfig` provides value from the root config object
 | 
			
		||||
    according to the current path in the config tree.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('parents', 'root_config')
 | 
			
		||||
 | 
			
		||||
    def __init__(self, parents, root_config):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param parents: Tuple of pieces of configuration option / section
 | 
			
		||||
            parent path.
 | 
			
		||||
        :type parents: tuple[str]
 | 
			
		||||
 | 
			
		||||
        :param root_config: Root configuration object.
 | 
			
		||||
        :type root_config: :py:class:`Config`
 | 
			
		||||
        """
 | 
			
		||||
        self.parents = parents
 | 
			
		||||
        """Tuple of pieces of configuration option / section parent path.
 | 
			
		||||
 | 
			
		||||
        :type: tuple[str]
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        self.root_config = root_config
 | 
			
		||||
        """Root configuration object.
 | 
			
		||||
 | 
			
		||||
        :type: :py:class:`Config`
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        super(ChildConfig, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def __getattr__(self, item):
 | 
			
		||||
        """Return instance of deferred config."""
 | 
			
		||||
        """Return instance of deferred config.
 | 
			
		||||
 | 
			
		||||
        :param item: Name of configuration option or section.
 | 
			
		||||
        :type item: str
 | 
			
		||||
 | 
			
		||||
        :rtype: :py:class:`ChildConfig`
 | 
			
		||||
        """
 | 
			
		||||
        return ChildConfig(parents=self.parents + (item,),
 | 
			
		||||
                           root_config=self.root_config)
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param args: Tuple of context positional arguments.
 | 
			
		||||
        :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
        :param kwargs: Dictionary of context keyword arguments.
 | 
			
		||||
        :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        return self.root_config(self.parents)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,10 +8,20 @@ from .errors import Error
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
GLOBAL_LOCK = threading.RLock()
 | 
			
		||||
"""Dependency injector global reentrant lock.
 | 
			
		||||
 | 
			
		||||
:type: :py:class:`threading.RLock`
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_provider(instance):
 | 
			
		||||
    """Check if instance is provider instance."""
 | 
			
		||||
    """Check if instance is provider instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (not isinstance(instance, six.class_types) and
 | 
			
		||||
            hasattr(instance, '__IS_PROVIDER__') and
 | 
			
		||||
            getattr(instance, '__IS_PROVIDER__') is True)
 | 
			
		||||
| 
						 | 
				
			
			@ -20,7 +30,13 @@ def is_provider(instance):
 | 
			
		|||
def ensure_is_provider(instance):
 | 
			
		||||
    """Check if instance is provider instance and return it.
 | 
			
		||||
 | 
			
		||||
    :raise: Error if provided instance is not provider.
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :raise: :py:exc:`dependency_injector.errors.Error` if provided instance is
 | 
			
		||||
            not provider.
 | 
			
		||||
 | 
			
		||||
    :rtype: :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
    """
 | 
			
		||||
    if not is_provider(instance):
 | 
			
		||||
        raise Error('Expected provider instance, '
 | 
			
		||||
| 
						 | 
				
			
			@ -29,14 +45,29 @@ def ensure_is_provider(instance):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def is_injection(instance):
 | 
			
		||||
    """Check if instance is injection instance."""
 | 
			
		||||
    """Check if instance is injection instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (not isinstance(instance, six.class_types) and
 | 
			
		||||
            hasattr(instance, '__IS_INJECTION__') and
 | 
			
		||||
            getattr(instance, '__IS_INJECTION__') is True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def ensure_is_injection(instance):
 | 
			
		||||
    """Check if instance is injection instance, otherwise raise and error."""
 | 
			
		||||
    """Check if instance is injection instance and return it.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :raise: :py:exc:`dependency_injector.errors.Error` if provided instance is
 | 
			
		||||
            not injection.
 | 
			
		||||
 | 
			
		||||
    :rtype: :py:class:`dependency_injector.injections.Injection`
 | 
			
		||||
    """
 | 
			
		||||
    if not is_injection(instance):
 | 
			
		||||
        raise Error('Expected injection instance, '
 | 
			
		||||
                    'got {0}'.format(str(instance)))
 | 
			
		||||
| 
						 | 
				
			
			@ -44,51 +75,99 @@ def ensure_is_injection(instance):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def is_arg_injection(instance):
 | 
			
		||||
    """Check if instance is positional argument injection instance."""
 | 
			
		||||
    """Check if instance is positional argument injection instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (not isinstance(instance, six.class_types) and
 | 
			
		||||
            hasattr(instance, '__IS_ARG_INJECTION__') and
 | 
			
		||||
            getattr(instance, '__IS_ARG_INJECTION__', False) is True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_kwarg_injection(instance):
 | 
			
		||||
    """Check if instance is keyword argument injection instance."""
 | 
			
		||||
    """Check if instance is keyword argument injection instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (not isinstance(instance, six.class_types) and
 | 
			
		||||
            hasattr(instance, '__IS_KWARG_INJECTION__') and
 | 
			
		||||
            getattr(instance, '__IS_KWARG_INJECTION__', False) is True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_attribute_injection(instance):
 | 
			
		||||
    """Check if instance is attribute injection instance."""
 | 
			
		||||
    """Check if instance is attribute injection instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (not isinstance(instance, six.class_types) and
 | 
			
		||||
            hasattr(instance, '__IS_ATTRIBUTE_INJECTION__') and
 | 
			
		||||
            getattr(instance, '__IS_ATTRIBUTE_INJECTION__', False) is True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_method_injection(instance):
 | 
			
		||||
    """Check if instance is method injection instance."""
 | 
			
		||||
    """Check if instance is method injection instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (not isinstance(instance, six.class_types) and
 | 
			
		||||
            hasattr(instance, '__IS_METHOD_INJECTION__') and
 | 
			
		||||
            getattr(instance, '__IS_METHOD_INJECTION__', False) is True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_catalog(instance):
 | 
			
		||||
    """Check if instance is catalog instance."""
 | 
			
		||||
    """Check if instance is catalog instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (hasattr(instance, '__IS_CATALOG__') and
 | 
			
		||||
            getattr(instance, '__IS_CATALOG__', False) is True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_dynamic_catalog(instance):
 | 
			
		||||
    """Check if instance is dynamic catalog instance."""
 | 
			
		||||
    """Check if instance is dynamic catalog instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (not isinstance(instance, six.class_types) and is_catalog(instance))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_declarative_catalog(instance):
 | 
			
		||||
    """Check if instance is declarative catalog instance."""
 | 
			
		||||
    """Check if instance is declarative catalog instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (isinstance(instance, six.class_types) and is_catalog(instance))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def is_catalog_bundle(instance):
 | 
			
		||||
    """Check if instance is catalog bundle instance."""
 | 
			
		||||
    """Check if instance is catalog bundle instance.
 | 
			
		||||
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :rtype: bool
 | 
			
		||||
    """
 | 
			
		||||
    return (not isinstance(instance, six.class_types) and
 | 
			
		||||
            hasattr(instance, '__IS_CATALOG_BUNDLE__') and
 | 
			
		||||
            getattr(instance, '__IS_CATALOG_BUNDLE__', False) is True)
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +176,13 @@ def is_catalog_bundle(instance):
 | 
			
		|||
def ensure_is_catalog_bundle(instance):
 | 
			
		||||
    """Check if instance is catalog bundle instance and return it.
 | 
			
		||||
 | 
			
		||||
    :raise: Error if provided instance is not catalog bundle.
 | 
			
		||||
    :param instance: Instance to be checked.
 | 
			
		||||
    :type instance: object
 | 
			
		||||
 | 
			
		||||
    :raise: :py:exc:`dependency_injector.errors.Error` if provided instance
 | 
			
		||||
            is not catalog bundle.
 | 
			
		||||
 | 
			
		||||
    :rtype: :py:class:`dependency_injector.catalogs.CatalogBundle`
 | 
			
		||||
    """
 | 
			
		||||
    if not is_catalog_bundle(instance):
 | 
			
		||||
        raise Error('Expected catalog bundle instance, '
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,28 +7,35 @@ Current section of documentation describes advanced usage of
 | 
			
		|||
@inject decorator
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
``@di.inject()`` decorator can be used for making *inline* dependency 
 | 
			
		||||
.. module:: dependency_injector.injections
 | 
			
		||||
 | 
			
		||||
:py:func:`inject` decorator is a part of 
 | 
			
		||||
:py:mod:`dependency_injector.injections` module.
 | 
			
		||||
 | 
			
		||||
:py:func:`inject` decorator can be used for making *inline* dependency 
 | 
			
		||||
injections.  It *patches* decorated callable in such way that dependency 
 | 
			
		||||
injection will be done during every call of decorated callable.
 | 
			
		||||
 | 
			
		||||
``di.inject()`` takes a various number of positional and keyword arguments 
 | 
			
		||||
:py:func:`inject` takes a various number of positional and keyword arguments 
 | 
			
		||||
that are used as decorated callable injections. Every time, when 
 | 
			
		||||
``di.inject()`` is called, positional and keyword argument injections would be 
 | 
			
		||||
passed as an callable arguments.
 | 
			
		||||
:py:func:`inject` is called, positional and keyword argument injections would 
 | 
			
		||||
be passed as an callable arguments.
 | 
			
		||||
 | 
			
		||||
Such behaviour is very similar to the standard Python ``functools.partial`` 
 | 
			
		||||
object, except of one thing: all injectable values are provided 
 | 
			
		||||
*"as is"*, except of providers (subclasses of ``di.Provider``). Providers 
 | 
			
		||||
*"as is"*, except of providers (subclasses of 
 | 
			
		||||
:py:class:`dependency_injector.providers.Provider`). Providers 
 | 
			
		||||
will be called every time, when injection needs to be done. For example, 
 | 
			
		||||
if injectable value of injection is a ``di.Factory``, it will provide new one 
 | 
			
		||||
if injectable value of injection is a 
 | 
			
		||||
:py:class:`dependency_injector.providers.Factory`, it will provide new one 
 | 
			
		||||
instance (as a result of its call) every time, when injection needs to be done.
 | 
			
		||||
 | 
			
		||||
``di.inject()`` behaviour with context positional and keyword arguments is 
 | 
			
		||||
:py:func:`inject` behaviour with context positional and keyword arguments is 
 | 
			
		||||
very like a standard Python ``functools.partial``:
 | 
			
		||||
 | 
			
		||||
- Positional context arguments will be appended after ``di.inject()`` 
 | 
			
		||||
- Positional context arguments will be appended after :py:func:`inject` 
 | 
			
		||||
  positional injections.
 | 
			
		||||
- Keyword context arguments have priority on ``di.inject()`` keyword 
 | 
			
		||||
- Keyword context arguments have priority on :py:func:`inject` keyword 
 | 
			
		||||
  injections and will be merged over them.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +43,7 @@ Example:
 | 
			
		|||
.. literalinclude:: ../../examples/advanced_usage/inject_simple.py
 | 
			
		||||
   :language: python
 | 
			
		||||
 | 
			
		||||
Example of usage ``@di.inject()`` decorator with Flask:
 | 
			
		||||
Example of usage :py:func:`inject` decorator with Flask:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/advanced_usage/inject_flask.py
 | 
			
		||||
   :language: python
 | 
			
		||||
| 
						 | 
				
			
			@ -45,11 +52,12 @@ Example of usage ``@di.inject()`` decorator with Flask:
 | 
			
		|||
@inject decorator with classes
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``@di.inject()`` could be applied for classes. In such case, it will look for 
 | 
			
		||||
:py:func:`inject` could be applied for classes. In such case, it will look for 
 | 
			
		||||
class ``__init__()`` method and pass injection to it. If decorated class has 
 | 
			
		||||
no ``__init__()`` method, appropriate ``di.Error`` will be raised.
 | 
			
		||||
no ``__init__()`` method, appropriate 
 | 
			
		||||
:py:exc:`dependency_injector.errors.Error` will be raised.
 | 
			
		||||
 | 
			
		||||
Example of usage ``@di.inject()`` with Flask class-based view:
 | 
			
		||||
Example of usage :py:func:`inject` with Flask class-based view:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/advanced_usage/inject_flask_class_based.py
 | 
			
		||||
   :language: python
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								docs/api/catalogs.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
``dependency_injector.catalogs``
 | 
			
		||||
--------------------------------
 | 
			
		||||
 | 
			
		||||
.. automodule:: dependency_injector.catalogs
 | 
			
		||||
   :members:
 | 
			
		||||
   :member-order: bysource
 | 
			
		||||
   :special-members:
 | 
			
		||||
							
								
								
									
										6
									
								
								docs/api/errors.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
``dependency_injector.errors``
 | 
			
		||||
------------------------------
 | 
			
		||||
 | 
			
		||||
.. automodule:: dependency_injector.errors
 | 
			
		||||
   :members:
 | 
			
		||||
   :member-order: bysource
 | 
			
		||||
							
								
								
									
										12
									
								
								docs/api/index.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
API Documentation
 | 
			
		||||
=================
 | 
			
		||||
 | 
			
		||||
..  toctree::
 | 
			
		||||
    :maxdepth: 2
 | 
			
		||||
 | 
			
		||||
    top_level
 | 
			
		||||
    providers
 | 
			
		||||
    injections
 | 
			
		||||
    catalogs
 | 
			
		||||
    utils
 | 
			
		||||
    errors
 | 
			
		||||
							
								
								
									
										7
									
								
								docs/api/injections.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
``dependency_injector.injections``
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
.. automodule:: dependency_injector.injections
 | 
			
		||||
   :members:
 | 
			
		||||
   :member-order: bysource
 | 
			
		||||
   :inherited-members:
 | 
			
		||||
							
								
								
									
										7
									
								
								docs/api/providers.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
``dependency_injector.providers``
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
.. automodule:: dependency_injector.providers
 | 
			
		||||
   :members:
 | 
			
		||||
   :member-order: bysource
 | 
			
		||||
   :inherited-members:
 | 
			
		||||
							
								
								
									
										5
									
								
								docs/api/top_level.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
``dependency_injector``
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
.. automodule:: dependency_injector
 | 
			
		||||
    :members: VERSION
 | 
			
		||||
							
								
								
									
										6
									
								
								docs/api/utils.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
``dependency_injector.utils``
 | 
			
		||||
-----------------------------
 | 
			
		||||
 | 
			
		||||
.. automodule:: dependency_injector.utils
 | 
			
		||||
   :members:
 | 
			
		||||
   :member-order: bysource
 | 
			
		||||
| 
						 | 
				
			
			@ -1,23 +1,43 @@
 | 
			
		|||
Creating catalog provider bundles
 | 
			
		||||
---------------------------------
 | 
			
		||||
Catalog provider bundles
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
``di.DeclarativeCatalog.Bundle`` is a 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 
 | 
			
		||||
limited scopes that could be passed to different subsystems.
 | 
			
		||||
.. module:: dependency_injector.catalogs
 | 
			
		||||
 | 
			
		||||
``di.DeclarativeCatalog.Bundle`` has exactly the same API as 
 | 
			
		||||
``di.DeclarativeCatalog`` except of the limitations on getting 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.
 | 
			
		||||
 | 
			
		||||
Each ``di.DeclarativeCatalog`` has a reference to its bundle class - 
 | 
			
		||||
``di.DeclarativeCatalog.Bundle``. For example, if some concrete catalog has name 
 | 
			
		||||
``SomeCatalog``, then its bundle class could be reached as 
 | 
			
		||||
``SomeCatalog.Bundle``. 
 | 
			
		||||
: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.
 | 
			
		||||
 | 
			
		||||
``di.DeclarativeCatalog.Bundle`` expects to get the list of its catalog providers
 | 
			
		||||
:py:class:`CatalogBundle` is considered to be dependable on catalogs 
 | 
			
		||||
(:py:class:`DeclarativeCatalog` or :py:class:`DynamicCatalog`) entity by 
 | 
			
		||||
its design.
 | 
			
		||||
 | 
			
		||||
Each catalog (:py:class:`DeclarativeCatalog` or :py:class:`DynamicCatalog`) 
 | 
			
		||||
has a reference to its bundle class - :py:attr:`DeclarativeCatalog.Bundle` 
 | 
			
		||||
(or :py:attr:`DynamicCatalog.Bundle` consequently). For example, subclass of 
 | 
			
		||||
:py:class:`CatalogBundle` for some concrete declarative catalog 
 | 
			
		||||
``SomeCatalog`` could be reached as ``SomeCatalog.Bundle``. 
 | 
			
		||||
 | 
			
		||||
:py:class:`CatalogBundle` expects to get the list of its catalog providers
 | 
			
		||||
as positional arguments and will limit the scope of created bundle to this 
 | 
			
		||||
list. 
 | 
			
		||||
 | 
			
		||||
.. note:: 
 | 
			
		||||
   
 | 
			
		||||
    Some notes about :py:class:`CatalogBundle` design.
 | 
			
		||||
 | 
			
		||||
    Design and syntax of :py:class:`CatalogBundle` was developed with the idea 
 | 
			
		||||
    of keeping full functionalities of type-hinting and introspection of 
 | 
			
		||||
    modern IDE's. This design came from some practical experience of using 
 | 
			
		||||
    :py:class:`CatalogBundle` and considered to be the most comfortable for 
 | 
			
		||||
    developer.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/catalogs/bundles.png
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										61
									
								
								docs/catalogs/declarative.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
Declarative catalogs
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
.. module:: dependency_injector.catalogs
 | 
			
		||||
 | 
			
		||||
:py:class:`DeclarativeCatalog` is a catalog of providers that could be
 | 
			
		||||
defined in declarative manner. It should cover most of the cases when list
 | 
			
		||||
of providers that would be included in catalog is deterministic (catalog
 | 
			
		||||
will not change its structure in runtime).
 | 
			
		||||
 | 
			
		||||
Declarative catalogs have to extend base declarative catalog class - 
 | 
			
		||||
:py:class:`dependency_injector.catalogs.DeclarativeCatalog`.
 | 
			
		||||
 | 
			
		||||
Declarative catalog's providers have to be defined like catalog's class 
 | 
			
		||||
attributes. Every provider in catalog has name. This name should follow 
 | 
			
		||||
``some_provider`` convention, that is standard naming convention for 
 | 
			
		||||
attribute names in Python.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    Declarative catalogs have several features that could be useful 
 | 
			
		||||
    for some kind of operations on catalog's providers, please visit API 
 | 
			
		||||
    documentation for getting full list of features - 
 | 
			
		||||
    :py:class:`dependency_injector.catalogs.DeclarativeCatalog`.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    It might be useful to add such 
 | 
			
		||||
    ``""":type: dependency_injector.providers.Provider -> Object1"""`` 
 | 
			
		||||
    docstrings just on the next line after provider's definition.  It will 
 | 
			
		||||
    help code analyzing tools and IDE's to understand that variable above 
 | 
			
		||||
    contains some callable object, that returns particular instance as a 
 | 
			
		||||
    result of its call.
 | 
			
		||||
 | 
			
		||||
Here is an simple example of defining declarative catalog with several 
 | 
			
		||||
factories:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/catalogs/declarative.png
 | 
			
		||||
    :width: 85%
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/declarative.py
 | 
			
		||||
   :language: python
 | 
			
		||||
 | 
			
		||||
Example of declarative catalogs inheritance:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/catalogs/declarative_inheritance.png
 | 
			
		||||
    :width: 100%
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/declarative_inheritance.py
 | 
			
		||||
   :language: python
 | 
			
		||||
 | 
			
		||||
Example of declarative catalog's provider injections:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/catalogs/declarative_injections.png
 | 
			
		||||
    :width: 100%
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/declarative_injections.py
 | 
			
		||||
   :language: python
 | 
			
		||||
							
								
								
									
										29
									
								
								docs/catalogs/dynamic.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
Dynamic catalogs
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
.. module:: dependency_injector.catalogs
 | 
			
		||||
 | 
			
		||||
:py:class:`DynamicCatalog` is a catalog of providers that could be created in 
 | 
			
		||||
application's runtime. It should cover most of the cases when list of 
 | 
			
		||||
providers that would be included in catalog is non-deterministic in terms of 
 | 
			
		||||
apllication code (catalog's structure could be determined just after 
 | 
			
		||||
application will be started and will do some initial work, like parsing list 
 | 
			
		||||
of catalog's providers from the configuration).
 | 
			
		||||
 | 
			
		||||
:py:class:`DeclarativeCatalog` and :py:class:`DynamicCatalog` have 
 | 
			
		||||
100% API parity.
 | 
			
		||||
 | 
			
		||||
Main difference between :py:class:`DeclarativeCatalog` and 
 | 
			
		||||
:py:class:`DynamicCatalog` is that :py:class:`DeclarativeCatalog` acts on 
 | 
			
		||||
class-level, while :py:class:`DynamicCatalog` do the same on 
 | 
			
		||||
instance-level.
 | 
			
		||||
 | 
			
		||||
Here is an simple example of defining dynamic catalog with several factories:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/dynamic.py
 | 
			
		||||
   :language: python
 | 
			
		||||
 | 
			
		||||
Next one example demonstrates creation and runtime filling of dynamic catalog:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/dynamic_runtime_creation.py
 | 
			
		||||
   :language: python
 | 
			
		||||
| 
						 | 
				
			
			@ -16,10 +16,12 @@ Also, for both of these and some other cases, it might be useful to attach
 | 
			
		|||
some init / shutdown functionality or something else, that deals with group 
 | 
			
		||||
of providers.
 | 
			
		||||
 | 
			
		||||
Catalogs module API docs - :py:mod:`dependency_injector.catalogs`.
 | 
			
		||||
 | 
			
		||||
..  toctree::
 | 
			
		||||
    :maxdepth: 2
 | 
			
		||||
 | 
			
		||||
    writing
 | 
			
		||||
    operating
 | 
			
		||||
    declarative
 | 
			
		||||
    dynamic
 | 
			
		||||
    bundles
 | 
			
		||||
    overriding
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,30 +0,0 @@
 | 
			
		|||
Operating with catalogs
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
``di.DeclarativeCatalog`` has several features that could be useful for some 
 | 
			
		||||
kind of operations on catalog's providers:
 | 
			
		||||
 | 
			
		||||
- ``di.DeclarativeCatalog.providers`` is read-only attribute that contains 
 | 
			
		||||
  ``dict`` of all catalog providers, including providers that are inherited 
 | 
			
		||||
  from parent catalogs, where key is the name of provider and value is 
 | 
			
		||||
  provider itself.
 | 
			
		||||
- ``di.DeclarativeCatalog.cls_providers`` is read-only attribute contains 
 | 
			
		||||
  ``dict`` of current catalog providers, where key is the name of provider 
 | 
			
		||||
  and value is provider itself.
 | 
			
		||||
- ``di.DeclarativeCatalog.inherited_providers`` is read-only attribute 
 | 
			
		||||
  contains ``dict`` of all providers that are inherited from parent catalogs, 
 | 
			
		||||
  where key is the name of provider and value is provider itself. 
 | 
			
		||||
- ``di.DeclarativeCatalog.filter(provider_type=di.Provider)`` is a class 
 | 
			
		||||
  method that could be used for filtering catalog providers by provider types 
 | 
			
		||||
  (for example, for getting all ``di.Factory`` providers). 
 | 
			
		||||
  ``di.DeclarativeCatalog.filter()`` method use 
 | 
			
		||||
  ``di.DeclarativeCatalog.providers``.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/catalogs/operating_with_providers.png
 | 
			
		||||
    :width: 100%
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/operating_with_providers.py
 | 
			
		||||
   :language: python
 | 
			
		||||
| 
						 | 
				
			
			@ -1,35 +1,49 @@
 | 
			
		|||
Overriding of catalogs
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
.. module:: dependency_injector.catalogs
 | 
			
		||||
 | 
			
		||||
Catalogs can be overridden by other catalogs. This, actually, means that 
 | 
			
		||||
all of the providers from overriding catalog will override providers with the 
 | 
			
		||||
same names in overridden catalog.
 | 
			
		||||
 | 
			
		||||
There are two ways to override catalog by another catalog:
 | 
			
		||||
There are two ways to override :py:class:`DeclarativeCatalog` with another 
 | 
			
		||||
catalog:
 | 
			
		||||
 | 
			
		||||
- Use ``di.DeclarativeCatalog.override(AnotherCatalog)`` method.
 | 
			
		||||
- Use ``@di.override(AnotherCatalog)`` class decorator.
 | 
			
		||||
- Use :py:meth:`DeclarativeCatalog.override` method.
 | 
			
		||||
- Use :py:func:`override` class decorator.
 | 
			
		||||
 | 
			
		||||
Example of overriding catalog using ``di.DeclarativeCatalog.override()`` 
 | 
			
		||||
Example of overriding catalog using :py:meth:`DeclarativeCatalog.override` 
 | 
			
		||||
method:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/override.py
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/override_declarative.py
 | 
			
		||||
   :language: python
 | 
			
		||||
 | 
			
		||||
Example of overriding catalog using ``@di.override()`` decorator:
 | 
			
		||||
Example of overriding catalog using :py:func:`override` decorator:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/override_decorator.py
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/override_declarative_decorator.py
 | 
			
		||||
   :language: python
 | 
			
		||||
 | 
			
		||||
Also there are several useful methods and properties that help to work with 
 | 
			
		||||
catalog overridings:
 | 
			
		||||
Also there are several useful :py:class:`DeclarativeCatalog`  methods and 
 | 
			
		||||
properties that help to work with catalog overridings:
 | 
			
		||||
 | 
			
		||||
- ``di.DeclarativeCatalog.is_overridden`` - read-only, evaluated in runtime, 
 | 
			
		||||
  property that is set to True if catalog is overridden.
 | 
			
		||||
- ``di.DeclarativeCatalog.last_overriding`` - reference to the last overriding 
 | 
			
		||||
  catalog, if any.
 | 
			
		||||
- ``di.DeclarativeCatalog.overridden_by`` - tuple of all overriding catalogs.
 | 
			
		||||
- ``di.DeclarativeCatalog.reset_last_overriding()`` - reset last overriding 
 | 
			
		||||
  catalog.
 | 
			
		||||
- ``di.DeclarativeCatalog.reset_override()`` - reset all overridings for all 
 | 
			
		||||
  catalog providers. 
 | 
			
		||||
- :py:attr:`DeclarativeCatalog.is_overridden` - read-only property that is set 
 | 
			
		||||
  to ``True`` if catalog is overridden.
 | 
			
		||||
- :py:attr:`DeclarativeCatalog.last_overriding` - read-only reference to 
 | 
			
		||||
  the last overriding catalog, if any.
 | 
			
		||||
- :py:attr:`DeclarativeCatalog.overridden_by` - tuple of all overriding 
 | 
			
		||||
  catalogs.
 | 
			
		||||
- :py:meth:`DeclarativeCatalog.reset_last_overriding()` - reset last 
 | 
			
		||||
  overriding catalog.
 | 
			
		||||
- :py:meth:`DeclarativeCatalog.reset_override()` - reset all overridings for 
 | 
			
		||||
  all catalog providers. 
 | 
			
		||||
 | 
			
		||||
:py:class:`DynamicCatalog` has exactly the same functionality, except of 
 | 
			
		||||
:py:func:`override` decorator. Also :py:class:`DynamicCatalog` can override 
 | 
			
		||||
:py:class:`DeclarativeCatalog` and vise versa.
 | 
			
		||||
 | 
			
		||||
Example of overriding :py:class:`DeclarativeCatalog` by 
 | 
			
		||||
:py:class:`DynamicCatalog`:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/override_declarative_by_dynamic.py
 | 
			
		||||
   :language: python
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,25 +0,0 @@
 | 
			
		|||
Writing catalogs
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
Catalogs have to extend base catalog class ``di.DeclarativeCatalog``.
 | 
			
		||||
 | 
			
		||||
Providers have to be defined like catalog's attributes. Every provider in
 | 
			
		||||
catalog has name. This name should follow ``some_provider`` convention, 
 | 
			
		||||
that is standard naming convention for attribute names in Python.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    It might be useful to add such ``""":type: di.Provider -> Object1"""`` 
 | 
			
		||||
    docstrings just on the next line after provider's definition.  It will 
 | 
			
		||||
    help code analyzing tools and IDE's to understand that variable above 
 | 
			
		||||
    contains some callable object, that returns particular instance as a 
 | 
			
		||||
    result of its call.
 | 
			
		||||
 | 
			
		||||
Here is an simple example of catalog with several factories:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/catalogs/writing_catalogs.png
 | 
			
		||||
    :width: 85%
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/catalogs/writing_catalogs.py
 | 
			
		||||
   :language: python
 | 
			
		||||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ import re
 | 
			
		|||
# Add any Sphinx extension module names here, as strings. They can be
 | 
			
		||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 | 
			
		||||
# ones.
 | 
			
		||||
extensions = []
 | 
			
		||||
extensions = ['sphinx.ext.autodoc']
 | 
			
		||||
 | 
			
		||||
# Add any paths that contain templates here, relative to this directory.
 | 
			
		||||
templates_path = ['_templates']
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
		 Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 295 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/catalogs/declarative.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 49 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/catalogs/declarative_inheritance.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 78 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/catalogs/declarative_injections.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 231 KiB  | 
| 
		 Before Width: | Height: | Size: 52 KiB  | 
| 
		 Before Width: | Height: | Size: 25 KiB  | 
| 
		 Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 29 KiB  | 
| 
		 Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 82 KiB  | 
| 
		 Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 36 KiB  | 
| 
		 Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 90 KiB  | 
| 
		 Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 19 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/providers/factory_attribute_injection.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 66 KiB  | 
| 
		 Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 66 KiB  | 
| 
		 Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 47 KiB  | 
| 
		 Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 40 KiB  | 
| 
		 Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 68 KiB  | 
| 
		 Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 72 KiB  | 
| 
		 Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 36 KiB  | 
| 
		 Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 78 KiB  | 
| 
		 Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 25 KiB  | 
| 
		 Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 25 KiB  | 
| 
		 Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 26 KiB  | 
| 
						 | 
				
			
			@ -55,5 +55,6 @@ Contents
 | 
			
		|||
    providers/index
 | 
			
		||||
    catalogs/index
 | 
			
		||||
    advanced_usage/index
 | 
			
		||||
    api/index
 | 
			
		||||
    main/feedback
 | 
			
		||||
    main/changelog
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,13 +9,31 @@ follows `Semantic versioning`_
 | 
			
		|||
 | 
			
		||||
Development version
 | 
			
		||||
-------------------
 | 
			
		||||
- Rename ``di.AbstractCatalog`` to ``di.DeclarativeCatalog`` 
 | 
			
		||||
- No features.
 | 
			
		||||
 | 
			
		||||
0.11.0
 | 
			
		||||
------
 | 
			
		||||
- Rename ``AbstractCatalog`` to ``DeclarativeCatalog`` 
 | 
			
		||||
  (with backward compatibility).
 | 
			
		||||
- Rename ``catalog`` module to ``catalogs`` with backward compatibility.
 | 
			
		||||
- Implement dynamic binding of providers for ``DeclarativeCatalog``.
 | 
			
		||||
- Add ``DynamicCatalog``.
 | 
			
		||||
- Change restrictions for providers-to-catalogs bindings - provider could be 
 | 
			
		||||
  bound to several catalogs with different names.
 | 
			
		||||
- Restrict overriding of providers by themselves.
 | 
			
		||||
- Restrict overriding of catalogs by themselves.
 | 
			
		||||
- Make ``DeclarativeCatalog.last_overriding`` attribute to be ``None`` by 
 | 
			
		||||
  default.
 | 
			
		||||
- Make ``Provider.last_overriding`` attribute to be ``None`` by 
 | 
			
		||||
  default.
 | 
			
		||||
- Refactor catalogs and providers modules.
 | 
			
		||||
- Add API documentation
 | 
			
		||||
- Improve user's guides and examples.
 | 
			
		||||
 | 
			
		||||
0.10.5
 | 
			
		||||
------
 | 
			
		||||
- Add more representable implementation for ``di.AbstractCatalog`` and 
 | 
			
		||||
  ``di.AbstractCatalog.Bundle``.
 | 
			
		||||
- Add more representable implementation for ``AbstractCatalog`` and 
 | 
			
		||||
  ``AbstractCatalog.Bundle``.
 | 
			
		||||
 | 
			
		||||
0.10.4
 | 
			
		||||
------
 | 
			
		||||
| 
						 | 
				
			
			@ -35,22 +53,22 @@ Development version
 | 
			
		|||
 | 
			
		||||
0.10.0
 | 
			
		||||
------
 | 
			
		||||
- Add functionality for creating ``di.AbstractCatalog`` provider bundles.
 | 
			
		||||
- Improve ``di.AbstractCatalog`` inheritance.
 | 
			
		||||
- Improve ``di.AbstractCatalog`` overriding.
 | 
			
		||||
- Add functionality for creating ``AbstractCatalog`` provider bundles.
 | 
			
		||||
- Improve ``AbstractCatalog`` inheritance.
 | 
			
		||||
- Improve ``AbstractCatalog`` overriding.
 | 
			
		||||
- Add images for catalog "Writing catalogs" and "Operating with catalogs" 
 | 
			
		||||
  examples.
 | 
			
		||||
- Add functionality for using positional argument injections with 
 | 
			
		||||
  ``di.Factory``, ``di.Singleton``, ``di.Callable`` providers and 
 | 
			
		||||
  ``di.inject`` decorator.
 | 
			
		||||
- Add functionality for decorating classes with ``@di.inject``.
 | 
			
		||||
- Add ``di.Singleton.injections`` attribute that represents a tuple of all 
 | 
			
		||||
  ``di.Singleton`` injections (including args, kwargs, attributes and methods).
 | 
			
		||||
- Add ``di.Callable.injections`` attribute that represents a tuple of all 
 | 
			
		||||
  ``di.Callable`` injections (including args and kwargs).
 | 
			
		||||
- Add optimization for ``di.Injection.value`` property that will compute 
 | 
			
		||||
  ``Factory``, ``Singleton``, ``Callable`` providers and 
 | 
			
		||||
  ``inject`` decorator.
 | 
			
		||||
- Add functionality for decorating classes with ``@inject``.
 | 
			
		||||
- Add ``Singleton.injections`` attribute that represents a tuple of all 
 | 
			
		||||
  ``Singleton`` injections (including args, kwargs, attributes and methods).
 | 
			
		||||
- Add ``Callable.injections`` attribute that represents a tuple of all 
 | 
			
		||||
  ``Callable`` injections (including args and kwargs).
 | 
			
		||||
- Add optimization for ``Injection.value`` property that will compute 
 | 
			
		||||
  type of injection once, instead of doing this on every call.
 | 
			
		||||
- Add ``di.VERSION`` constant for verification of currently installed version.
 | 
			
		||||
- Add ``VERSION`` constant for verification of currently installed version.
 | 
			
		||||
- Add support of Python 3.5.
 | 
			
		||||
- Add support of six 1.10.0.
 | 
			
		||||
- Add minor refactorings and code style fixes.
 | 
			
		||||
| 
						 | 
				
			
			@ -58,8 +76,8 @@ Development version
 | 
			
		|||
0.9.5
 | 
			
		||||
-----
 | 
			
		||||
- Change provider attributes scope to public.
 | 
			
		||||
- Add ``di.Factory.injections`` attribute that represents a tuple of all 
 | 
			
		||||
  ``di.Factory`` injections (including kwargs, attributes and methods).
 | 
			
		||||
- Add ``Factory.injections`` attribute that represents a tuple of all 
 | 
			
		||||
  ``Factory`` injections (including kwargs, attributes and methods).
 | 
			
		||||
 | 
			
		||||
0.9.4
 | 
			
		||||
-----
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,7 @@ framework can be installed from PyPi_:
 | 
			
		|||
    pip install dependency_injector
 | 
			
		||||
 | 
			
		||||
    # Installing particular version:
 | 
			
		||||
    pip install dependency_injector==0.9.0
 | 
			
		||||
    pip install dependency_injector==0.11.0
 | 
			
		||||
    
 | 
			
		||||
Sources can be cloned from GitHub_:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,14 +23,14 @@ Sources can be cloned from GitHub_:
 | 
			
		|||
Also all *Dependency Injector* releases can be downloaded from 
 | 
			
		||||
`GitHub releases page`_.
 | 
			
		||||
 | 
			
		||||
Verification of currently installed version could be done using ``di.VERSION`` 
 | 
			
		||||
constant:
 | 
			
		||||
Verification of currently installed version could be done using 
 | 
			
		||||
:py:obj:`dependency_injector.VERSION` constant:
 | 
			
		||||
 | 
			
		||||
.. code-block:: bash
 | 
			
		||||
 | 
			
		||||
    >>> import dependency_injector as di
 | 
			
		||||
    >>> di.VERSION
 | 
			
		||||
    '0.10.0'
 | 
			
		||||
    >>> from dependency_injector import VERSION
 | 
			
		||||
    >>> VERSION
 | 
			
		||||
    '0.11.0'
 | 
			
		||||
 | 
			
		||||
.. _PyPi: https://pypi.python.org/pypi/dependency_injector
 | 
			
		||||
.. _GitHub: https://github.com/rmk135/dependency_injector
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,27 +57,6 @@ framework:
 | 
			
		|||
 | 
			
		||||
Main idea of *Dependency Injector* is to keep dependencies under control.
 | 
			
		||||
 | 
			
		||||
Shortcuts
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
*Dependency Injector* recommends to use such kind of import shortcut:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
   import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
- All *Dependency Injector* entities could be used just from top-level package 
 | 
			
		||||
  (like ``di.Factory``, ``di.inject``, ``di.AbstractCatalog`` and so on).
 | 
			
		||||
- Another one way is to use second level packages (like 
 | 
			
		||||
  ``di.providers.Factory``, ``di.injections.inject``, 
 | 
			
		||||
  ``di.catalog.AbstractCatalog`` and so on). It might be useful for improving 
 | 
			
		||||
  of readability in some cases.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    ``import dependency_injector as di`` shortcut is used among current 
 | 
			
		||||
    documentation, images and examples.
 | 
			
		||||
 | 
			
		||||
Main entities
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,18 +70,21 @@ interaction with each other.
 | 
			
		|||
There are 3 main entities:
 | 
			
		||||
 | 
			
		||||
- Providers. Providers are strategies of accesing objects. For example, 
 | 
			
		||||
  ``di.providers.Factory`` creates new instance of provided 
 | 
			
		||||
  class every time it is called. ``di.providers.Singleton`` creates 
 | 
			
		||||
  provided instance once and returns it on every next call. Providers 
 | 
			
		||||
  could be overridden by another providers. Base class is - 
 | 
			
		||||
  ``di.providers.Provider``.
 | 
			
		||||
  :py:class:`dependency_injector.providers.Factory` creates new instance of 
 | 
			
		||||
  provided class every time it is called. 
 | 
			
		||||
  :py:class:`dependency_injector.providers.Singleton` creates provided 
 | 
			
		||||
  instance once and returns it on every next call. Providers could be 
 | 
			
		||||
  overridden by another providers. Base class is - 
 | 
			
		||||
  :py:class:`dependency_injector.providers.Provider`.
 | 
			
		||||
- Injections. Injections are instructions for making dependency injections 
 | 
			
		||||
  (there are several ways how they could be done). Injections are used mostly
 | 
			
		||||
  by ``di.providers.Factory`` and ``di.providers.Singleton`` providers, but 
 | 
			
		||||
  these are not only cases. Base class is - ``di.injections.Injection``.
 | 
			
		||||
  by :py:class:`dependency_injector.providers.Factory` and 
 | 
			
		||||
  :py:class:`dependency_injector.providers.Singleton` providers, but 
 | 
			
		||||
  these are not only cases. Base class is - 
 | 
			
		||||
  :py:class:`dependency_injector.injections.Injection`.
 | 
			
		||||
- Catalogs. Catalogs are collections of providers. They are used for grouping 
 | 
			
		||||
  of providers by some principles. Base class is - 
 | 
			
		||||
  ``di.catalog.AbstractCatalog``.
 | 
			
		||||
  :py:class:`dependency_injector.catalogs.DeclarativeCatalog`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _SLOC: http://en.wikipedia.org/wiki/Source_lines_of_code
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,40 +1,43 @@
 | 
			
		|||
Callable providers
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
``di.Callable`` provider is a provider that wraps particular callable with
 | 
			
		||||
.. module:: dependency_injector.providers
 | 
			
		||||
 | 
			
		||||
:py:class:`Callable` provider is a provider that wraps particular callable with
 | 
			
		||||
some injections. Every call of this provider returns result of call of initial
 | 
			
		||||
callable.
 | 
			
		||||
 | 
			
		||||
Callable providers and injections
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``di.Callable`` takes a various number of positional and keyword arguments 
 | 
			
		||||
that are used as decorated callable injections. Every time, when 
 | 
			
		||||
``di.Callable`` is called, positional and keyword argument injections would be 
 | 
			
		||||
passed as an callable arguments.
 | 
			
		||||
:py:class:`Callable` takes a various number of positional and keyword 
 | 
			
		||||
arguments that are used as decorated callable injections. Every time, when 
 | 
			
		||||
:py:class:`Callable` is called, positional and keyword argument injections 
 | 
			
		||||
would be passed as an callable arguments.
 | 
			
		||||
 | 
			
		||||
Such behaviour is very similar to the standard Python ``functools.partial`` 
 | 
			
		||||
object, except of one thing: all injectable values are provided 
 | 
			
		||||
*"as is"*, except of providers (subclasses of ``di.Provider``). Providers 
 | 
			
		||||
*"as is"*, except of providers (subclasses of :py:class:`Provider`). Providers 
 | 
			
		||||
will be called every time, when injection needs to be done. For example, 
 | 
			
		||||
if injectable value of injection is a ``di.Factory``, it will provide new one 
 | 
			
		||||
instance (as a result of its call) every time, when injection needs to be done.
 | 
			
		||||
if injectable value of injection is a :py:class:`Factory`, it will provide 
 | 
			
		||||
new one instance (as a result of its call) every time, when injection needs 
 | 
			
		||||
to be done.
 | 
			
		||||
 | 
			
		||||
``di.Callable`` behaviour with context positional and keyword arguments is 
 | 
			
		||||
very like a standard Python ``functools.partial``:
 | 
			
		||||
:py:class:`Callable` behaviour with context positional and keyword arguments 
 | 
			
		||||
is very like a standard Python ``functools.partial``:
 | 
			
		||||
 | 
			
		||||
- Positional context arguments will be appended after ``di.Callable`` 
 | 
			
		||||
- Positional context arguments will be appended after :py:class:`Callable` 
 | 
			
		||||
  positional injections.
 | 
			
		||||
- Keyword context arguments have priority on ``di.Callable`` keyword 
 | 
			
		||||
- Keyword context arguments have priority on :py:class:`Callable` keyword 
 | 
			
		||||
  injections and will be merged over them.
 | 
			
		||||
 | 
			
		||||
Example that shows usage of ``di.Callable`` with positional argument 
 | 
			
		||||
Example that shows usage of :py:class:`Callable` with positional argument 
 | 
			
		||||
injections:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/callable_args.py
 | 
			
		||||
   :language: python
 | 
			
		||||
 | 
			
		||||
Next one example shows usage of ``di.Callable`` with keyword argument 
 | 
			
		||||
Next one example shows usage of :py:class:`Callable` with keyword argument 
 | 
			
		||||
injections:
 | 
			
		||||
 | 
			
		||||
.. image:: /images/providers/callable.png
 | 
			
		||||
| 
						 | 
				
			
			@ -47,13 +50,13 @@ injections:
 | 
			
		|||
Callable providers delegation
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``di.Callable`` provider could be delegated to any other provider via any kind 
 | 
			
		||||
of injection. Delegation of ``di.Callable`` providers is the same as 
 | 
			
		||||
``di.Factory`` and ``di.Singleton`` providers delegation, please follow 
 | 
			
		||||
*Factory providers delegation* section for example.
 | 
			
		||||
:py:class:`Callable` provider could be delegated to any other provider via any 
 | 
			
		||||
kind of injection. Delegation of :py:class:`Callable` providers is the same as 
 | 
			
		||||
:py:class:`Factory` and :py:class:`Singleton` providers delegation, please 
 | 
			
		||||
follow *Factory providers delegation* section for example.
 | 
			
		||||
 | 
			
		||||
``di.Callable`` delegate could be created obviously using 
 | 
			
		||||
``di.Delegate(di.Callable())`` or by calling ``di.Callable.delegate()`` method.
 | 
			
		||||
:py:class:`Callable` delegate could be created obviously using 
 | 
			
		||||
``Delegate(Callable(...))`` or by calling ``Callable(...).delegate()`` method.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,27 +1,28 @@
 | 
			
		|||
Writing custom providers
 | 
			
		||||
Writing of custom providers
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
.. module:: dependency_injector.providers
 | 
			
		||||
 | 
			
		||||
List of *Dependency Injector* providers could be widened with custom providers.
 | 
			
		||||
 | 
			
		||||
Below are some tips and recommendations that have to be met:
 | 
			
		||||
 | 
			
		||||
    1. Every custom provider has to extend base provider class - 
 | 
			
		||||
       ``di.Provider``.
 | 
			
		||||
    2. Cusom provider's ``__init__()`` could be overriden with only condition: 
 | 
			
		||||
       parent initializer (``di.Provider.__init__()``) has to be called.
 | 
			
		||||
       :py:class:`Provider`.
 | 
			
		||||
    2. Cusom provider's ``__init__()`` could be overriden, but parent's
 | 
			
		||||
       initializer (:py:meth:`Provider.__init__`) has to be called.
 | 
			
		||||
    3. Providing strategy has to be implemented in custom provider's 
 | 
			
		||||
       ``_provide()`` method. All ``*args`` & ``**kwargs`` that will be
 | 
			
		||||
       recieved by ``di.Provider.__call__()`` will be transefed to custom 
 | 
			
		||||
       provider's ``_provide()``. 
 | 
			
		||||
       :py:meth:`Provider._provide` method. All ``*args`` & ``**kwargs`` 
 | 
			
		||||
       that will be recieved by :py:meth:`Provider.__call__` will be 
 | 
			
		||||
       transefed to custom provider's :py:meth:`Provider._provide`. 
 | 
			
		||||
    4. If custom provider is based on some standard providers, it is better to
 | 
			
		||||
       use delegation of standard providers, then extending of them.
 | 
			
		||||
    5. If custom provider defines any attributes, it is good to list them in 
 | 
			
		||||
       ``__slots__`` attribute (as *Dependency Injector* does). It can save 
 | 
			
		||||
       some memory.
 | 
			
		||||
    6. If custom provider deals with injections (e.g. ``di.Factory``, 
 | 
			
		||||
       ``di.Singleton`` providers), it is strongly recommended to be 
 | 
			
		||||
       consistent with ``di.Factory``, ``di.Singleton`` and ``di.Callable`` 
 | 
			
		||||
       providers style. 
 | 
			
		||||
    6. If custom provider deals with injections, it is strongly recommended 
 | 
			
		||||
       to be consistent with :py:class:`Factory`, :py:class:`Singleton` and 
 | 
			
		||||
       :py:class:`Callable` providers style. 
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,9 @@
 | 
			
		|||
External dependency providers
 | 
			
		||||
-----------------------------
 | 
			
		||||
 | 
			
		||||
``di.ExternalDependency`` provider can be useful for development of
 | 
			
		||||
.. module:: dependency_injector.providers
 | 
			
		||||
 | 
			
		||||
:py:class:`ExternalDependency` provider can be useful for development of
 | 
			
		||||
self-sufficient libraries / modules / applications that has required external
 | 
			
		||||
dependencies.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,10 @@
 | 
			
		|||
Factory providers
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
``di.Factory`` provider creates new instance of specified class on every call.
 | 
			
		||||
.. module:: dependency_injector.providers
 | 
			
		||||
 | 
			
		||||
:py:class:`Factory` provider creates new instance of specified class on every 
 | 
			
		||||
call.
 | 
			
		||||
 | 
			
		||||
Nothing could be better than brief example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,21 +18,22 @@ Nothing could be better than brief example:
 | 
			
		|||
Factory providers and __init__ injections
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``di.Factory`` takes a various number of positional and keyword arguments that 
 | 
			
		||||
are used as ``__init__()`` injections. Every time, when ``di.Factory`` 
 | 
			
		||||
creates new one instance, positional and keyword argument injections would be 
 | 
			
		||||
passed as an instance's arguments.
 | 
			
		||||
:py:class:`Factory` takes a various number of positional and keyword arguments 
 | 
			
		||||
that are used as ``__init__()`` injections. Every time, when 
 | 
			
		||||
:py:class:`Factory` creates new one instance, positional and keyword 
 | 
			
		||||
argument injections would be passed as an instance's arguments.
 | 
			
		||||
 | 
			
		||||
Such behaviour is very similar to the standard Python ``functools.partial`` 
 | 
			
		||||
object, except of one thing: all injectable values are provided 
 | 
			
		||||
*"as is"*, except of providers (subclasses of ``di.Provider``). Providers 
 | 
			
		||||
*"as is"*, except of providers (subclasses of :py:class:`Provider`). Providers 
 | 
			
		||||
will be called every time, when injection needs to be done. For example, 
 | 
			
		||||
if injectable value of injection is a ``di.Factory``, it will provide new one 
 | 
			
		||||
instance (as a result of its call) every time, when injection needs to be done.
 | 
			
		||||
if injectable value of injection is a :py:class:`Factory`, it will provide 
 | 
			
		||||
new one instance (as a result of its call) every time, when injection needs 
 | 
			
		||||
to be done.
 | 
			
		||||
 | 
			
		||||
Example below is a little bit more complicated. It shows how to create 
 | 
			
		||||
``di.Factory`` of particular class with ``__init__()`` argument injections 
 | 
			
		||||
which injectable values are also provided by another factories:
 | 
			
		||||
:py:class:`Factory` of particular class with ``__init__()`` argument 
 | 
			
		||||
injections which injectable values are also provided by another factories:
 | 
			
		||||
 | 
			
		||||
.. note:: 
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,14 +62,14 @@ Example of usage keyword argument injections:
 | 
			
		|||
Factory providers and __init__ injections priority
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Next example shows how ``di.Factory`` provider deals with positional and 
 | 
			
		||||
keyword ``__init__()`` context arguments. In few words, ``di.Factory`` 
 | 
			
		||||
Next example shows how :py:class:`Factory` provider deals with positional and 
 | 
			
		||||
keyword ``__init__()`` context arguments. In few words, :py:class:`Factory` 
 | 
			
		||||
behaviour here is very like a standard Python ``functools.partial``:
 | 
			
		||||
 | 
			
		||||
- Positional context arguments will be appended after ``di.Factory`` 
 | 
			
		||||
- Positional context arguments will be appended after :py:class:`Factory` 
 | 
			
		||||
  positional injections.
 | 
			
		||||
- Keyword context arguments have priority on ``di.Factory`` keyword injections 
 | 
			
		||||
  and will be merged over them.
 | 
			
		||||
- Keyword context arguments have priority on :py:class:`Factory` keyword 
 | 
			
		||||
  injections and will be merged over them.
 | 
			
		||||
 | 
			
		||||
So, please, follow the example below:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,34 +86,38 @@ Objects can take dependencies in different forms (some objects take init
 | 
			
		|||
arguments, other use attributes setting or method calls). It affects how 
 | 
			
		||||
such objects are created and initialized.
 | 
			
		||||
 | 
			
		||||
``di.Factory`` provider takes various number of positional and keyword 
 | 
			
		||||
:py:class:`Factory` provider takes various number of positional and keyword 
 | 
			
		||||
arguments, that define what kinds of dependency injections have to be used.
 | 
			
		||||
 | 
			
		||||
All of those instructions are defined in ``di.injections`` module and are 
 | 
			
		||||
subclasses of ``di.injections.Injection`` (shortcut ``di.Injection``). There 
 | 
			
		||||
are several types of injections that are used by ``di.Factory`` provider:
 | 
			
		||||
All of those instructions are defined in 
 | 
			
		||||
:py:mod:`dependency_injector.injections` module and are subclasses of 
 | 
			
		||||
:py:class:`dependency_injector.injections.Injection`. There are several types 
 | 
			
		||||
of injections that are used by :py:class:`Factory` provider:
 | 
			
		||||
 | 
			
		||||
+ ``di.Arg`` - injection is done by passing injectable value in object's
 | 
			
		||||
  ``__init__()`` method in time of object's creation as positional argument.
 | 
			
		||||
  Takes injectable value only.
 | 
			
		||||
+ ``di.KwArg`` - injection is done by passing injectable value in object's
 | 
			
		||||
  ``__init__()`` method in time of object's creation as keyword argument.
 | 
			
		||||
  Takes keyword name of ``__init__()`` argument and injectable value.
 | 
			
		||||
+ ``di.Attribute`` - injection is done by setting specified attribute with
 | 
			
		||||
  injectable value right after object's creation. Takes attribute's name
 | 
			
		||||
  and injectable value.
 | 
			
		||||
+ ``di.Method`` - injection is done by calling of specified method with
 | 
			
		||||
  injectable value right after object's creation and attribute injections
 | 
			
		||||
  are done. Takes method name and injectable value.
 | 
			
		||||
+ :py:class:`dependency_injector.injections.Arg` - injection is done by 
 | 
			
		||||
  passing injectable value in object's ``__init__()`` method in time of 
 | 
			
		||||
  object's creation as positional argument. Takes injectable value only.
 | 
			
		||||
+ :py:class:`dependency_injector.injections.KwArg` - injection is done by 
 | 
			
		||||
  passing injectable value in object's ``__init__()`` method in time of 
 | 
			
		||||
  object's creation as keyword argument.  Takes keyword name of 
 | 
			
		||||
  ``__init__()`` argument and injectable value.
 | 
			
		||||
+ :py:class:`dependency_injector.injections.Attribute` - injection is done 
 | 
			
		||||
  by setting specified attribute with injectable value right after 
 | 
			
		||||
  object's creation. Takes attribute's name and injectable value.
 | 
			
		||||
+ :py:class:`dependency_injector.injections.Method` - injection is done by 
 | 
			
		||||
  calling of specified method with injectable value right after object's 
 | 
			
		||||
  creation and attribute injections are done. Takes method name and 
 | 
			
		||||
  injectable value.
 | 
			
		||||
 | 
			
		||||
All ``di.Injection``'s injectable values are provided *"as is"*, except of
 | 
			
		||||
providers (subclasses of ``di.Provider``). Providers will be called every time,
 | 
			
		||||
when injection needs to be done.
 | 
			
		||||
All :py:class:`dependency_injector.injections.Injection`'s injectable values 
 | 
			
		||||
are provided *"as is"*, except of providers (subclasses of 
 | 
			
		||||
:py:class:`Provider`). Providers will be called every time, when injection 
 | 
			
		||||
needs to be done.
 | 
			
		||||
 | 
			
		||||
Factory providers and attribute injections
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Example below shows how to create ``di.Factory`` of particular class with
 | 
			
		||||
Example below shows how to create :py:class:`Factory` of particular class with
 | 
			
		||||
attribute injections. Those injections are done by setting specified attributes
 | 
			
		||||
with injectable values right after object's creation.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,10 +131,10 @@ Example:
 | 
			
		|||
Factory providers and method injections
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Current example shows how to create ``di.Factory`` of particular class with
 | 
			
		||||
method injections. Those injections are done by calling of specified method
 | 
			
		||||
with injectable value right after object's creation and attribute injections
 | 
			
		||||
are done.
 | 
			
		||||
Current example shows how to create :py:class:`Factory` of particular class
 | 
			
		||||
with method injections. Those injections are done by calling of specified 
 | 
			
		||||
method with injectable value right after object's creation and attribute 
 | 
			
		||||
injections are done.
 | 
			
		||||
 | 
			
		||||
Method injections are not very popular in Python due Python best practices
 | 
			
		||||
(usage of public attributes instead of setter methods), but they may appear in
 | 
			
		||||
| 
						 | 
				
			
			@ -142,21 +150,21 @@ Example:
 | 
			
		|||
Factory providers delegation
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``di.Factory`` provider could be delegated to any other provider via any kind 
 | 
			
		||||
of injection. As it was mentioned earlier, if ``di.Factory`` is injectable 
 | 
			
		||||
value, it will be called every time when injection is done. ``di.Factory`` 
 | 
			
		||||
delegation is performed by wrapping delegated ``di.Factory`` into special 
 | 
			
		||||
provider type - ``di.Delegate``, that just returns wrapped ``di.Factory``. 
 | 
			
		||||
Saying in other words, delegation of factories - is a way to inject factories 
 | 
			
		||||
themselves, instead of results of their calls. 
 | 
			
		||||
 | 
			
		||||
:py:class:`Factory` provider could be delegated to any other provider via any 
 | 
			
		||||
kind of injection. As it was mentioned earlier, if :py:class:`Factory` is 
 | 
			
		||||
injectable value, it will be called every time when injection is done. 
 | 
			
		||||
:py:class:`Factory` delegation is performed by wrapping delegated 
 | 
			
		||||
:py:class:`Factory` into special provider type - :py:class:`Delegate`, that 
 | 
			
		||||
just returns wrapped :py:class:`Factory`. Saying in other words, delegation 
 | 
			
		||||
of factories - is a way to inject factories themselves, instead of results 
 | 
			
		||||
of their calls. 
 | 
			
		||||
 | 
			
		||||
Actually, there are two ways of creating factory delegates:
 | 
			
		||||
 | 
			
		||||
+ ``di.Delegate(di.Factory(...))`` - obviously wrapping factory into 
 | 
			
		||||
  ``di.Delegate`` provider.
 | 
			
		||||
+ ``di.Factory(...).delegate()`` - calling factory ``delegate()`` method, that 
 | 
			
		||||
  returns delegate wrapper for current factory.
 | 
			
		||||
+ ``Delegate(Factory(...))`` - obviously wrapping factory into 
 | 
			
		||||
  :py:class:`Delegate` provider.
 | 
			
		||||
+ ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate` 
 | 
			
		||||
  method, that returns delegate wrapper for current factory.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,17 +4,21 @@ Providers
 | 
			
		|||
Providers are strategies of accessing objects. They describe how particular 
 | 
			
		||||
objects are provided.
 | 
			
		||||
 | 
			
		||||
Base providers class is - :py:class:`dependency_injector.providers.Provider`
 | 
			
		||||
 | 
			
		||||
Every provider is callable (implements ``__call__()``). Every call to provider 
 | 
			
		||||
instance returns provided result, according to the providing strategy of 
 | 
			
		||||
particular provider. 
 | 
			
		||||
 | 
			
		||||
Current documentation section consists from description of standard providers
 | 
			
		||||
library and some useful information like overriding of providers and writing 
 | 
			
		||||
custom providers.
 | 
			
		||||
of custom providers.
 | 
			
		||||
 | 
			
		||||
All providers are validated in multithreading environment and considered to 
 | 
			
		||||
be thread safe.
 | 
			
		||||
 | 
			
		||||
Providers module API docs - :py:mod:`dependency_injector.providers`
 | 
			
		||||
 | 
			
		||||
..  toctree::
 | 
			
		||||
    :maxdepth: 2
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
Overriding of providers
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
.. module:: dependency_injector.providers
 | 
			
		||||
 | 
			
		||||
Every provider could be overridden by another provider.
 | 
			
		||||
 | 
			
		||||
This gives opportunity to make system behaviour more flexible in some points.
 | 
			
		||||
| 
						 | 
				
			
			@ -15,22 +17,22 @@ Provider overriding functionality has such interface:
 | 
			
		|||
    :width: 45%
 | 
			
		||||
    :align: center
 | 
			
		||||
 | 
			
		||||
+ ``di.Provider.override()`` - takes another provider that will be used 
 | 
			
		||||
+ :py:meth:`Provider.override()` - takes another provider that will be used 
 | 
			
		||||
  instead of current provider. This method could be called several times. 
 | 
			
		||||
  In such case, last passed provider would be used as overriding one.
 | 
			
		||||
+ ``di.Provider.reset_override()`` - resets all overriding providers. Provider 
 | 
			
		||||
  starts to behave itself like usual.
 | 
			
		||||
+ ``di.Provider.is_overridden`` - bool, ``True`` if provider is overridden.
 | 
			
		||||
+ :py:meth:`Provider.reset_override()` - resets all overriding providers. 
 | 
			
		||||
  Provider starts to behave itself like usual.
 | 
			
		||||
+ :py:attr:`Provider.is_overridden` - bool, ``True`` if provider is overridden.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Actually, initial provider forms stack from overriding providers. There is 
 | 
			
		||||
   some, not so common, but still usefull, functionality that could be used:
 | 
			
		||||
 | 
			
		||||
   + ``di.Provider.last_overriding`` - always keeps reference to last 
 | 
			
		||||
   + :py:attr:`Provider.last_overriding` - always keeps reference to last 
 | 
			
		||||
     overriding provider.
 | 
			
		||||
   + ``di.Provider.reset_last_overriding()`` - remove last overriding provider 
 | 
			
		||||
     from stack of overriding providers.
 | 
			
		||||
   + :py:meth:`Provider.reset_last_overriding()` - remove last overriding 
 | 
			
		||||
     provider from stack of overriding providers.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,10 @@
 | 
			
		|||
Singleton providers
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
``di.Singleton`` provider creates new instance of specified class on first call
 | 
			
		||||
and returns same instance on every next call.
 | 
			
		||||
.. module:: dependency_injector.providers
 | 
			
		||||
 | 
			
		||||
:py:class:`Singleton` provider creates new instance of specified class on 
 | 
			
		||||
first call and returns same instance on every next call.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -16,9 +18,9 @@ Example:
 | 
			
		|||
Singleton providers and injections
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``di.Singleton`` providers use ``di.Factory`` providers for first creation of
 | 
			
		||||
specified class instance, so, all of the rules about injections are the same,
 | 
			
		||||
as for ``di.Factory`` providers.
 | 
			
		||||
:py:class:`Singleton` providers use :py:class:`Factory` providers for first 
 | 
			
		||||
creation of specified class instance, so, all of the rules about injections 
 | 
			
		||||
are the same, as for :py:class:`Factory` providers.
 | 
			
		||||
 | 
			
		||||
.. image:: /images/providers/singleton_internals.png
 | 
			
		||||
    :width: 80%
 | 
			
		||||
| 
						 | 
				
			
			@ -26,29 +28,29 @@ as for ``di.Factory`` providers.
 | 
			
		|||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    Due that ``di.Singleton`` provider creates specified class instance only on
 | 
			
		||||
    the first call, all injections are done once, during the first call, also.
 | 
			
		||||
    Every next call, while instance has been already created and memorized, no
 | 
			
		||||
    injections are done, ``di.Singleton`` provider just returns memorized 
 | 
			
		||||
    earlier instance.
 | 
			
		||||
    Due that :py:class:`Singleton` provider creates specified class instance 
 | 
			
		||||
    only on the first call, all injections are done once, during the first 
 | 
			
		||||
    call, also.  Every next call, while instance has been already created 
 | 
			
		||||
    and memorized, no injections are done, :py:class:`Singleton` provider just 
 | 
			
		||||
    returns memorized earlier instance.
 | 
			
		||||
 | 
			
		||||
    This may cause some problems, for example, in case of trying to bind
 | 
			
		||||
    ``di.Factory`` provider with ``di.Singleton`` provider (provided by 
 | 
			
		||||
    dependent ``di.Factory`` instance will be injected only once, during the 
 | 
			
		||||
    first call). Be aware that such behaviour was made with opened eyes and is 
 | 
			
		||||
    not a bug.
 | 
			
		||||
    :py:class:`Factory` provider with :py:class:`Singleton` provider (provided 
 | 
			
		||||
    by dependent :py:class:`Factory` instance will be injected only once, 
 | 
			
		||||
    during the first call). Be aware that such behaviour was made with opened 
 | 
			
		||||
    eyes and is not a bug.
 | 
			
		||||
 | 
			
		||||
    By the way, in such case, ``di.Delegate`` provider can be useful. It makes
 | 
			
		||||
    possible to inject providers *as is*. Please check out full example in
 | 
			
		||||
    *Providers delegation* section.
 | 
			
		||||
    By the way, in such case, :py:class:`Delegate` provider can be useful. It 
 | 
			
		||||
    makes possible to inject providers *as is*. Please check out full example 
 | 
			
		||||
    in *Providers delegation* section.
 | 
			
		||||
 | 
			
		||||
Singleton providers resetting
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Created and memorized by ``di.Singleton`` instance can be reset. Reset of
 | 
			
		||||
``di.Singleton``'s memorized instance is done by clearing reference to it. 
 | 
			
		||||
Further lifecycle of memorized instance is out of ``di.Singleton`` provider's 
 | 
			
		||||
control.
 | 
			
		||||
Created and memorized by :py:class:`Singleton` instance can be reset. Reset of
 | 
			
		||||
:py:class:`Singleton`'s memorized instance is done by clearing reference to 
 | 
			
		||||
it.  Further lifecycle of memorized instance is out of :py:class:`Singleton` 
 | 
			
		||||
provider's control.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,13 +60,13 @@ Example:
 | 
			
		|||
Singleton providers delegation
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
``di.Singleton`` provider could be delegated to any other provider via any 
 | 
			
		||||
kind of injection. Delegation of ``di.Singleton`` providers is the same as 
 | 
			
		||||
``di.Factory`` providers delegation, please follow 
 | 
			
		||||
*Factory providers delegation* section for example.
 | 
			
		||||
:py:class:`Singleton` provider could be delegated to any other provider via 
 | 
			
		||||
any kind of injection. Delegation of :py:class:`Singleton` providers is the 
 | 
			
		||||
same as :py:class:`Factory` providers delegation, please follow *Factory 
 | 
			
		||||
providers delegation* section for example.
 | 
			
		||||
 | 
			
		||||
``di.Singleton`` delegate could be created obviously using 
 | 
			
		||||
``di.Delegate(di.Singleton())`` or by calling ``di.Singleton.delegate()`` 
 | 
			
		||||
:py:class:`Singleton` delegate could be created obviously using 
 | 
			
		||||
``Delegate(Singleton(...))`` or by calling ``Singleton(...).delegate()`` 
 | 
			
		||||
method.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,16 +1,19 @@
 | 
			
		|||
Static providers
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
.. module:: dependency_injector.providers
 | 
			
		||||
 | 
			
		||||
Static providers are family of providers that return their values "as is".
 | 
			
		||||
There are four types of static providers:
 | 
			
		||||
 | 
			
		||||
    - ``di.Class``
 | 
			
		||||
    - ``di.Object``
 | 
			
		||||
    - ``di.Function``
 | 
			
		||||
    - ``di.Value``
 | 
			
		||||
    - :py:class:`Class`
 | 
			
		||||
    - :py:class:`Object`
 | 
			
		||||
    - :py:class:`Function`
 | 
			
		||||
    - :py:class:`Value`
 | 
			
		||||
 | 
			
		||||
All of them have the same behaviour, but usage of anyone is predicted by
 | 
			
		||||
readability and providing object's type.
 | 
			
		||||
All of them have the same behaviour (inherited from 
 | 
			
		||||
:py:class:`StaticProvider`), but usage of any is predicted by readability 
 | 
			
		||||
and providing object's type.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
"""Config provider examples."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ObjectA(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -13,17 +14,17 @@ class ObjectA(object):
 | 
			
		|||
        self.timezone = timezone
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Catalog(di.AbstractCatalog):
 | 
			
		||||
class Catalog(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Catalog of providers."""
 | 
			
		||||
 | 
			
		||||
    config = di.Config()
 | 
			
		||||
    """:type: di.Config"""
 | 
			
		||||
    config = providers.Config()
 | 
			
		||||
    """:type: providers.Config"""
 | 
			
		||||
 | 
			
		||||
    object_a = di.Factory(ObjectA,
 | 
			
		||||
                          fee=config.FEE,
 | 
			
		||||
                          price=config.PRICE,
 | 
			
		||||
                          timezone=config.GLOBAL.TIMEZONE)
 | 
			
		||||
    """:type: di.Provider -> ObjectA"""
 | 
			
		||||
    object_a = providers.Factory(ObjectA,
 | 
			
		||||
                                 fee=config.FEE,
 | 
			
		||||
                                 price=config.PRICE,
 | 
			
		||||
                                 timezone=config.GLOBAL.TIMEZONE)
 | 
			
		||||
    """:type: providers.Provider -> ObjectA"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Setting config value and making some tests.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,22 +1,24 @@
 | 
			
		|||
"""`@di.inject()` decorator and Flask view example."""
 | 
			
		||||
"""`inject()` decorator and Flask view example."""
 | 
			
		||||
 | 
			
		||||
import sqlite3
 | 
			
		||||
import flask
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
from dependency_injector import injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
database = di.Singleton(sqlite3.connect,
 | 
			
		||||
                        ':memory:',
 | 
			
		||||
                        timeout=30,
 | 
			
		||||
                        detect_types=True,
 | 
			
		||||
                        isolation_level='EXCLUSIVE')
 | 
			
		||||
database = providers.Singleton(sqlite3.connect,
 | 
			
		||||
                               ':memory:',
 | 
			
		||||
                               timeout=30,
 | 
			
		||||
                               detect_types=True,
 | 
			
		||||
                               isolation_level='EXCLUSIVE')
 | 
			
		||||
 | 
			
		||||
app = flask.Flask(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@app.route('/')
 | 
			
		||||
@di.inject(database)
 | 
			
		||||
@di.inject(flask.request)
 | 
			
		||||
@injections.inject(database)
 | 
			
		||||
@injections.inject(flask.request)
 | 
			
		||||
def hello(request, database):
 | 
			
		||||
    """Example Flask view."""
 | 
			
		||||
    print request
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,22 +1,24 @@
 | 
			
		|||
"""`@di.inject()` decorator with classes example."""
 | 
			
		||||
"""`inject()` decorator with classes example."""
 | 
			
		||||
 | 
			
		||||
import sqlite3
 | 
			
		||||
import flask
 | 
			
		||||
import flask.views
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
from dependency_injector import injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
database = di.Singleton(sqlite3.Connection,
 | 
			
		||||
                        database=':memory:',
 | 
			
		||||
                        timeout=30,
 | 
			
		||||
                        detect_types=True,
 | 
			
		||||
                        isolation_level='EXCLUSIVE')
 | 
			
		||||
database = providers.Singleton(sqlite3.Connection,
 | 
			
		||||
                               database=':memory:',
 | 
			
		||||
                               timeout=30,
 | 
			
		||||
                               detect_types=True,
 | 
			
		||||
                               isolation_level='EXCLUSIVE')
 | 
			
		||||
 | 
			
		||||
app = flask.Flask(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@di.inject(database=database)
 | 
			
		||||
@di.inject(some_setting=777)
 | 
			
		||||
@injections.inject(database=database)
 | 
			
		||||
@injections.inject(some_setting=777)
 | 
			
		||||
class HelloView(flask.views.View):
 | 
			
		||||
    """Example flask class-based view."""
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,15 @@
 | 
			
		|||
"""`@di.inject()` decorator simple example."""
 | 
			
		||||
"""`inject()` decorator simple example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
from dependency_injector import injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dependency_injector_factory = di.Factory(object)
 | 
			
		||||
dependency_injector_factory = providers.Factory(object)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Example of using `di.inject()` decorator keyword argument injections:
 | 
			
		||||
@di.inject(new_object=dependency_injector_factory)
 | 
			
		||||
@di.inject(some_setting=1334)
 | 
			
		||||
@injections.inject(new_object=dependency_injector_factory)
 | 
			
		||||
@injections.inject(some_setting=1334)
 | 
			
		||||
def example_callback1(new_object, some_setting):
 | 
			
		||||
    """Example callback that does some asserts for input args."""
 | 
			
		||||
    assert isinstance(new_object, object)
 | 
			
		||||
| 
						 | 
				
			
			@ -16,7 +17,7 @@ def example_callback1(new_object, some_setting):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
# Example of using `di.inject()` decorator with positional argument injections:
 | 
			
		||||
@di.inject(dependency_injector_factory, 1334)
 | 
			
		||||
@injections.inject(dependency_injector_factory, 1334)
 | 
			
		||||
def example_callback2(new_object, some_setting):
 | 
			
		||||
    """Example callback that does some asserts for input args."""
 | 
			
		||||
    assert isinstance(new_object, object)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,38 +1,40 @@
 | 
			
		|||
"""Catalog bundles example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
from dependency_injector import errors
 | 
			
		||||
 | 
			
		||||
import services
 | 
			
		||||
import views
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Declaring services catalog:
 | 
			
		||||
class Services(di.DeclarativeCatalog):
 | 
			
		||||
class Services(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Example catalog of service providers."""
 | 
			
		||||
 | 
			
		||||
    users = di.Factory(services.UsersService)
 | 
			
		||||
    """:type: di.Provider -> services.UsersService"""
 | 
			
		||||
    users = providers.Factory(services.Users)
 | 
			
		||||
    """:type: providers.Provider -> services.Users"""
 | 
			
		||||
 | 
			
		||||
    auth = di.Factory(services.AuthService)
 | 
			
		||||
    """:type: di.Provider -> services.AuthService"""
 | 
			
		||||
    auth = providers.Factory(services.Auth)
 | 
			
		||||
    """:type: providers.Provider -> services.Auth"""
 | 
			
		||||
 | 
			
		||||
    photos = di.Factory(services.PhotosService)
 | 
			
		||||
    """:type: di.Provider -> services.PhotosService"""
 | 
			
		||||
    photos = providers.Factory(services.Photos)
 | 
			
		||||
    """:type: providers.Provider -> services.Photos"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Declaring views catalog:
 | 
			
		||||
class Views(di.DeclarativeCatalog):
 | 
			
		||||
class Views(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Example catalog of web views."""
 | 
			
		||||
 | 
			
		||||
    auth = di.Factory(views.AuthView,
 | 
			
		||||
                      services=Services.Bundle(Services.users,
 | 
			
		||||
                                               Services.auth))
 | 
			
		||||
    """:type: di.Provider -> views.AuthView"""
 | 
			
		||||
    auth = providers.Factory(views.Auth,
 | 
			
		||||
                             services=Services.Bundle(Services.users,
 | 
			
		||||
                                                      Services.auth))
 | 
			
		||||
    """:type: providers.Provider -> views.Auth"""
 | 
			
		||||
 | 
			
		||||
    photos = di.Factory(views.PhotosView,
 | 
			
		||||
                        services=Services.Bundle(Services.users,
 | 
			
		||||
                                                 Services.photos))
 | 
			
		||||
    """:type: di.Provider -> views.PhotosView"""
 | 
			
		||||
    photos = providers.Factory(views.Photos,
 | 
			
		||||
                               services=Services.Bundle(Services.users,
 | 
			
		||||
                                                        Services.photos))
 | 
			
		||||
    """:type: providers.Provider -> views.Photos"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating example views:
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +49,7 @@ assert auth_view.services.users is Services.users
 | 
			
		|||
assert auth_view.services.auth is Services.auth
 | 
			
		||||
try:
 | 
			
		||||
    auth_view.services.photos
 | 
			
		||||
except di.Error:
 | 
			
		||||
except errors.Error:
 | 
			
		||||
    # `photos` service provider is not in scope of `auth_view` services bundle,
 | 
			
		||||
    # so `di.Error` will be raised.
 | 
			
		||||
    pass
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +58,7 @@ assert photos_view.services.users is Services.users
 | 
			
		|||
assert photos_view.services.photos is Services.photos
 | 
			
		||||
try:
 | 
			
		||||
    photos_view.services.auth
 | 
			
		||||
except di.Error as exception:
 | 
			
		||||
except errors.Error as exception:
 | 
			
		||||
    # `auth` service provider is not in scope of `photo_processing_view`
 | 
			
		||||
    # services bundle, so `di.Error` will be raised.
 | 
			
		||||
    pass
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,13 +5,13 @@ class BaseService(object):
 | 
			
		|||
    """Example base class of service."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UsersService(BaseService):
 | 
			
		||||
class Users(BaseService):
 | 
			
		||||
    """Example users service."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AuthService(BaseService):
 | 
			
		||||
class Auth(BaseService):
 | 
			
		||||
    """Example auth service."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PhotosService(BaseService):
 | 
			
		||||
class Photos(BaseService):
 | 
			
		||||
    """Example photo service."""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,15 +7,15 @@ class BaseWebView(object):
 | 
			
		|||
    def __init__(self, services):
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :type services: catalogs.Services
 | 
			
		||||
        :param services: Bundle of service providers
 | 
			
		||||
        :type services: catalogs.Services
 | 
			
		||||
        """
 | 
			
		||||
        self.services = services
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AuthView(BaseWebView):
 | 
			
		||||
class Auth(BaseWebView):
 | 
			
		||||
    """Example auth web view."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PhotosView(BaseWebView):
 | 
			
		||||
class Photos(BaseWebView):
 | 
			
		||||
    """Example photo processing web view."""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								examples/catalogs/declarative.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
"""Declarative catalog simple example."""
 | 
			
		||||
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Defining declarative catalog:
 | 
			
		||||
class Catalog(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Providers catalog."""
 | 
			
		||||
 | 
			
		||||
    factory1 = providers.Factory(object)
 | 
			
		||||
    """:type: providers.Provider -> object"""
 | 
			
		||||
 | 
			
		||||
    factory2 = providers.Factory(object)
 | 
			
		||||
    """:type: providers.Provider -> object"""
 | 
			
		||||
 | 
			
		||||
# Creating some objects:
 | 
			
		||||
object1 = Catalog.factory1()
 | 
			
		||||
object2 = Catalog.factory2()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert object1 is not object2
 | 
			
		||||
assert isinstance(object1, object)
 | 
			
		||||
assert isinstance(object2, object)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +1,21 @@
 | 
			
		|||
"""Operating with catalog providers example."""
 | 
			
		||||
"""Declarative catalogs inheritance example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CatalogA(di.DeclarativeCatalog):
 | 
			
		||||
class CatalogA(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Example catalog A."""
 | 
			
		||||
 | 
			
		||||
    provider1 = di.Factory(object)
 | 
			
		||||
    """:type: di.Provider -> object"""
 | 
			
		||||
    provider1 = providers.Factory(object)
 | 
			
		||||
    """:type: providers.Provider -> object"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CatalogB(CatalogA):
 | 
			
		||||
    """Example catalog B."""
 | 
			
		||||
 | 
			
		||||
    provider2 = di.Singleton(object)
 | 
			
		||||
    """:type: di.Provider -> object"""
 | 
			
		||||
    provider2 = providers.Singleton(object)
 | 
			
		||||
    """:type: providers.Provider -> object"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Making some asserts for `providers` attribute:
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +30,3 @@ assert CatalogB.cls_providers == dict(provider2=CatalogB.provider2)
 | 
			
		|||
# Making some asserts for `inherited_providers` attribute:
 | 
			
		||||
assert CatalogA.inherited_providers == dict()
 | 
			
		||||
assert CatalogB.inherited_providers == dict(provider1=CatalogA.provider1)
 | 
			
		||||
 | 
			
		||||
# Making some asserts for `filter()` method:
 | 
			
		||||
assert CatalogB.filter(di.Factory) == dict(provider1=CatalogA.provider1)
 | 
			
		||||
assert CatalogB.filter(di.Singleton) == dict(provider2=CatalogB.provider2)
 | 
			
		||||
							
								
								
									
										50
									
								
								examples/catalogs/declarative_injections.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
"""Declarative catalog's provider injections example."""
 | 
			
		||||
 | 
			
		||||
import sqlite3
 | 
			
		||||
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UsersService(object):
 | 
			
		||||
    """Users service, that has dependency on database."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, db):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.db = db
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AuthService(object):
 | 
			
		||||
    """Auth service, that has dependencies on users service and database."""
 | 
			
		||||
 | 
			
		||||
    def __init__(self, db, users_service):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self.db = db
 | 
			
		||||
        self.users_service = users_service
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Services(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Catalog of service providers."""
 | 
			
		||||
 | 
			
		||||
    database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
			
		||||
    """:type: providers.Provider -> sqlite3.Connection"""
 | 
			
		||||
 | 
			
		||||
    users = providers.Factory(UsersService,
 | 
			
		||||
                              db=database)
 | 
			
		||||
    """:type: providers.Provider -> UsersService"""
 | 
			
		||||
 | 
			
		||||
    auth = providers.Factory(AuthService,
 | 
			
		||||
                             db=database,
 | 
			
		||||
                             users_service=users)
 | 
			
		||||
    """:type: providers.Provider -> AuthService"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Retrieving service providers from catalog:
 | 
			
		||||
users_service = Services.users()
 | 
			
		||||
auth_service = Services.auth()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert users_service.db is auth_service.db is Services.database()
 | 
			
		||||
assert isinstance(auth_service.users_service, UsersService)
 | 
			
		||||
assert users_service is not Services.users()
 | 
			
		||||
assert auth_service is not Services.auth()
 | 
			
		||||
							
								
								
									
										18
									
								
								examples/catalogs/dynamic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
"""Dynamic catalog simple example."""
 | 
			
		||||
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Defining dynamic catalog:
 | 
			
		||||
catalog = catalogs.DynamicCatalog(factory1=providers.Factory(object),
 | 
			
		||||
                                  factory2=providers.Factory(object))
 | 
			
		||||
 | 
			
		||||
# Creating some objects:
 | 
			
		||||
object1 = catalog.factory1()
 | 
			
		||||
object2 = catalog.factory2()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert object1 is not object2
 | 
			
		||||
assert isinstance(object1, object)
 | 
			
		||||
assert isinstance(object2, object)
 | 
			
		||||
							
								
								
									
										66
									
								
								examples/catalogs/dynamic_runtime_creation.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
"""Dynamic catalog creation and runtime filling of it example."""
 | 
			
		||||
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Defining several example services:
 | 
			
		||||
class UsersService(object):
 | 
			
		||||
    """Example users service."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AuthService(object):
 | 
			
		||||
    """Example auth service."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def import_cls(cls_name):
 | 
			
		||||
    """Import class by its fully qualified name.
 | 
			
		||||
 | 
			
		||||
    In terms of current example it is just a small helper function. Please,
 | 
			
		||||
    don't use it in production approaches.
 | 
			
		||||
    """
 | 
			
		||||
    path_components = cls_name.split('.')
 | 
			
		||||
    if len(path_components) == 1:
 | 
			
		||||
        path_components.insert(0, '__main__')
 | 
			
		||||
    module = __import__('.'.join(path_components[0:-1]),
 | 
			
		||||
                        locals(),
 | 
			
		||||
                        globals(),
 | 
			
		||||
                        fromlist=path_components[-1:])
 | 
			
		||||
    return getattr(module, path_components[-1])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# "Parsing" some configuration:
 | 
			
		||||
config = {
 | 
			
		||||
    'services': {
 | 
			
		||||
        'users': {
 | 
			
		||||
            'class': 'UsersService',
 | 
			
		||||
            'provider_class': 'dependency_injector.providers.Factory',
 | 
			
		||||
        },
 | 
			
		||||
        'auth': {
 | 
			
		||||
            'class': 'AuthService',
 | 
			
		||||
            'provider_class': 'dependency_injector.providers.Factory',
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Defining dynamic service providers catalog:
 | 
			
		||||
services = catalogs.DynamicCatalog()
 | 
			
		||||
 | 
			
		||||
# Filling dynamic service providers catalog according to the configuration:
 | 
			
		||||
for service_name, service_info in config['services'].iteritems():
 | 
			
		||||
    # Runtime importing of service and service provider classes:
 | 
			
		||||
    service_cls = import_cls(service_info['class'])
 | 
			
		||||
    service_provider_cls = import_cls(service_info['provider_class'])
 | 
			
		||||
 | 
			
		||||
    # Creating service provider:
 | 
			
		||||
    service_provider = service_provider_cls(service_cls)
 | 
			
		||||
 | 
			
		||||
    # Binding service provider to the dynamic service providers catalog:
 | 
			
		||||
    services.bind_provider(service_name, service_provider)
 | 
			
		||||
 | 
			
		||||
# Creating some objects:
 | 
			
		||||
users_service = services.users()
 | 
			
		||||
auth_service = services.auth()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert isinstance(users_service, UsersService)
 | 
			
		||||
assert isinstance(auth_service, AuthService)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,44 +0,0 @@
 | 
			
		|||
"""Catalog overriding example."""
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating some example classes:
 | 
			
		||||
Object1 = collections.namedtuple('Object1', ['arg1', 'arg2'])
 | 
			
		||||
Object2 = collections.namedtuple('Object2', ['object1'])
 | 
			
		||||
ExtendedObject2 = collections.namedtuple('ExtendedObject2', [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Catalog(di.DeclarativeCatalog):
 | 
			
		||||
    """Providers catalog."""
 | 
			
		||||
 | 
			
		||||
    object1_factory = di.Factory(Object1,
 | 
			
		||||
                                 arg1=1,
 | 
			
		||||
                                 arg2=2)
 | 
			
		||||
    """:type: di.Provider -> Object1"""
 | 
			
		||||
 | 
			
		||||
    object2_factory = di.Factory(Object2,
 | 
			
		||||
                                 object1=object1_factory)
 | 
			
		||||
    """:type: di.Provider -> Object2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AnotherCatalog(di.DeclarativeCatalog):
 | 
			
		||||
    """Another providers catalog."""
 | 
			
		||||
 | 
			
		||||
    object2_factory = di.Factory(ExtendedObject2)
 | 
			
		||||
    """:type: di.Provider -> ExtendedObject2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Overriding `Catalog` with `AnotherCatalog`:
 | 
			
		||||
Catalog.override(AnotherCatalog)
 | 
			
		||||
 | 
			
		||||
# Creating some objects using overridden catalog:
 | 
			
		||||
object2_1 = Catalog.object2_factory()
 | 
			
		||||
object2_2 = Catalog.object2_factory()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert object2_1 is not object2_2
 | 
			
		||||
 | 
			
		||||
assert isinstance(object2_1, ExtendedObject2)
 | 
			
		||||
assert isinstance(object2_2, ExtendedObject2)
 | 
			
		||||
							
								
								
									
										48
									
								
								examples/catalogs/override_declarative.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,48 @@
 | 
			
		|||
"""Declarative catalog overriding example."""
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating some example classes:
 | 
			
		||||
Object1 = collections.namedtuple('Object1', ['arg1', 'arg2'])
 | 
			
		||||
Object2 = collections.namedtuple('Object2', ['object1'])
 | 
			
		||||
ExtendedObject2 = collections.namedtuple('ExtendedObject2', [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Catalog(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Catalog of some providers."""
 | 
			
		||||
 | 
			
		||||
    object1_factory = providers.Factory(Object1,
 | 
			
		||||
                                        arg1=1,
 | 
			
		||||
                                        arg2=2)
 | 
			
		||||
    """:type: providers.Provider -> Object1"""
 | 
			
		||||
 | 
			
		||||
    object2_factory = providers.Factory(Object2,
 | 
			
		||||
                                        object1=object1_factory)
 | 
			
		||||
    """:type: providers.Provider -> Object2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AnotherCatalog(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Overriding catalog."""
 | 
			
		||||
 | 
			
		||||
    object2_factory = providers.Factory(ExtendedObject2)
 | 
			
		||||
    """:type: providers.Provider -> ExtendedObject2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Overriding `Catalog` with `AnotherCatalog`:
 | 
			
		||||
Catalog.override(AnotherCatalog)
 | 
			
		||||
 | 
			
		||||
# Creating some objects using overridden catalog:
 | 
			
		||||
object2_1 = Catalog.object2_factory()
 | 
			
		||||
object2_2 = Catalog.object2_factory()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert Catalog.is_overridden
 | 
			
		||||
 | 
			
		||||
assert object2_1 is not object2_2
 | 
			
		||||
 | 
			
		||||
assert isinstance(object2_1, ExtendedObject2)
 | 
			
		||||
assert isinstance(object2_2, ExtendedObject2)
 | 
			
		||||
							
								
								
									
										43
									
								
								examples/catalogs/override_declarative_by_dynamic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
"""Declarative catalog overriding by dynamic catalog example."""
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating some example classes:
 | 
			
		||||
Object1 = collections.namedtuple('Object1', ['arg1', 'arg2'])
 | 
			
		||||
Object2 = collections.namedtuple('Object2', ['object1'])
 | 
			
		||||
ExtendedObject2 = collections.namedtuple('ExtendedObject2', [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Catalog(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Catalog of some providers."""
 | 
			
		||||
 | 
			
		||||
    object1_factory = providers.Factory(Object1,
 | 
			
		||||
                                        arg1=1,
 | 
			
		||||
                                        arg2=2)
 | 
			
		||||
    """:type: providers.Provider -> Object1"""
 | 
			
		||||
 | 
			
		||||
    object2_factory = providers.Factory(Object2,
 | 
			
		||||
                                        object1=object1_factory)
 | 
			
		||||
    """:type: providers.Provider -> Object2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Overriding `Catalog` with some `DynamicCatalog` instance:
 | 
			
		||||
overriding_catalog = catalogs.DynamicCatalog(
 | 
			
		||||
    object2_factory=providers.Factory(ExtendedObject2))
 | 
			
		||||
Catalog.override(overriding_catalog)
 | 
			
		||||
 | 
			
		||||
# Creating some objects using overridden catalog:
 | 
			
		||||
object2_1 = Catalog.object2_factory()
 | 
			
		||||
object2_2 = Catalog.object2_factory()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert Catalog.is_overridden
 | 
			
		||||
 | 
			
		||||
assert object2_1 is not object2_2
 | 
			
		||||
 | 
			
		||||
assert isinstance(object2_1, ExtendedObject2)
 | 
			
		||||
assert isinstance(object2_2, ExtendedObject2)
 | 
			
		||||
							
								
								
									
										46
									
								
								examples/catalogs/override_declarative_decorator.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
				
			
			@ -0,0 +1,46 @@
 | 
			
		|||
"""Declarative catalog overriding using `@override()` decorator example."""
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
# Creating some example classes:
 | 
			
		||||
Object1 = collections.namedtuple('Object1', ['arg1', 'arg2'])
 | 
			
		||||
Object2 = collections.namedtuple('Object2', ['object1'])
 | 
			
		||||
ExtendedObject2 = collections.namedtuple('ExtendedObject2', [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Catalog(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Catalog of some providers."""
 | 
			
		||||
 | 
			
		||||
    object1_factory = providers.Factory(Object1,
 | 
			
		||||
                                        arg1=1,
 | 
			
		||||
                                        arg2=2)
 | 
			
		||||
    """:type: providers.Provider -> Object1"""
 | 
			
		||||
 | 
			
		||||
    object2_factory = providers.Factory(Object2,
 | 
			
		||||
                                        object1=object1_factory)
 | 
			
		||||
    """:type: providers.Provider -> Object2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Overriding `Catalog` with `AnotherCatalog`:
 | 
			
		||||
@catalogs.override(Catalog)
 | 
			
		||||
class AnotherCatalog(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Overriding catalog."""
 | 
			
		||||
 | 
			
		||||
    object2_factory = providers.Factory(ExtendedObject2)
 | 
			
		||||
    """:type: providers.Provider -> ExtendedObject2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating some objects using overridden catalog:
 | 
			
		||||
object2_1 = Catalog.object2_factory()
 | 
			
		||||
object2_2 = Catalog.object2_factory()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert Catalog.is_overridden
 | 
			
		||||
 | 
			
		||||
assert object2_1 is not object2_2
 | 
			
		||||
 | 
			
		||||
assert isinstance(object2_1, ExtendedObject2)
 | 
			
		||||
assert isinstance(object2_2, ExtendedObject2)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,43 +0,0 @@
 | 
			
		|||
"""Catalog overriding using `@di.override()` decorator example."""
 | 
			
		||||
 | 
			
		||||
import collections
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating some example classes:
 | 
			
		||||
Object1 = collections.namedtuple('Object1', ['arg1', 'arg2'])
 | 
			
		||||
Object2 = collections.namedtuple('Object2', ['object1'])
 | 
			
		||||
ExtendedObject2 = collections.namedtuple('ExtendedObject2', [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Catalog(di.DeclarativeCatalog):
 | 
			
		||||
    """Providers catalog."""
 | 
			
		||||
 | 
			
		||||
    object1_factory = di.Factory(Object1,
 | 
			
		||||
                                 arg1=1,
 | 
			
		||||
                                 arg2=2)
 | 
			
		||||
    """:type: di.Provider -> Object1"""
 | 
			
		||||
 | 
			
		||||
    object2_factory = di.Factory(Object2,
 | 
			
		||||
                                 object1=object1_factory)
 | 
			
		||||
    """:type: di.Provider -> Object2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Overriding `Catalog` with `AnotherCatalog`:
 | 
			
		||||
@di.override(Catalog)
 | 
			
		||||
class AnotherCatalog(di.DeclarativeCatalog):
 | 
			
		||||
    """Another providers catalog."""
 | 
			
		||||
 | 
			
		||||
    object2_factory = di.Factory(ExtendedObject2)
 | 
			
		||||
    """:type: di.Provider -> ExtendedObject2"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating some objects using overridden catalog:
 | 
			
		||||
object2_1 = Catalog.object2_factory()
 | 
			
		||||
object2_2 = Catalog.object2_factory()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert object2_1 is not object2_2
 | 
			
		||||
 | 
			
		||||
assert isinstance(object2_1, ExtendedObject2)
 | 
			
		||||
assert isinstance(object2_2, ExtendedObject2)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,22 +0,0 @@
 | 
			
		|||
"""Catalog example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Catalog(di.DeclarativeCatalog):
 | 
			
		||||
    """Providers catalog."""
 | 
			
		||||
 | 
			
		||||
    factory1 = di.Factory(object)
 | 
			
		||||
    """:type: di.Provider -> object"""
 | 
			
		||||
 | 
			
		||||
    factory2 = di.Factory(object)
 | 
			
		||||
    """:type: di.Provider -> object"""
 | 
			
		||||
 | 
			
		||||
# Creating some objects:
 | 
			
		||||
object1 = Catalog.factory1()
 | 
			
		||||
object2 = Catalog.factory2()
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert object1 is not object2
 | 
			
		||||
assert isinstance(object1, object)
 | 
			
		||||
assert isinstance(object2, object)
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,10 @@
 | 
			
		|||
"""Concept example of `Dependency Injector`."""
 | 
			
		||||
 | 
			
		||||
import sqlite3
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
from dependency_injector import catalogs
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
from dependency_injector import injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UsersService(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -21,20 +24,20 @@ class AuthService(object):
 | 
			
		|||
        self.users_service = users_service
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Services(di.DeclarativeCatalog):
 | 
			
		||||
class Services(catalogs.DeclarativeCatalog):
 | 
			
		||||
    """Catalog of service providers."""
 | 
			
		||||
 | 
			
		||||
    database = di.Singleton(sqlite3.connect, ':memory:')
 | 
			
		||||
    """:type: di.Provider -> sqlite3.Connection"""
 | 
			
		||||
    database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
			
		||||
    """:type: providers.Provider -> sqlite3.Connection"""
 | 
			
		||||
 | 
			
		||||
    users = di.Factory(UsersService,
 | 
			
		||||
                       db=database)
 | 
			
		||||
    """:type: di.Provider -> UsersService"""
 | 
			
		||||
    users = providers.Factory(UsersService,
 | 
			
		||||
                              db=database)
 | 
			
		||||
    """:type: providers.Provider -> UsersService"""
 | 
			
		||||
 | 
			
		||||
    auth = di.Factory(AuthService,
 | 
			
		||||
                      db=database,
 | 
			
		||||
                      users_service=users)
 | 
			
		||||
    """:type: di.Provider -> AuthService"""
 | 
			
		||||
    auth = providers.Factory(AuthService,
 | 
			
		||||
                             db=database,
 | 
			
		||||
                             users_service=users)
 | 
			
		||||
    """:type: providers.Provider -> AuthService"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Retrieving catalog providers:
 | 
			
		||||
| 
						 | 
				
			
			@ -49,9 +52,9 @@ assert auth_service is not Services.auth()
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
# Making some "inline" injections:
 | 
			
		||||
@di.inject(users_service=Services.users)
 | 
			
		||||
@di.inject(auth_service=Services.auth)
 | 
			
		||||
@di.inject(database=Services.database)
 | 
			
		||||
@injections.inject(users_service=Services.users)
 | 
			
		||||
@injections.inject(auth_service=Services.auth)
 | 
			
		||||
@injections.inject(database=Services.database)
 | 
			
		||||
def example(users_service, auth_service, database):
 | 
			
		||||
    """Example callback."""
 | 
			
		||||
    assert users_service.db is auth_service.db
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,11 @@
 | 
			
		|||
"""`di.Callable` providers with positional arguments example."""
 | 
			
		||||
"""`Callable` providers with positional arguments example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating even and odd filter providers:
 | 
			
		||||
even_filter = di.Callable(filter, lambda x: x % 2 == 0)
 | 
			
		||||
odd_filter = di.Callable(filter, lambda x: x % 2 != 0)
 | 
			
		||||
even_filter = providers.Callable(filter, lambda x: x % 2 == 0)
 | 
			
		||||
odd_filter = providers.Callable(filter, lambda x: x % 2 != 0)
 | 
			
		||||
 | 
			
		||||
# Creating even and odd ranges using xrange() and filter providers:
 | 
			
		||||
even_range = even_filter(xrange(1, 10))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,14 @@
 | 
			
		|||
"""`di.Callable` providers delegation example."""
 | 
			
		||||
"""`Callable` providers delegation example."""
 | 
			
		||||
 | 
			
		||||
import sys
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Creating some callable provider and few delegates of it:
 | 
			
		||||
callable_provider = di.Callable(sys.exit)
 | 
			
		||||
callable_provider = providers.Callable(sys.exit)
 | 
			
		||||
callable_provider_delegate1 = callable_provider.delegate()
 | 
			
		||||
callable_provider_delegate2 = di.Delegate(callable_provider)
 | 
			
		||||
callable_provider_delegate2 = providers.Delegate(callable_provider)
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert callable_provider_delegate1() is callable_provider
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,16 @@
 | 
			
		|||
"""`di.Callable` providers with keyword arguments example."""
 | 
			
		||||
"""`Callable` providers with keyword arguments example."""
 | 
			
		||||
 | 
			
		||||
import passlib.hash
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Password hasher and verifier providers (hash function could be changed
 | 
			
		||||
# anytime (for example, to sha512) without any changes in client's code):
 | 
			
		||||
password_hasher = di.Callable(passlib.hash.sha256_crypt.encrypt,
 | 
			
		||||
                              salt_size=16,
 | 
			
		||||
                              rounds=10000)
 | 
			
		||||
password_verifier = di.Callable(passlib.hash.sha256_crypt.verify)
 | 
			
		||||
password_hasher = providers.Callable(passlib.hash.sha256_crypt.encrypt,
 | 
			
		||||
                                     salt_size=16,
 | 
			
		||||
                                     rounds=10000)
 | 
			
		||||
password_verifier = providers.Callable(passlib.hash.sha256_crypt.verify)
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
hashed_password = password_hasher('super secret')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,24 +1,33 @@
 | 
			
		|||
"""Custom `di.Factory` example."""
 | 
			
		||||
"""Custom `Factory` example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UsersFactory(di.Provider):
 | 
			
		||||
class UsersFactory(providers.Provider):
 | 
			
		||||
    """Example users factory."""
 | 
			
		||||
 | 
			
		||||
    __slots__ = ('_factory',)
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        """Initializer."""
 | 
			
		||||
        self._factory = di.Factory(User)
 | 
			
		||||
        self._factory = providers.Factory(User)
 | 
			
		||||
        super(UsersFactory, self).__init__()
 | 
			
		||||
 | 
			
		||||
    def _provide(self, *args, **kwargs):
 | 
			
		||||
        """Return provided instance."""
 | 
			
		||||
        """Return provided instance.
 | 
			
		||||
 | 
			
		||||
        :param args: tuple of context positional arguments
 | 
			
		||||
        :type args: tuple[object]
 | 
			
		||||
 | 
			
		||||
        :param kwargs: dictionary of context keyword arguments
 | 
			
		||||
        :type kwargs: dict[str, object]
 | 
			
		||||
 | 
			
		||||
        :rtype: object
 | 
			
		||||
        """
 | 
			
		||||
        return self._factory(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
"""`di.ExternalDependency` providers example."""
 | 
			
		||||
"""`ExternalDependency` providers example."""
 | 
			
		||||
 | 
			
		||||
import sqlite3
 | 
			
		||||
import contextlib
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserService(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +15,8 @@ class UserService(object):
 | 
			
		|||
    def __init__(self, database):
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        Database dependency need to be injected via init arg.
 | 
			
		||||
        :param database: Database connection.
 | 
			
		||||
        :type database: sqlite3.dbapi2.Connection
 | 
			
		||||
        """
 | 
			
		||||
        self.database = database
 | 
			
		||||
        self.database.row_factory = sqlite3.dbapi2.Row
 | 
			
		||||
| 
						 | 
				
			
			@ -43,18 +45,18 @@ class UserService(object):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
# Database and UserService providers:
 | 
			
		||||
database = di.ExternalDependency(instance_of=sqlite3.dbapi2.Connection)
 | 
			
		||||
users_service_factory = di.Factory(UserService,
 | 
			
		||||
                                   database=database)
 | 
			
		||||
database = providers.ExternalDependency(instance_of=sqlite3.dbapi2.Connection)
 | 
			
		||||
users_service_factory = providers.Factory(UserService,
 | 
			
		||||
                                          database=database)
 | 
			
		||||
 | 
			
		||||
# Out of library's scope.
 | 
			
		||||
#
 | 
			
		||||
# Setting database provider:
 | 
			
		||||
database.provided_by(di.Singleton(sqlite3.dbapi2.Connection,
 | 
			
		||||
                                  database=':memory:',
 | 
			
		||||
                                  timeout=30,
 | 
			
		||||
                                  detect_types=True,
 | 
			
		||||
                                  isolation_level='EXCLUSIVE'))
 | 
			
		||||
database.provided_by(providers.Singleton(sqlite3.dbapi2.Connection,
 | 
			
		||||
                                         database=':memory:',
 | 
			
		||||
                                         timeout=30,
 | 
			
		||||
                                         detect_types=True,
 | 
			
		||||
                                         isolation_level='EXCLUSIVE'))
 | 
			
		||||
 | 
			
		||||
# Creating UserService instance:
 | 
			
		||||
users_service = users_service_factory()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,13 @@
 | 
			
		|||
"""`di.Factory` providers example."""
 | 
			
		||||
"""`Factory` providers example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
 | 
			
		||||
# Factory provider creates new instance of specified class on every call.
 | 
			
		||||
users_factory = di.Factory(User)
 | 
			
		||||
users_factory = providers.Factory(User)
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
"""`di.Factory` providers with attribute injections example."""
 | 
			
		||||
"""`Factory` providers with attribute injections example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
from dependency_injector import injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -20,11 +21,13 @@ class CreditCard(object):
 | 
			
		|||
    """Example class CreditCard."""
 | 
			
		||||
 | 
			
		||||
# User, Photo and CreditCard factories:
 | 
			
		||||
credit_cards_factory = di.Factory(CreditCard)
 | 
			
		||||
photos_factory = di.Factory(Photo)
 | 
			
		||||
users_factory = di.Factory(User,
 | 
			
		||||
                           di.Attribute('main_photo', photos_factory),
 | 
			
		||||
                           di.Attribute('credit_card', credit_cards_factory))
 | 
			
		||||
credit_cards_factory = providers.Factory(CreditCard)
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User,
 | 
			
		||||
                                  injections.Attribute('main_photo',
 | 
			
		||||
                                                       photos_factory),
 | 
			
		||||
                                  injections.Attribute('credit_card',
 | 
			
		||||
                                                       credit_cards_factory))
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
"""`di.Factory` providers delegation example."""
 | 
			
		||||
"""`Factory` providers delegation example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ class User(object):
 | 
			
		|||
    def __init__(self, photos_factory):
 | 
			
		||||
        """Initializer.
 | 
			
		||||
 | 
			
		||||
        :param photos_factory: (di.Factory) -> Photo
 | 
			
		||||
        :param photos_factory: providers.Factory -> Photo
 | 
			
		||||
        """
 | 
			
		||||
        self.photos_factory = photos_factory
 | 
			
		||||
        self._main_photo = None
 | 
			
		||||
| 
						 | 
				
			
			@ -27,9 +27,9 @@ class Photo(object):
 | 
			
		|||
    """Example class Photo."""
 | 
			
		||||
 | 
			
		||||
# User and Photo factories:
 | 
			
		||||
photos_factory = di.Factory(Photo)
 | 
			
		||||
users_factory = di.Factory(User,
 | 
			
		||||
                           photos_factory=di.Delegate(photos_factory))
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User,
 | 
			
		||||
                                  photos_factory=photos_factory.delegate())
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
"""`di.Factory` providers with init positional injections example."""
 | 
			
		||||
"""`Factory` providers with init positional injections example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -16,8 +16,8 @@ class Photo(object):
 | 
			
		|||
    """Example class Photo."""
 | 
			
		||||
 | 
			
		||||
# User and Photo factories:
 | 
			
		||||
photos_factory = di.Factory(Photo)
 | 
			
		||||
users_factory = di.Factory(User, photos_factory)
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User, photos_factory)
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()  # Same as: user1 = User(Photo())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
"""`di.Factory` providers with init injections priority example."""
 | 
			
		||||
"""`Factory` providers with init injections priority example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -30,11 +30,11 @@ class CreditCard(object):
 | 
			
		|||
    """Example class CreditCard."""
 | 
			
		||||
 | 
			
		||||
# User, Photo and CreditCard factories:
 | 
			
		||||
credit_cards_factory = di.Factory(CreditCard)
 | 
			
		||||
photos_factory = di.Factory(Photo)
 | 
			
		||||
users_factory = di.Factory(User,
 | 
			
		||||
                           main_photo=photos_factory,
 | 
			
		||||
                           credit_card=credit_cards_factory)
 | 
			
		||||
credit_cards_factory = providers.Factory(CreditCard)
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User,
 | 
			
		||||
                                  main_photo=photos_factory,
 | 
			
		||||
                                  credit_card=credit_cards_factory)
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory(1)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
"""`di.Factory` providers with init keyword injections example."""
 | 
			
		||||
"""`Factory` providers with init keyword injections example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -16,8 +16,8 @@ class Photo(object):
 | 
			
		|||
    """Example class Photo."""
 | 
			
		||||
 | 
			
		||||
# User and Photo factories:
 | 
			
		||||
photos_factory = di.Factory(Photo)
 | 
			
		||||
users_factory = di.Factory(User, main_photo=photos_factory)
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User, main_photo=photos_factory)
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()  # Same as: user1 = User(main_photo=Photo())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
"""`di.Factory` providers with method injections example."""
 | 
			
		||||
"""`Factory` providers with method injections example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
from dependency_injector import injections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -28,11 +29,13 @@ class CreditCard(object):
 | 
			
		|||
    """Example class CreditCard."""
 | 
			
		||||
 | 
			
		||||
# User, Photo and CreditCard factories:
 | 
			
		||||
credit_cards_factory = di.Factory(CreditCard)
 | 
			
		||||
photos_factory = di.Factory(Photo)
 | 
			
		||||
users_factory = di.Factory(User,
 | 
			
		||||
                           di.Method('set_main_photo', photos_factory),
 | 
			
		||||
                           di.Method('set_credit_card', credit_cards_factory))
 | 
			
		||||
credit_cards_factory = providers.Factory(CreditCard)
 | 
			
		||||
photos_factory = providers.Factory(Photo)
 | 
			
		||||
users_factory = providers.Factory(User,
 | 
			
		||||
                                  injections.Method('set_main_photo',
 | 
			
		||||
                                                    photos_factory),
 | 
			
		||||
                                  injections.Method('set_credit_card',
 | 
			
		||||
                                                    credit_cards_factory))
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,13 @@
 | 
			
		|||
"""Simple providers overriding example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
    """Example class User."""
 | 
			
		||||
 | 
			
		||||
# Users factory:
 | 
			
		||||
users_factory = di.Factory(User)
 | 
			
		||||
users_factory = providers.Factory(User)
 | 
			
		||||
 | 
			
		||||
# Creating several User objects:
 | 
			
		||||
user1 = users_factory()
 | 
			
		||||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ class SuperUser(User):
 | 
			
		|||
    """Example class SuperUser."""
 | 
			
		||||
 | 
			
		||||
# Overriding users factory:
 | 
			
		||||
users_factory.override(di.Factory(SuperUser))
 | 
			
		||||
users_factory.override(providers.Factory(SuperUser))
 | 
			
		||||
 | 
			
		||||
# Creating some more User objects using overridden users factory:
 | 
			
		||||
user3 = users_factory()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
"""Overriding user's model example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -26,8 +26,7 @@ class UserService(object):
 | 
			
		|||
        return self.user_cls(id=id, password='secret' + str(id))
 | 
			
		||||
 | 
			
		||||
# Users factory and UserService provider:
 | 
			
		||||
users_service = di.Factory(UserService,
 | 
			
		||||
                           user_cls=User)
 | 
			
		||||
users_service = providers.Factory(UserService, user_cls=User)
 | 
			
		||||
 | 
			
		||||
# Getting several users and making some asserts:
 | 
			
		||||
user1 = users_service().get_by_id(1)
 | 
			
		||||
| 
						 | 
				
			
			@ -71,8 +70,8 @@ class ExtendedUserService(UserService):
 | 
			
		|||
        return user
 | 
			
		||||
 | 
			
		||||
# Overriding users_service provider:
 | 
			
		||||
extended_users_service = di.Factory(ExtendedUserService,
 | 
			
		||||
                                    user_cls=ExtendedUser)
 | 
			
		||||
extended_users_service = providers.Factory(ExtendedUserService,
 | 
			
		||||
                                           user_cls=ExtendedUser)
 | 
			
		||||
users_service.override(extended_users_service)
 | 
			
		||||
 | 
			
		||||
# Getting few other users users and making some asserts:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
"""`di.Singleton` providers example."""
 | 
			
		||||
"""`Singleton` providers example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserService(object):
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ class UserService(object):
 | 
			
		|||
 | 
			
		||||
# Singleton provider creates new instance of specified class on first call and
 | 
			
		||||
# returns same instance on every next call.
 | 
			
		||||
users_service_provider = di.Singleton(UserService)
 | 
			
		||||
users_service_provider = providers.Singleton(UserService)
 | 
			
		||||
 | 
			
		||||
# Retrieving several UserService objects:
 | 
			
		||||
user_service1 = users_service_provider()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,12 @@
 | 
			
		|||
"""`di.Singleton` providers delegation example."""
 | 
			
		||||
"""`Singleton` providers delegation example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Some singleton provider and few delegates of it:
 | 
			
		||||
singleton_provider = di.Singleton(object)
 | 
			
		||||
singleton_provider = providers.Singleton(object)
 | 
			
		||||
singleton_provider_delegate1 = singleton_provider.delegate()
 | 
			
		||||
singleton_provider_delegate2 = di.Delegate(singleton_provider)
 | 
			
		||||
singleton_provider_delegate2 = providers.Delegate(singleton_provider)
 | 
			
		||||
 | 
			
		||||
# Making some asserts:
 | 
			
		||||
assert singleton_provider_delegate1() is singleton_provider
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,13 @@
 | 
			
		|||
"""`di.Singleton` providers resetting example."""
 | 
			
		||||
"""`Singleton` providers resetting example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UserService(object):
 | 
			
		||||
    """Example class UserService."""
 | 
			
		||||
 | 
			
		||||
# Users service singleton provider:
 | 
			
		||||
users_service_provider = di.Singleton(UserService)
 | 
			
		||||
users_service_provider = providers.Singleton(UserService)
 | 
			
		||||
 | 
			
		||||
# Retrieving several UserService objects:
 | 
			
		||||
user_service1 = users_service_provider()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,20 +1,20 @@
 | 
			
		|||
"""Static providers example."""
 | 
			
		||||
 | 
			
		||||
import dependency_injector as di
 | 
			
		||||
from dependency_injector import providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Provides class - `object`:
 | 
			
		||||
cls_provider = di.Class(object)
 | 
			
		||||
cls_provider = providers.Class(object)
 | 
			
		||||
assert cls_provider() is object
 | 
			
		||||
 | 
			
		||||
# Provides object - `object()`:
 | 
			
		||||
object_provider = di.Object(object())
 | 
			
		||||
object_provider = providers.Object(object())
 | 
			
		||||
assert isinstance(object_provider(), object)
 | 
			
		||||
 | 
			
		||||
# Provides function - `len`:
 | 
			
		||||
function_provider = di.Function(len)
 | 
			
		||||
function_provider = providers.Function(len)
 | 
			
		||||
assert function_provider() is len
 | 
			
		||||
 | 
			
		||||
# Provides value - `123`:
 | 
			
		||||
value_provider = di.Value(123)
 | 
			
		||||
value_provider = providers.Value(123)
 | 
			
		||||
assert value_provider() == 123
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1,13 @@
 | 
			
		|||
"""Dependency injector unittests."""
 | 
			
		||||
 | 
			
		||||
import unittest2 as unittest
 | 
			
		||||
 | 
			
		||||
from dependency_injector import VERSION
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VersionTest(unittest.TestCase):
 | 
			
		||||
    """Version constant tests."""
 | 
			
		||||
 | 
			
		||||
    def test_version_follows_semantic_versioning(self):
 | 
			
		||||
        """Test that version follows semantic versioning."""
 | 
			
		||||
        self.assertEquals(len(VERSION.split('.')))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -282,11 +282,9 @@ class DeclarativeCatalogTests(unittest.TestCase):
 | 
			
		|||
 | 
			
		||||
        self.assertIs(CatalogA.px, px)
 | 
			
		||||
        self.assertIs(CatalogA.get_provider('px'), px)
 | 
			
		||||
        self.assertIs(CatalogA.catalog.px, px)
 | 
			
		||||
 | 
			
		||||
        self.assertIs(CatalogA.py, py)
 | 
			
		||||
        self.assertIs(CatalogA.get_provider('py'), py)
 | 
			
		||||
        self.assertIs(CatalogA.catalog.py, py)
 | 
			
		||||
 | 
			
		||||
        del CatalogA.px
 | 
			
		||||
        del CatalogA.py
 | 
			
		||||
| 
						 | 
				
			
			@ -300,11 +298,9 @@ class DeclarativeCatalogTests(unittest.TestCase):
 | 
			
		|||
 | 
			
		||||
        self.assertIs(CatalogB.px, px)
 | 
			
		||||
        self.assertIs(CatalogB.get_provider('px'), px)
 | 
			
		||||
        self.assertIs(CatalogB.catalog.px, px)
 | 
			
		||||
 | 
			
		||||
        self.assertIs(CatalogB.py, py)
 | 
			
		||||
        self.assertIs(CatalogB.get_provider('py'), py)
 | 
			
		||||
        self.assertIs(CatalogB.catalog.py, py)
 | 
			
		||||
 | 
			
		||||
        del CatalogB.px
 | 
			
		||||
        del CatalogB.py
 | 
			
		||||
| 
						 | 
				
			
			@ -319,11 +315,9 @@ class DeclarativeCatalogTests(unittest.TestCase):
 | 
			
		|||
 | 
			
		||||
        self.assertIs(CatalogB.px, px)
 | 
			
		||||
        self.assertIs(CatalogB.get_provider('px'), px)
 | 
			
		||||
        self.assertIs(CatalogB.catalog.px, px)
 | 
			
		||||
 | 
			
		||||
        self.assertIs(CatalogB.py, py)
 | 
			
		||||
        self.assertIs(CatalogB.get_provider('py'), py)
 | 
			
		||||
        self.assertIs(CatalogB.catalog.py, py)
 | 
			
		||||
 | 
			
		||||
        del CatalogB.px
 | 
			
		||||
        del CatalogB.py
 | 
			
		||||
| 
						 | 
				
			
			@ -480,6 +474,23 @@ class OverrideTests(unittest.TestCase):
 | 
			
		|||
        self.assertEqual(CatalogA.p12(), 2)
 | 
			
		||||
        self.assertEqual(len(CatalogA.overridden_by), 1)
 | 
			
		||||
 | 
			
		||||
    def test_override_declarative_catalog_with_itself(self):
 | 
			
		||||
        """Test catalog overriding of declarative catalog with itself."""
 | 
			
		||||
        with self.assertRaises(errors.Error):
 | 
			
		||||
            CatalogA.override(CatalogA)
 | 
			
		||||
 | 
			
		||||
    def test_override_declarative_catalog_with_subclass(self):
 | 
			
		||||
        """Test catalog overriding of declarative catalog with subclass."""
 | 
			
		||||
        with self.assertRaises(errors.Error):
 | 
			
		||||
            CatalogB.override(CatalogA)
 | 
			
		||||
 | 
			
		||||
    def test_override_dynamic_catalog_with_itself(self):
 | 
			
		||||
        """Test catalog overriding of dynamic catalog with itself."""
 | 
			
		||||
        catalog = catalogs.DynamicCatalog(p11=providers.Value(1),
 | 
			
		||||
                                          p12=providers.Value(2))
 | 
			
		||||
        with self.assertRaises(errors.Error):
 | 
			
		||||
            catalog.override(catalog)
 | 
			
		||||
 | 
			
		||||
    def test_overriding_with_dynamic_catalog(self):
 | 
			
		||||
        """Test catalog overriding with another dynamic catalog."""
 | 
			
		||||
        CatalogA.override(catalogs.DynamicCatalog(p11=providers.Value(1),
 | 
			
		||||
| 
						 | 
				
			
			@ -512,8 +523,7 @@ class OverrideTests(unittest.TestCase):
 | 
			
		|||
 | 
			
		||||
    def test_last_overriding_on_not_overridden(self):
 | 
			
		||||
        """Test catalog last_overriding property on not overridden catalog."""
 | 
			
		||||
        with self.assertRaises(errors.Error):
 | 
			
		||||
            CatalogA.last_overriding
 | 
			
		||||
        self.assertIsNone(CatalogA.last_overriding)
 | 
			
		||||
 | 
			
		||||
    def test_reset_last_overriding(self):
 | 
			
		||||
        """Test resetting last overriding catalog."""
 | 
			
		||||
| 
						 | 
				
			
			@ -561,3 +571,14 @@ class OverrideTests(unittest.TestCase):
 | 
			
		|||
 | 
			
		||||
        self.assertFalse(CatalogA.p11.is_overridden)
 | 
			
		||||
        self.assertFalse(CatalogA.p12.is_overridden)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CatalogModuleBackwardCompatibility(unittest.TestCase):
 | 
			
		||||
    """Backward compatibility test of catalog module."""
 | 
			
		||||
 | 
			
		||||
    def test_import_catalog(self):
 | 
			
		||||
        """Test that module `catalog` is the same as `catalogs`."""
 | 
			
		||||
        from dependency_injector import catalog
 | 
			
		||||
        from dependency_injector import catalogs
 | 
			
		||||
 | 
			
		||||
        self.assertIs(catalog, catalogs)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,13 +90,7 @@ class ProviderTests(unittest.TestCase):
 | 
			
		|||
 | 
			
		||||
    def test_last_overriding_of_not_overridden_provider(self):
 | 
			
		||||
        """Test getting last overriding from not overridden provider."""
 | 
			
		||||
        try:
 | 
			
		||||
            self.provider.last_overriding
 | 
			
		||||
        except errors.Error:
 | 
			
		||||
            pass
 | 
			
		||||
        else:
 | 
			
		||||
            self.fail('Got en error in {}'.format(
 | 
			
		||||
                str(self.test_last_overriding_of_not_overridden_provider)))
 | 
			
		||||
        self.assertIsNone(self.provider.last_overriding)
 | 
			
		||||
 | 
			
		||||
    def test_reset_last_overriding(self):
 | 
			
		||||
        """Test reseting of last overriding provider."""
 | 
			
		||||
| 
						 | 
				
			
			@ -129,13 +123,7 @@ class ProviderTests(unittest.TestCase):
 | 
			
		|||
        self.provider.reset_override()
 | 
			
		||||
 | 
			
		||||
        self.assertFalse(self.provider.is_overridden)
 | 
			
		||||
        try:
 | 
			
		||||
            self.provider.last_overriding
 | 
			
		||||
        except errors.Error:
 | 
			
		||||
            pass
 | 
			
		||||
        else:
 | 
			
		||||
            self.fail('Got en error in {}'.format(
 | 
			
		||||
                str(self.test_last_overriding_of_not_overridden_provider)))
 | 
			
		||||
        self.assertIsNone(self.provider.last_overriding)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DelegateTests(unittest.TestCase):
 | 
			
		||||
| 
						 | 
				
			
			@ -564,6 +552,35 @@ class SingletonTests(unittest.TestCase):
 | 
			
		|||
        self.assertIsInstance(instance1, object)
 | 
			
		||||
        self.assertIsInstance(instance2, object)
 | 
			
		||||
 | 
			
		||||
    def test_provides_attr(self):
 | 
			
		||||
        """Test provides attribute."""
 | 
			
		||||
        provider = providers.Singleton(Example)
 | 
			
		||||
        self.assertIs(provider.provides, Example)
 | 
			
		||||
 | 
			
		||||
    def test_args_attr(self):
 | 
			
		||||
        """Test args attribute."""
 | 
			
		||||
        provider = providers.Singleton(Example, 1, 2)
 | 
			
		||||
        self.assertEquals(len(provider.args), 2)
 | 
			
		||||
 | 
			
		||||
    def test_kwargs_attr(self):
 | 
			
		||||
        """Test kwargs attribute."""
 | 
			
		||||
        provider = providers.Singleton(Example, init_arg1=1, init_arg2=2)
 | 
			
		||||
        self.assertEquals(len(provider.kwargs), 2)
 | 
			
		||||
 | 
			
		||||
    def test_attributes_attr(self):
 | 
			
		||||
        """Test attributes attribute."""
 | 
			
		||||
        provider = providers.Singleton(Example,
 | 
			
		||||
                                       injections.Attribute('attribute1', 1),
 | 
			
		||||
                                       injections.Attribute('attribute2', 2))
 | 
			
		||||
        self.assertEquals(len(provider.attributes), 2)
 | 
			
		||||
 | 
			
		||||
    def test_methods_attr(self):
 | 
			
		||||
        """Test methods attribute."""
 | 
			
		||||
        provider = providers.Singleton(Example,
 | 
			
		||||
                                       injections.Method('method1', 1),
 | 
			
		||||
                                       injections.Method('method2', 2))
 | 
			
		||||
        self.assertEquals(len(provider.methods), 2)
 | 
			
		||||
 | 
			
		||||
    def test_injections(self):
 | 
			
		||||
        """Test getting a full list of injections using injections property."""
 | 
			
		||||
        provider = providers.Singleton(Example,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||