Merge remote-tracking branch 'origin/2.0'
							
								
								
									
										135
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						| 
						 | 
					@ -23,9 +23,6 @@ Status
 | 
				
			||||||
| *PyPi*                                | .. image:: https://img.shields.io/pypi/v/dependency_injector.svg                       |
 | 
					| *PyPi*                                | .. image:: https://img.shields.io/pypi/v/dependency_injector.svg                       |
 | 
				
			||||||
|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
					|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
				
			||||||
|                                       |    :alt: Latest Version                                                                |
 | 
					|                                       |    :alt: Latest Version                                                                |
 | 
				
			||||||
|                                       | .. image:: https://img.shields.io/pypi/dm/dependency_injector.svg                      |
 | 
					 | 
				
			||||||
|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
					 | 
				
			||||||
|                                       |    :alt: Downloads                                                                     |
 | 
					 | 
				
			||||||
|                                       | .. image:: https://img.shields.io/pypi/l/dependency_injector.svg                       |
 | 
					|                                       | .. image:: https://img.shields.io/pypi/l/dependency_injector.svg                       |
 | 
				
			||||||
|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
					|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
				
			||||||
|                                       |    :alt: License                                                                       |
 | 
					|                                       |    :alt: License                                                                       |
 | 
				
			||||||
| 
						 | 
					@ -55,61 +52,133 @@ Installation
 | 
				
			||||||
Example
 | 
					Example
 | 
				
			||||||
-------
 | 
					-------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Brief example below demonstrates usage of *Dependency Injector* containers and 
 | 
				
			||||||
 | 
					providers for definition of several IoC containers for some microservice 
 | 
				
			||||||
 | 
					system that consists from several business and platform services:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code-block:: python
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """Dependency Injector example."""
 | 
					    """Example of several Dependency Injector IoC containers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    import sys
 | 
					 | 
				
			||||||
    import sqlite3
 | 
					    import sqlite3
 | 
				
			||||||
 | 
					    import boto.s3.connection
 | 
				
			||||||
 | 
					    import example.services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from boto.s3.connection import S3Connection
 | 
					    import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					    import dependency_injector.providers as providers
 | 
				
			||||||
    from dependency_injector import catalogs
 | 
					 | 
				
			||||||
    from dependency_injector import providers
 | 
					 | 
				
			||||||
    from dependency_injector import injections
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    from example import services
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Platform(catalogs.DeclarativeCatalog):
 | 
					    class Platform(containers.DeclarativeContainer):
 | 
				
			||||||
        """Catalog of platform service providers."""
 | 
					        """IoC container of platform service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
					        database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        s3 = providers.Singleton(S3Connection,
 | 
					        s3 = providers.Singleton(boto.s3.connection.S3Connection,
 | 
				
			||||||
                                 aws_access_key_id='KEY',
 | 
					                                 aws_access_key_id='KEY',
 | 
				
			||||||
                                 aws_secret_access_key='SECRET')
 | 
					                                 aws_secret_access_key='SECRET')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Services(catalogs.DeclarativeCatalog):
 | 
					    class Services(containers.DeclarativeContainer):
 | 
				
			||||||
        """Catalog of business service providers."""
 | 
					        """IoC container of business service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        users = providers.Factory(services.Users,
 | 
					        users = providers.Factory(example.services.Users,
 | 
				
			||||||
                                  db=Platform.database)
 | 
					                                  db=Platform.database)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        photos = providers.Factory(services.Photos,
 | 
					        auth = providers.Factory(example.services.Auth,
 | 
				
			||||||
                                   db=Platform.database,
 | 
					 | 
				
			||||||
                                   s3=Platform.s3)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auth = providers.Factory(services.Auth,
 | 
					 | 
				
			||||||
                                 db=Platform.database,
 | 
					                                 db=Platform.database,
 | 
				
			||||||
                                 token_ttl=3600)
 | 
					                                 token_ttl=3600)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        photos = providers.Factory(example.services.Photos,
 | 
				
			||||||
 | 
					                                   db=Platform.database,
 | 
				
			||||||
 | 
					                                   s3=Platform.s3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @injections.inject(users_service=Services.users)
 | 
					Next example demonstrates usage of ``@inject`` decorator with IoC containers 
 | 
				
			||||||
    @injections.inject(auth_service=Services.auth)
 | 
					defined above: 
 | 
				
			||||||
    @injections.inject(photos_service=Services.photos)
 | 
					
 | 
				
			||||||
    def main(argv, users_service, auth_service, photos_service):
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """Dependency Injector @inject decorator example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    import application
 | 
				
			||||||
 | 
					    import dependency_injector.injections as injections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @injections.inject(users_service=application.Services.users)
 | 
				
			||||||
 | 
					    @injections.inject(auth_service=application.Services.auth)
 | 
				
			||||||
 | 
					    @injections.inject(photos_service=application.Services.photos)
 | 
				
			||||||
 | 
					    def main(users_service, auth_service, photos_service):
 | 
				
			||||||
        """Main function."""
 | 
					        """Main function."""
 | 
				
			||||||
        login, password, photo_path = argv[1:]
 | 
					        user = users_service.get_user('user')
 | 
				
			||||||
 | 
					        auth_service.authenticate(user, 'secret')
 | 
				
			||||||
        user = users_service.get_user(login)
 | 
					        photos_service.upload_photo(user['id'], 'photo.jpg')
 | 
				
			||||||
        auth_service.authenticate(user, password)
 | 
					 | 
				
			||||||
        photos_service.upload_photo(user['id'], photo_path)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if __name__ == '__main__':
 | 
					    if __name__ == '__main__':
 | 
				
			||||||
        main(sys.argv)
 | 
					        main()
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					Alternative definition styles
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*Dependecy Injector* supports few other styles of dependency injections 
 | 
				
			||||||
 | 
					definition.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					IoC containers from previous example could look like these:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Platform(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					        """IoC container of platform service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        database = providers.Singleton(sqlite3.connect) \
 | 
				
			||||||
 | 
					            .add_args(':memory:')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        s3 = providers.Singleton(boto.s3.connection.S3Connection) \
 | 
				
			||||||
 | 
					            .add_kwargs(aws_access_key_id='KEY',
 | 
				
			||||||
 | 
					                        aws_secret_access_key='SECRET')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Services(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					        """IoC container of business service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        users = providers.Factory(example.services.Users) \
 | 
				
			||||||
 | 
					            .add_kwargs(db=Platform.database)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auth = providers.Factory(example.services.Auth) \
 | 
				
			||||||
 | 
					            .add_kwargs(db=Platform.database,
 | 
				
			||||||
 | 
					                        token_ttl=3600)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        photos = providers.Factory(example.services.Photos) \
 | 
				
			||||||
 | 
					            .add_kwargs(db=Platform.database,
 | 
				
			||||||
 | 
					                        s3=Platform.s3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					or like this these:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Platform(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					        """IoC container of platform service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        database = providers.Singleton(sqlite3.connect)
 | 
				
			||||||
 | 
					        database.add_args(':memory:')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        s3 = providers.Singleton(boto.s3.connection.S3Connection)
 | 
				
			||||||
 | 
					        s3.add_kwargs(aws_access_key_id='KEY',
 | 
				
			||||||
 | 
					                      aws_secret_access_key='SECRET')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class Services(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					        """IoC container of business service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        users = providers.Factory(example.services.Users)
 | 
				
			||||||
 | 
					        users.add_kwargs(db=Platform.database)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auth = providers.Factory(example.services.Auth)
 | 
				
			||||||
 | 
					        auth.add_kwargs(db=Platform.database,
 | 
				
			||||||
 | 
					                        token_ttl=3600)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        photos = providers.Factory(example.services.Photos)
 | 
				
			||||||
 | 
					        photos.add_kwargs(db=Platform.database,
 | 
				
			||||||
 | 
					                          s3=Platform.s3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can get more *Dependency Injector* examples in ``/examples`` directory on
 | 
					You can get more *Dependency Injector* examples in ``/examples`` directory on
 | 
				
			||||||
GitHub:
 | 
					GitHub:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,126 +1,7 @@
 | 
				
			||||||
"""Dependency injector."""
 | 
					"""Dependency injector top-level package."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector.catalogs import (
 | 
					VERSION = '2.0.0'
 | 
				
			||||||
    DeclarativeCatalog,
 | 
					 | 
				
			||||||
    AbstractCatalog,
 | 
					 | 
				
			||||||
    DynamicCatalog,
 | 
					 | 
				
			||||||
    CatalogBundle,
 | 
					 | 
				
			||||||
    override,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.providers import (
 | 
					 | 
				
			||||||
    Provider,
 | 
					 | 
				
			||||||
    Delegate,
 | 
					 | 
				
			||||||
    Callable,
 | 
					 | 
				
			||||||
    DelegatedCallable,
 | 
					 | 
				
			||||||
    Factory,
 | 
					 | 
				
			||||||
    DelegatedFactory,
 | 
					 | 
				
			||||||
    Singleton,
 | 
					 | 
				
			||||||
    DelegatedSingleton,
 | 
					 | 
				
			||||||
    ExternalDependency,
 | 
					 | 
				
			||||||
    StaticProvider,
 | 
					 | 
				
			||||||
    Class,
 | 
					 | 
				
			||||||
    Object,
 | 
					 | 
				
			||||||
    Function,
 | 
					 | 
				
			||||||
    Value,
 | 
					 | 
				
			||||||
    Config,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.injections import (
 | 
					 | 
				
			||||||
    Injection,
 | 
					 | 
				
			||||||
    Arg,
 | 
					 | 
				
			||||||
    KwArg,
 | 
					 | 
				
			||||||
    Attribute,
 | 
					 | 
				
			||||||
    Method,
 | 
					 | 
				
			||||||
    inject,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.utils import (
 | 
					 | 
				
			||||||
    is_provider,
 | 
					 | 
				
			||||||
    ensure_is_provider,
 | 
					 | 
				
			||||||
    is_delegated_provider,
 | 
					 | 
				
			||||||
    is_injection,
 | 
					 | 
				
			||||||
    ensure_is_injection,
 | 
					 | 
				
			||||||
    is_arg_injection,
 | 
					 | 
				
			||||||
    is_kwarg_injection,
 | 
					 | 
				
			||||||
    is_attribute_injection,
 | 
					 | 
				
			||||||
    is_method_injection,
 | 
					 | 
				
			||||||
    is_catalog,
 | 
					 | 
				
			||||||
    is_dynamic_catalog,
 | 
					 | 
				
			||||||
    is_declarative_catalog,
 | 
					 | 
				
			||||||
    is_catalog_bundle,
 | 
					 | 
				
			||||||
    ensure_is_catalog_bundle,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.errors import (
 | 
					 | 
				
			||||||
    Error,
 | 
					 | 
				
			||||||
    UndefinedProviderError,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Backward compatibility for versions < 0.11.*
 | 
					 | 
				
			||||||
from dependency_injector import catalogs
 | 
					 | 
				
			||||||
catalog = catalogs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VERSION = '1.17.0'
 | 
					 | 
				
			||||||
"""Version number that follows semantic versioning.
 | 
					"""Version number that follows semantic versioning.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:type: str
 | 
					:type: str
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
__all__ = (
 | 
					 | 
				
			||||||
    # Catalogs
 | 
					 | 
				
			||||||
    'DeclarativeCatalog',
 | 
					 | 
				
			||||||
    'AbstractCatalog',
 | 
					 | 
				
			||||||
    'DynamicCatalog',
 | 
					 | 
				
			||||||
    'CatalogBundle',
 | 
					 | 
				
			||||||
    'override',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Providers
 | 
					 | 
				
			||||||
    'Provider',
 | 
					 | 
				
			||||||
    'Delegate',
 | 
					 | 
				
			||||||
    'Callable',
 | 
					 | 
				
			||||||
    'DelegatedCallable',
 | 
					 | 
				
			||||||
    'Factory',
 | 
					 | 
				
			||||||
    'DelegatedFactory',
 | 
					 | 
				
			||||||
    'Singleton',
 | 
					 | 
				
			||||||
    'DelegatedSingleton',
 | 
					 | 
				
			||||||
    'ExternalDependency',
 | 
					 | 
				
			||||||
    'StaticProvider',
 | 
					 | 
				
			||||||
    'Class',
 | 
					 | 
				
			||||||
    'Object',
 | 
					 | 
				
			||||||
    'Function',
 | 
					 | 
				
			||||||
    'Value',
 | 
					 | 
				
			||||||
    'Config',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Injections
 | 
					 | 
				
			||||||
    'Injection',
 | 
					 | 
				
			||||||
    'Arg',
 | 
					 | 
				
			||||||
    'KwArg',
 | 
					 | 
				
			||||||
    'Attribute',
 | 
					 | 
				
			||||||
    'Method',
 | 
					 | 
				
			||||||
    'inject',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Utils
 | 
					 | 
				
			||||||
    'is_provider',
 | 
					 | 
				
			||||||
    'ensure_is_provider',
 | 
					 | 
				
			||||||
    'is_delegated_provider',
 | 
					 | 
				
			||||||
    'is_injection',
 | 
					 | 
				
			||||||
    'ensure_is_injection',
 | 
					 | 
				
			||||||
    'is_arg_injection',
 | 
					 | 
				
			||||||
    'is_kwarg_injection',
 | 
					 | 
				
			||||||
    'is_attribute_injection',
 | 
					 | 
				
			||||||
    'is_method_injection',
 | 
					 | 
				
			||||||
    'is_catalog',
 | 
					 | 
				
			||||||
    'is_dynamic_catalog',
 | 
					 | 
				
			||||||
    'is_declarative_catalog',
 | 
					 | 
				
			||||||
    'is_catalog_bundle',
 | 
					 | 
				
			||||||
    'ensure_is_catalog_bundle',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Errors
 | 
					 | 
				
			||||||
    'Error',
 | 
					 | 
				
			||||||
    'UndefinedProviderError',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Version
 | 
					 | 
				
			||||||
    'VERSION'
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,24 +0,0 @@
 | 
				
			||||||
"""Dependency injector catalogs package."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.catalogs.bundle import CatalogBundle
 | 
					 | 
				
			||||||
from dependency_injector.catalogs.dynamic import DynamicCatalog
 | 
					 | 
				
			||||||
from dependency_injector.catalogs.declarative import (
 | 
					 | 
				
			||||||
    DeclarativeCatalogMetaClass,
 | 
					 | 
				
			||||||
    DeclarativeCatalog,
 | 
					 | 
				
			||||||
    AbstractCatalog,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from dependency_injector.catalogs.utils import (
 | 
					 | 
				
			||||||
    copy,
 | 
					 | 
				
			||||||
    override
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
__all__ = (
 | 
					 | 
				
			||||||
    'CatalogBundle',
 | 
					 | 
				
			||||||
    'DynamicCatalog',
 | 
					 | 
				
			||||||
    'DeclarativeCatalogMetaClass',
 | 
					 | 
				
			||||||
    'DeclarativeCatalog',
 | 
					 | 
				
			||||||
    'AbstractCatalog',
 | 
					 | 
				
			||||||
    'copy',
 | 
					 | 
				
			||||||
    'override',
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,118 +0,0 @@
 | 
				
			||||||
"""Dependency injector catalogs bundle module."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import six
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.errors import (
 | 
					 | 
				
			||||||
    Error,
 | 
					 | 
				
			||||||
    UndefinedProviderError,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class CatalogBundle(object):
 | 
					 | 
				
			||||||
    """Bundle of catalog providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`CatalogBundle` is a frozen, limited collection of catalog
 | 
					 | 
				
			||||||
    providers. While catalog could be used as a centralized place for
 | 
					 | 
				
			||||||
    particular providers group, such bundles of catalog providers can be used
 | 
					 | 
				
			||||||
    for creating several frozen, limited scopes that could be passed to
 | 
					 | 
				
			||||||
    different subsystems.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`CatalogBundle` has API's parity with catalogs
 | 
					 | 
				
			||||||
    (:py:class:`DeclarativeCatalog` or :py:class:`DynamicCatalog`) in terms of
 | 
					 | 
				
			||||||
    retrieving the providers, but it is "frozen" in terms of modification
 | 
					 | 
				
			||||||
    provider's list.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`CatalogBundle` is considered to be dependable on catalogs
 | 
					 | 
				
			||||||
    (:py:class:`DeclarativeCatalog` or :py:class:`DynamicCatalog`) entity by
 | 
					 | 
				
			||||||
    its design.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: catalog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Bundle's catalog.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Dictionary of all providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    catalog = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __IS_CATALOG_BUNDLE__ = True
 | 
					 | 
				
			||||||
    __slots__ = ('providers', '__dict__')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def sub_cls_factory(cls, catalog):
 | 
					 | 
				
			||||||
        """Create bundle subclass for catalog.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :return: Subclass of :py:class:`CatalogBundle`.
 | 
					 | 
				
			||||||
        :rtype: :py:class:`CatalogBundle`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return type('BundleSubclass', (cls,), dict(catalog=catalog))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, *providers):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param providers: Tuple of catalog's bundle providers.
 | 
					 | 
				
			||||||
        :type providers: tuple[
 | 
					 | 
				
			||||||
            :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.providers = dict((self.catalog.get_provider_bind_name(provider),
 | 
					 | 
				
			||||||
                               provider)
 | 
					 | 
				
			||||||
                              for provider in providers)
 | 
					 | 
				
			||||||
        self.__dict__.update(self.providers)
 | 
					 | 
				
			||||||
        super(CatalogBundle, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_provider(self, name):
 | 
					 | 
				
			||||||
        """Return provider with specified name or raise an error.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Provider's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :return: Provider with specified name.
 | 
					 | 
				
			||||||
        :rtype: :py:class:`dependency_injector.providers.Provider`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            return self.providers[name]
 | 
					 | 
				
			||||||
        except KeyError:
 | 
					 | 
				
			||||||
            raise Error('Provider "{0}" is not a part of {1}'.format(name,
 | 
					 | 
				
			||||||
                                                                     self))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def has_provider(self, name):
 | 
					 | 
				
			||||||
        """Check if there is provider with certain name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Provider's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: bool
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return name in self.providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __getattr__(self, item):
 | 
					 | 
				
			||||||
        """Return provider with specified name or raise en error.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Attribute's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if item.startswith('__') and item.endswith('__'):
 | 
					 | 
				
			||||||
            return super(CatalogBundle, self).__getattr__(item)
 | 
					 | 
				
			||||||
        raise UndefinedProviderError('Provider "{0}" is not a part '
 | 
					 | 
				
			||||||
                                     'of {1}'.format(item, self))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __repr__(self):
 | 
					 | 
				
			||||||
        """Return string representation of catalog's bundle.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return '<{0}.Bundle({1})>'.format(
 | 
					 | 
				
			||||||
            self.catalog.name, ', '.join(six.iterkeys(self.providers)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __str__ = __repr__
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,491 +0,0 @@
 | 
				
			||||||
"""Dependency injector declarative catalog module."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import six
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.catalogs.dynamic import DynamicCatalog
 | 
					 | 
				
			||||||
from dependency_injector.catalogs.bundle import CatalogBundle
 | 
					 | 
				
			||||||
from dependency_injector.utils import (
 | 
					 | 
				
			||||||
    is_provider,
 | 
					 | 
				
			||||||
    is_catalog,
 | 
					 | 
				
			||||||
    is_declarative_catalog,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from dependency_injector.errors import (
 | 
					 | 
				
			||||||
    Error,
 | 
					 | 
				
			||||||
    UndefinedProviderError,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class DeclarativeCatalogMetaClass(type):
 | 
					 | 
				
			||||||
    """Declarative catalog meta class."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __new__(mcs, class_name, bases, attributes):
 | 
					 | 
				
			||||||
        """Declarative catalog class factory."""
 | 
					 | 
				
			||||||
        cls_providers = tuple((name, provider)
 | 
					 | 
				
			||||||
                              for name, provider in six.iteritems(attributes)
 | 
					 | 
				
			||||||
                              if is_provider(provider))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inherited_providers = tuple((name, provider)
 | 
					 | 
				
			||||||
                                    for base in bases if is_catalog(base)
 | 
					 | 
				
			||||||
                                    for name, provider in six.iteritems(
 | 
					 | 
				
			||||||
                                        base.providers))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        providers = cls_providers + inherited_providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        cls = type.__new__(mcs, class_name, bases, attributes)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if cls.provider_type:
 | 
					 | 
				
			||||||
            cls._catalog = type('DynamicCatalog',
 | 
					 | 
				
			||||||
                                (DynamicCatalog,),
 | 
					 | 
				
			||||||
                                dict(provider_type=cls.provider_type))()
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return cls
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def name(cls):
 | 
					 | 
				
			||||||
        """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):
 | 
					 | 
				
			||||||
        """Read-only dictionary of all providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return cls._catalog.providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def cls_providers(cls):
 | 
					 | 
				
			||||||
        """Read-only dictionary of current catalog providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return cls._cls_providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def inherited_providers(cls):
 | 
					 | 
				
			||||||
        """Read-only dictionary of inherited providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return cls._inherited_providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def overridden_by(cls):
 | 
					 | 
				
			||||||
        """Tuple of overriding catalogs.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[
 | 
					 | 
				
			||||||
            :py:class:`DeclarativeCatalog` |
 | 
					 | 
				
			||||||
            :py:class:`DynamicCatalog`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return cls._catalog.overridden_by
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def is_overridden(cls):
 | 
					 | 
				
			||||||
        """Read-only property that is set to ``True`` if catalog is overridden.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: bool
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return cls._catalog.is_overridden
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def last_overriding(cls):
 | 
					 | 
				
			||||||
        """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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __setattr__(cls, 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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):
 | 
					 | 
				
			||||||
            cls.bind_provider(name, value, _set_as_attribute=False)
 | 
					 | 
				
			||||||
        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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Attribute's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if is_provider(getattr(cls, name)):
 | 
					 | 
				
			||||||
            delattr(cls._catalog, name)
 | 
					 | 
				
			||||||
        return super(DeclarativeCatalogMetaClass, cls).__delattr__(name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __repr__(cls):
 | 
					 | 
				
			||||||
        """Return string representation of the catalog.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return '<{0}({1})>'.format(cls.name,
 | 
					 | 
				
			||||||
                                   ', '.join(six.iterkeys(cls.providers)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __str__ = __repr__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.add_metaclass(DeclarativeCatalogMetaClass)
 | 
					 | 
				
			||||||
class DeclarativeCatalog(object):
 | 
					 | 
				
			||||||
    """Declarative catalog of providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        class Services(DeclarativeCatalog):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            auth = providers.Factory(AuthService)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            users = providers.Factory(UsersService)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        users_service = Services.users()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: Bundle
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Catalog's bundle class.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: :py:class:`CatalogBundle`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provider_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If provider type is defined, :py:class:`DeclarativeCatalog` checks that
 | 
					 | 
				
			||||||
        all of its providers are instances of
 | 
					 | 
				
			||||||
        :py:attr:`DeclarativeCatalog.provider_type`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | None
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Bundle = CatalogBundle
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provider_type = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _catalog = DynamicCatalog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    _cls_providers = dict()
 | 
					 | 
				
			||||||
    _inherited_providers = dict()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __IS_CATALOG__ = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def name(self):
 | 
					 | 
				
			||||||
        """Read-only property that represents catalog's name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Catalog's name is catalog's module + catalog's class name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.__class__.name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def providers(self):
 | 
					 | 
				
			||||||
        """Read-only dictionary of all providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.__class__.providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def cls_providers(self):
 | 
					 | 
				
			||||||
        """Read-only dictionary of current catalog providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.__class__.cls_providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def inherited_providers(self):
 | 
					 | 
				
			||||||
        """Read-only dictionary of inherited providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.__class__.inherited_providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def overridden_by(self):
 | 
					 | 
				
			||||||
        """Tuple of overriding catalogs.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: tuple[:py:class:`DeclarativeCatalog` |
 | 
					 | 
				
			||||||
                      :py:class:`DynamicCatalog`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.__class__.overridden_by
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def is_overridden(self):
 | 
					 | 
				
			||||||
        """Read-only property that is set to ``True`` if catalog is overridden.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: bool
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.__class__.is_overridden
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def last_overriding(self):
 | 
					 | 
				
			||||||
        """Read-only reference to the last overriding catalog, if any.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog` |
 | 
					 | 
				
			||||||
               None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.__class__.last_overriding
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def is_bundle_owner(cls, 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        cls._catalog.reset_last_overriding()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def reset_override(cls):
 | 
					 | 
				
			||||||
        """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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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, force=False,
 | 
					 | 
				
			||||||
                      _set_as_attribute=True):
 | 
					 | 
				
			||||||
        """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`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param force: Force binding of provider.
 | 
					 | 
				
			||||||
        :type force: bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if cls._catalog.is_provider_bound(provider):
 | 
					 | 
				
			||||||
            bindind_name = cls._catalog.get_provider_bind_name(provider)
 | 
					 | 
				
			||||||
            if bindind_name == name and not force:
 | 
					 | 
				
			||||||
                return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        cls._catalog.bind_provider(name, provider, force)
 | 
					 | 
				
			||||||
        cls.cls_providers[name] = provider
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if _set_as_attribute:
 | 
					 | 
				
			||||||
            setattr(cls, name, provider)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def bind_providers(cls, providers, force=False):
 | 
					 | 
				
			||||||
        """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`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param force: Force binding of providers.
 | 
					 | 
				
			||||||
        :type force: bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        for name, provider in six.iteritems(providers):
 | 
					 | 
				
			||||||
            cls.bind_provider(name, provider, force=force)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def has_provider(cls, 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Provider's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        delattr(cls, name)
 | 
					 | 
				
			||||||
        del cls.cls_providers[name]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @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.*
 | 
					 | 
				
			||||||
AbstractCatalog = DeclarativeCatalog
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,338 +0,0 @@
 | 
				
			||||||
"""Dependency injector dynamic catalog module."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import six
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.catalogs.bundle import CatalogBundle
 | 
					 | 
				
			||||||
from dependency_injector.utils import (
 | 
					 | 
				
			||||||
    is_provider,
 | 
					 | 
				
			||||||
    ensure_is_provider,
 | 
					 | 
				
			||||||
    ensure_is_catalog_bundle,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from dependency_injector.errors import (
 | 
					 | 
				
			||||||
    Error,
 | 
					 | 
				
			||||||
    UndefinedProviderError,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class DynamicCatalog(object):
 | 
					 | 
				
			||||||
    """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()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: Bundle
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Catalog's bundle class.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: :py:class:`CatalogBundle`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Catalog's name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        By default, it is catalog's module + catalog's class name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Dictionary of all providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: overridden_by
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of overriding catalogs.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[
 | 
					 | 
				
			||||||
            :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provider_type
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If provider type is defined, :py:class:`DynamicCatalog` checks that
 | 
					 | 
				
			||||||
        all of its providers are instances of
 | 
					 | 
				
			||||||
        :py:attr:`DynamicCatalog.provider_type`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | None
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provider_type = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __IS_CATALOG__ = True
 | 
					 | 
				
			||||||
    __slots__ = ('name', 'providers', 'provider_names', 'overridden_by',
 | 
					 | 
				
			||||||
                 'Bundle')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, **providers):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param providers: Dictionary of catalog providers.
 | 
					 | 
				
			||||||
        :type providers:
 | 
					 | 
				
			||||||
            dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.Bundle = CatalogBundle.sub_cls_factory(self)
 | 
					 | 
				
			||||||
        self.name = '.'.join((self.__class__.__module__,
 | 
					 | 
				
			||||||
                              self.__class__.__name__))
 | 
					 | 
				
			||||||
        self.providers = dict()
 | 
					 | 
				
			||||||
        self.provider_names = dict()
 | 
					 | 
				
			||||||
        self.overridden_by = tuple()
 | 
					 | 
				
			||||||
        self.bind_providers(providers)
 | 
					 | 
				
			||||||
        super(DynamicCatalog, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def is_bundle_owner(self, bundle):
 | 
					 | 
				
			||||||
        """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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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 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):
 | 
					 | 
				
			||||||
        """Read-only property that is set to ``True`` if catalog is overridden.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: bool
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return bool(self.overridden_by)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def last_overriding(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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if not self.is_overridden:
 | 
					 | 
				
			||||||
            raise Error('Catalog {0} is not overridden'.format(self))
 | 
					 | 
				
			||||||
        self.overridden_by = self.overridden_by[:-1]
 | 
					 | 
				
			||||||
        for provider in six.itervalues(self.providers):
 | 
					 | 
				
			||||||
            provider.reset_last_overriding()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def reset_override(self):
 | 
					 | 
				
			||||||
        """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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Provider's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.UndefinedProviderError`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :return: Provider with specified name.
 | 
					 | 
				
			||||||
        :rtype: :py:class:`dependency_injector.providers.Provider`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            return self.providers[name]
 | 
					 | 
				
			||||||
        except KeyError:
 | 
					 | 
				
			||||||
            raise UndefinedProviderError('{0} has no provider with such '
 | 
					 | 
				
			||||||
                                         'name - {1}'.format(self, name))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def bind_provider(self, name, provider, force=False):
 | 
					 | 
				
			||||||
        """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`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param force: Force binding of provider.
 | 
					 | 
				
			||||||
        :type force: bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        provider = ensure_is_provider(provider)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (self.__class__.provider_type and
 | 
					 | 
				
			||||||
                not isinstance(provider, self.__class__.provider_type)):
 | 
					 | 
				
			||||||
            raise Error('{0} can contain only {1} instances'.format(
 | 
					 | 
				
			||||||
                self, self.__class__.provider_type))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if not force:
 | 
					 | 
				
			||||||
            if name in self.providers:
 | 
					 | 
				
			||||||
                raise Error('Catalog {0} already has provider with '
 | 
					 | 
				
			||||||
                            'such name - {1}'.format(self, name))
 | 
					 | 
				
			||||||
            if provider in self.provider_names:
 | 
					 | 
				
			||||||
                raise Error('Catalog {0} already has such provider '
 | 
					 | 
				
			||||||
                            'instance - {1}'.format(self, provider))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.providers[name] = provider
 | 
					 | 
				
			||||||
        self.provider_names[provider] = name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def bind_providers(self, providers, force=False):
 | 
					 | 
				
			||||||
        """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`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param force: Force binding of providers.
 | 
					 | 
				
			||||||
        :type force: bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raise: :py:exc:`dependency_injector.errors.Error`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        for name, provider in six.iteritems(providers):
 | 
					 | 
				
			||||||
            self.bind_provider(name, provider, force)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def has_provider(self, name):
 | 
					 | 
				
			||||||
        """Check if there is provider with certain name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Provider's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: bool
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return name in self.providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def unbind_provider(self, name):
 | 
					 | 
				
			||||||
        """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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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)
 | 
					 | 
				
			||||||
        return super(DynamicCatalog, self).__setattr__(name, value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __delattr__(self, 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Attribute's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.unbind_provider(name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __repr__(self):
 | 
					 | 
				
			||||||
        """Return Python representation of catalog.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return '<{0}({1})>'.format(self.name,
 | 
					 | 
				
			||||||
                                   ', '.join(six.iterkeys(self.providers)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __str__ = __repr__
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,62 +0,0 @@
 | 
				
			||||||
"""Dependency injector catalog utils."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import six
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.utils import _copy_providers
 | 
					 | 
				
			||||||
from dependency_injector.errors import UndefinedProviderError
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def copy(catalog):
 | 
					 | 
				
			||||||
    """:py:class:`DeclarativeCatalog` copying decorator.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    This decorator copy all providers from provided catalog to decorated one.
 | 
					 | 
				
			||||||
    If one of the decorated catalog providers matches to source catalog
 | 
					 | 
				
			||||||
    providers by name, it would be replaced by reference.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :param catalog: Catalog that should be copied by decorated catalog.
 | 
					 | 
				
			||||||
    :type catalog: :py:class:`DeclarativeCatalog`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :return: Declarative catalog's copying decorator.
 | 
					 | 
				
			||||||
    :rtype:
 | 
					 | 
				
			||||||
        callable(:py:class:`DeclarativeCatalog`)
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    def decorator(copied_catalog):
 | 
					 | 
				
			||||||
        """Copying decorator.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param copied_catalog: Decorated catalog.
 | 
					 | 
				
			||||||
        :type copied_catalog: :py:class:`DeclarativeCatalog`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :return: Decorated catalog.
 | 
					 | 
				
			||||||
        :rtype:
 | 
					 | 
				
			||||||
            :py:class:`DeclarativeCatalog`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        memo = dict()
 | 
					 | 
				
			||||||
        for name, provider in six.iteritems(copied_catalog.cls_providers):
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                source_provider = catalog.get_provider(name)
 | 
					 | 
				
			||||||
            except UndefinedProviderError:
 | 
					 | 
				
			||||||
                pass
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                memo[id(source_provider)] = provider
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        copied_catalog.bind_providers(_copy_providers(catalog.providers, memo),
 | 
					 | 
				
			||||||
                                      force=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return copied_catalog
 | 
					 | 
				
			||||||
    return decorator
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def override(catalog):
 | 
					 | 
				
			||||||
    """:py:class:`DeclarativeCatalog` overriding decorator.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :param catalog: Catalog that should be overridden by decorated catalog.
 | 
					 | 
				
			||||||
    :type catalog: :py:class:`DeclarativeCatalog`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :return: Declarative catalog's overriding decorator.
 | 
					 | 
				
			||||||
    :rtype: callable(:py:class:`DeclarativeCatalog`)
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    def decorator(overriding_catalog):
 | 
					 | 
				
			||||||
        """Overriding decorator."""
 | 
					 | 
				
			||||||
        catalog.override(overriding_catalog)
 | 
					 | 
				
			||||||
        return overriding_catalog
 | 
					 | 
				
			||||||
    return decorator
 | 
					 | 
				
			||||||
							
								
								
									
										363
									
								
								dependency_injector/containers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,363 @@
 | 
				
			||||||
 | 
					"""Dependency injector IoC containers module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import (
 | 
				
			||||||
 | 
					    providers,
 | 
				
			||||||
 | 
					    utils,
 | 
				
			||||||
 | 
					    errors,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DynamicContainer(object):
 | 
				
			||||||
 | 
					    """Dynamic inversion of control container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        services = DynamicContainer()
 | 
				
			||||||
 | 
					        services.auth = providers.Factory(AuthService)
 | 
				
			||||||
 | 
					        services.users = providers.Factory(UsersService,
 | 
				
			||||||
 | 
					                                           auth_service=services.auth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Read-only dictionary of all providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: overridden
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Tuple of overriding containers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: tuple[:py:class:`DynamicContainer`]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. py:attribute:: provider_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Type of providers that could be placed in container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __IS_CONTAINER__ = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.provider_type = providers.Provider
 | 
				
			||||||
 | 
					        self.providers = dict()
 | 
				
			||||||
 | 
					        self.overridden = tuple()
 | 
				
			||||||
 | 
					        super(DynamicContainer, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __setattr__(self, name, value):
 | 
				
			||||||
 | 
					        """Set instance attribute.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If value of attribute is provider, it will be added into providers
 | 
				
			||||||
 | 
					        dictionary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: Attribute's name
 | 
				
			||||||
 | 
					        :type name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param value: Attribute's value
 | 
				
			||||||
 | 
					        :type value: object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if utils.is_provider(value):
 | 
				
			||||||
 | 
					            _check_provider_type(self, value)
 | 
				
			||||||
 | 
					            self.providers[name] = value
 | 
				
			||||||
 | 
					        super(DynamicContainer, self).__setattr__(name, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __delattr__(self, name):
 | 
				
			||||||
 | 
					        """Delete instance attribute.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If value of attribute is provider, it will be deleted from providers
 | 
				
			||||||
 | 
					        dictionary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: Attribute's name
 | 
				
			||||||
 | 
					        :type name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if name in self.providers:
 | 
				
			||||||
 | 
					            del self.providers[name]
 | 
				
			||||||
 | 
					        super(DynamicContainer, self).__delattr__(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def override(self, overriding):
 | 
				
			||||||
 | 
					        """Override current container by overriding container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param overriding: Overriding container.
 | 
				
			||||||
 | 
					        :type overriding: :py:class:`DynamicContainer`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :raise: :py:exc:`dependency_injector.errors.Error` if trying to
 | 
				
			||||||
 | 
					                override container by itself
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if overriding is self:
 | 
				
			||||||
 | 
					            raise errors.Error('Container {0} could not be overridden '
 | 
				
			||||||
 | 
					                               'with itself'.format(self))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.overridden += (overriding,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for name, provider in six.iteritems(overriding.providers):
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                getattr(self, name).override(provider)
 | 
				
			||||||
 | 
					            except AttributeError:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_last_overriding(self):
 | 
				
			||||||
 | 
					        """Reset last overriding provider for each container providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if not self.overridden:
 | 
				
			||||||
 | 
					            raise errors.Error('Container {0} is not overridden'.format(self))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.overridden = self.overridden[:-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for provider in six.itervalues(self.providers):
 | 
				
			||||||
 | 
					            provider.reset_last_overriding()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def reset_override(self):
 | 
				
			||||||
 | 
					        """Reset all overridings for each container providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.overridden = tuple()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for provider in six.itervalues(self.providers):
 | 
				
			||||||
 | 
					            provider.reset_override()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DeclarativeContainerMetaClass(type):
 | 
				
			||||||
 | 
					    """Declarative inversion of control container meta class."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __new__(mcs, class_name, bases, attributes):
 | 
				
			||||||
 | 
					        """Declarative container class factory."""
 | 
				
			||||||
 | 
					        cls_providers = tuple((name, provider)
 | 
				
			||||||
 | 
					                              for name, provider in six.iteritems(attributes)
 | 
				
			||||||
 | 
					                              if utils.is_provider(provider))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        inherited_providers = tuple((name, provider)
 | 
				
			||||||
 | 
					                                    for base in bases if utils.is_container(
 | 
				
			||||||
 | 
					                                        base) and base is not DynamicContainer
 | 
				
			||||||
 | 
					                                    for name, provider in six.iteritems(
 | 
				
			||||||
 | 
					                                        base.cls_providers))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attributes['cls_providers'] = dict(cls_providers)
 | 
				
			||||||
 | 
					        attributes['inherited_providers'] = dict(inherited_providers)
 | 
				
			||||||
 | 
					        attributes['providers'] = dict(cls_providers + inherited_providers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cls = type.__new__(mcs, class_name, bases, attributes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for provider in six.itervalues(cls.providers):
 | 
				
			||||||
 | 
					            _check_provider_type(cls, provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __setattr__(cls, name, value):
 | 
				
			||||||
 | 
					        """Set class attribute.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If value of attribute is provider, it will be added into providers
 | 
				
			||||||
 | 
					        dictionary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: Attribute's name
 | 
				
			||||||
 | 
					        :type name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param value: Attribute's value
 | 
				
			||||||
 | 
					        :type value: object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if utils.is_provider(value):
 | 
				
			||||||
 | 
					            _check_provider_type(cls, value)
 | 
				
			||||||
 | 
					            cls.providers[name] = value
 | 
				
			||||||
 | 
					            cls.cls_providers[name] = value
 | 
				
			||||||
 | 
					        super(DeclarativeContainerMetaClass, cls).__setattr__(name, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __delattr__(cls, name):
 | 
				
			||||||
 | 
					        """Delete class attribute.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If value of attribute is provider, it will be deleted from providers
 | 
				
			||||||
 | 
					        dictionary.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param name: Attribute's name
 | 
				
			||||||
 | 
					        :type name: str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if name in cls.providers and name in cls.cls_providers:
 | 
				
			||||||
 | 
					            del cls.providers[name]
 | 
				
			||||||
 | 
					            del cls.cls_providers[name]
 | 
				
			||||||
 | 
					        super(DeclarativeContainerMetaClass, cls).__delattr__(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@six.add_metaclass(DeclarativeContainerMetaClass)
 | 
				
			||||||
 | 
					class DeclarativeContainer(object):
 | 
				
			||||||
 | 
					    """Declarative inversion of control container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Services(DeclarativeContainer):
 | 
				
			||||||
 | 
					            auth = providers.Factory(AuthService)
 | 
				
			||||||
 | 
					            users = providers.Factory(UsersService,
 | 
				
			||||||
 | 
					                                      auth_service=auth)
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __IS_CONTAINER__ = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    provider_type = providers.Provider
 | 
				
			||||||
 | 
					    """Type of providers that could be placed in container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    instance_type = DynamicContainer
 | 
				
			||||||
 | 
					    """Type of container that is returned on instantiating declarative
 | 
				
			||||||
 | 
					    container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :type: type
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    providers = dict()
 | 
				
			||||||
 | 
					    """Read-only dictionary of all providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :type: dict[str, :py:class:`dependency_injector.providers.Provider`]
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cls_providers = dict()
 | 
				
			||||||
 | 
					    """Read-only dictionary of current container 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`]
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    overridden = tuple()
 | 
				
			||||||
 | 
					    """Tuple of overriding containers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :type: tuple[:py:class:`DeclarativeContainer`]
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __new__(cls, *args, **kwargs):
 | 
				
			||||||
 | 
					        """Constructor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Dynamic container with copy of all providers.
 | 
				
			||||||
 | 
					        :rtype: :py:class:`DynamicContainer`
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        container = cls.instance_type(*args, **kwargs)
 | 
				
			||||||
 | 
					        container.provider_type = cls.provider_type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for name, provider in six.iteritems(utils.deepcopy(cls.providers)):
 | 
				
			||||||
 | 
					            setattr(container, name, provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def override(cls, overriding):
 | 
				
			||||||
 | 
					        """Override current container by overriding container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param overriding: Overriding container.
 | 
				
			||||||
 | 
					        :type overriding: :py:class:`DeclarativeContainer`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :raise: :py:exc:`dependency_injector.errors.Error` if trying to
 | 
				
			||||||
 | 
					                override container by itself or its subclasses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if issubclass(cls, overriding):
 | 
				
			||||||
 | 
					            raise errors.Error('Container {0} could not be overridden '
 | 
				
			||||||
 | 
					                               'with itself or its subclasses'.format(cls))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cls.overridden += (overriding,)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for name, provider in six.iteritems(overriding.cls_providers):
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                getattr(cls, name).override(provider)
 | 
				
			||||||
 | 
					            except AttributeError:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def reset_last_overriding(cls):
 | 
				
			||||||
 | 
					        """Reset last overriding provider for each container providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        if not cls.overridden:
 | 
				
			||||||
 | 
					            raise errors.Error('Container {0} is not overridden'.format(cls))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cls.overridden = cls.overridden[:-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for provider in six.itervalues(cls.providers):
 | 
				
			||||||
 | 
					            provider.reset_last_overriding()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def reset_override(cls):
 | 
				
			||||||
 | 
					        """Reset all overridings for each container providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: None
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        cls.overridden = tuple()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for provider in six.itervalues(cls.providers):
 | 
				
			||||||
 | 
					            provider.reset_override()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def override(container):
 | 
				
			||||||
 | 
					    """:py:class:`DeclarativeContainer` overriding decorator.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param container: Container that should be overridden by decorated
 | 
				
			||||||
 | 
					                      container.
 | 
				
			||||||
 | 
					    :type container: :py:class:`DeclarativeContainer`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :return: Declarative container's overriding decorator.
 | 
				
			||||||
 | 
					    :rtype: callable(:py:class:`DeclarativeContainer`)
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def _decorator(overriding_container):
 | 
				
			||||||
 | 
					        """Overriding decorator."""
 | 
				
			||||||
 | 
					        container.override(overriding_container)
 | 
				
			||||||
 | 
					        return overriding_container
 | 
				
			||||||
 | 
					    return _decorator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def copy(container):
 | 
				
			||||||
 | 
					    """:py:class:`DeclarativeContainer` copying decorator.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This decorator copy all providers from provided container to decorated one.
 | 
				
			||||||
 | 
					    If one of the decorated container providers matches to source container
 | 
				
			||||||
 | 
					    providers by name, it would be replaced by reference.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param container: Container that should be copied by decorated container.
 | 
				
			||||||
 | 
					    :type container: :py:class:`DeclarativeContainer`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :return: Declarative container's copying decorator.
 | 
				
			||||||
 | 
					    :rtype: callable(:py:class:`DeclarativeContainer`)
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def _decorator(copied_container):
 | 
				
			||||||
 | 
					        memo = dict()
 | 
				
			||||||
 | 
					        for name, provider in six.iteritems(copied_container.cls_providers):
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                source_provider = getattr(container, name)
 | 
				
			||||||
 | 
					            except AttributeError:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                memo[id(source_provider)] = provider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        providers_copy = utils.deepcopy(container.providers, memo)
 | 
				
			||||||
 | 
					        for name, provider in six.iteritems(providers_copy):
 | 
				
			||||||
 | 
					            setattr(copied_container, name, provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return copied_container
 | 
				
			||||||
 | 
					    return _decorator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _check_provider_type(cls, provider):
 | 
				
			||||||
 | 
					    if not isinstance(provider, cls.provider_type):
 | 
				
			||||||
 | 
					        raise errors.Error('{0} can contain only {1} '
 | 
				
			||||||
 | 
					                           'instances'.format(cls, cls.provider_type))
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
"""Errors module."""
 | 
					"""Dependency injector errors module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Error(Exception):
 | 
					class Error(Exception):
 | 
				
			||||||
| 
						 | 
					@ -6,17 +6,3 @@ class Error(Exception):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    All dependency injector errors extend this error class.
 | 
					    All dependency injector errors extend this error class.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UndefinedProviderError(Error, AttributeError):
 | 
					 | 
				
			||||||
    """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__()``.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,169 +1,13 @@
 | 
				
			||||||
"""Injections module."""
 | 
					"""Dependency injector injections module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector.utils import (
 | 
					from dependency_injector.providers.base import (
 | 
				
			||||||
    is_provider,
 | 
					    _parse_positional_injections,
 | 
				
			||||||
    is_delegated_provider,
 | 
					    _parse_keyword_injections,
 | 
				
			||||||
    is_injection,
 | 
					 | 
				
			||||||
    is_arg_injection,
 | 
					 | 
				
			||||||
    is_kwarg_injection,
 | 
					 | 
				
			||||||
    fetch_cls_init,
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from dependency_injector import utils
 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					from dependency_injector import errors
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class Injection(object):
 | 
					 | 
				
			||||||
    """Base injection class.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    All injections extend this class.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: injectable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Injectable value, could be provider or any other object.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: object | :py:class:`dependency_injector.providers.Provider`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: call_injectable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Flag that is set to ``True`` if it is needed to call injectable.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Injectable needs to be called if it is not delegated provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: bool
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __IS_INJECTION__ = True
 | 
					 | 
				
			||||||
    __slots__ = ('injectable', 'call_injectable')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, injectable):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param injectable: Injectable value, could be provider or any
 | 
					 | 
				
			||||||
                           other object.
 | 
					 | 
				
			||||||
        :type injectable: object |
 | 
					 | 
				
			||||||
                          :py:class:`dependency_injector.providers.Provider`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.injectable = injectable
 | 
					 | 
				
			||||||
        self.call_injectable = (is_provider(injectable) and
 | 
					 | 
				
			||||||
                                not is_delegated_provider(injectable))
 | 
					 | 
				
			||||||
        super(Injection, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @property
 | 
					 | 
				
			||||||
    def value(self):
 | 
					 | 
				
			||||||
        """Read-only property that represents injectable value.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Injectable values and delegated providers are provided "as is".
 | 
					 | 
				
			||||||
        Other providers will be called every time, when injection needs to
 | 
					 | 
				
			||||||
        be done.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: object
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        if self.call_injectable:
 | 
					 | 
				
			||||||
            return self.injectable.provide()
 | 
					 | 
				
			||||||
        return self.injectable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """Return string representation of provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return '<{injection}({injectable}) at {address}>'.format(
 | 
					 | 
				
			||||||
            injection='.'.join((self.__class__.__module__,
 | 
					 | 
				
			||||||
                                self.__class__.__name__)),
 | 
					 | 
				
			||||||
            injectable=repr(self.injectable),
 | 
					 | 
				
			||||||
            address=hex(id(self)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __repr__ = __str__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Arg(Injection):
 | 
					 | 
				
			||||||
    """Positional argument injection."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __IS_ARG_INJECTION__ = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class _NamedInjection(Injection):
 | 
					 | 
				
			||||||
    """Base class of named injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Injection target's name (keyword argument, attribute, method).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: str
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __slots__ = ('name',)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, name, injectable):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param name: Injection target's name.
 | 
					 | 
				
			||||||
        :type name: str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param injectable: Injectable value, could be provider or any
 | 
					 | 
				
			||||||
                           other object.
 | 
					 | 
				
			||||||
        :type injectable: object |
 | 
					 | 
				
			||||||
                          :py:class:`dependency_injector.providers.Provider`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.name = name
 | 
					 | 
				
			||||||
        super(_NamedInjection, self).__init__(injectable)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """Return string representation of provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return '<{injection}({name}, {injectable}) at {address}>'.format(
 | 
					 | 
				
			||||||
            name=repr(self.name),
 | 
					 | 
				
			||||||
            injection='.'.join((self.__class__.__module__,
 | 
					 | 
				
			||||||
                                self.__class__.__name__)),
 | 
					 | 
				
			||||||
            injectable=repr(self.injectable),
 | 
					 | 
				
			||||||
            address=hex(id(self)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __repr__ = __str__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class KwArg(_NamedInjection):
 | 
					 | 
				
			||||||
    """Keyword argument injection.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Keyword argument's name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: str
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __IS_KWARG_INJECTION__ = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Attribute(_NamedInjection):
 | 
					 | 
				
			||||||
    """Attribute injection.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Attribute's name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: str
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __IS_ATTRIBUTE_INJECTION__ = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Method(_NamedInjection):
 | 
					 | 
				
			||||||
    """Method injection.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Method's name.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: str
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __IS_METHOD_INJECTION__ = True
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def inject(*args, **kwargs):
 | 
					def inject(*args, **kwargs):
 | 
				
			||||||
| 
						 | 
					@ -178,24 +22,18 @@ def inject(*args, **kwargs):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. code-block:: python
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Positional arguments injections (simplified syntax):
 | 
					        # Positional arguments injections:
 | 
				
			||||||
        @inject(1, 2)
 | 
					        @inject(1, 2)
 | 
				
			||||||
        def some_function(arg1, arg2):
 | 
					        def some_function(arg1, arg2):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Keyword arguments injections (simplified syntax):
 | 
					        # Keyword arguments injections:
 | 
				
			||||||
        @inject(arg1=1)
 | 
					        @inject(arg1=1)
 | 
				
			||||||
        @inject(arg2=2)
 | 
					        @inject(arg2=2)
 | 
				
			||||||
        def some_function(arg1, arg2):
 | 
					        def some_function(arg1, arg2):
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Keyword arguments injections (extended (full) syntax):
 | 
					        # Keyword arguments injections into class init:
 | 
				
			||||||
        @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(arg1=1)
 | 
				
			||||||
        @inject(arg2=2)
 | 
					        @inject(arg2=2)
 | 
				
			||||||
        class SomeClass(object):
 | 
					        class SomeClass(object):
 | 
				
			||||||
| 
						 | 
					@ -212,16 +50,16 @@ def inject(*args, **kwargs):
 | 
				
			||||||
    :return: Class / callable decorator
 | 
					    :return: Class / callable decorator
 | 
				
			||||||
    :rtype: (callable) -> (type | callable)
 | 
					    :rtype: (callable) -> (type | callable)
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    arg_injections = _parse_args_injections(args)
 | 
					    arg_injections = _parse_positional_injections(args)
 | 
				
			||||||
    kwarg_injections = _parse_kwargs_injections(args, kwargs)
 | 
					    kwarg_injections = _parse_keyword_injections(kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def decorator(callback_or_cls):
 | 
					    def decorator(callback_or_cls):
 | 
				
			||||||
        """Dependency injection decorator."""
 | 
					        """Dependency injection decorator."""
 | 
				
			||||||
        if isinstance(callback_or_cls, six.class_types):
 | 
					        if isinstance(callback_or_cls, six.class_types):
 | 
				
			||||||
            cls = callback_or_cls
 | 
					            cls = callback_or_cls
 | 
				
			||||||
            cls_init = fetch_cls_init(cls)
 | 
					            cls_init = utils.fetch_cls_init(cls)
 | 
				
			||||||
            if not cls_init:
 | 
					            if not cls_init:
 | 
				
			||||||
                raise Error(
 | 
					                raise errors.Error(
 | 
				
			||||||
                    'Class {0}.{1} has no __init__() '.format(cls.__module__,
 | 
					                    'Class {0}.{1} has no __init__() '.format(cls.__module__,
 | 
				
			||||||
                                                              cls.__name__) +
 | 
					                                                              cls.__name__) +
 | 
				
			||||||
                    'method and could not be decorated with @inject decorator')
 | 
					                    'method and could not be decorated with @inject decorator')
 | 
				
			||||||
| 
						 | 
					@ -232,19 +70,19 @@ def inject(*args, **kwargs):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if hasattr(callback, '__INJECT_DECORATED__'):
 | 
					        if hasattr(callback, '__INJECT_DECORATED__'):
 | 
				
			||||||
            callback.args += arg_injections
 | 
					            callback.args += arg_injections
 | 
				
			||||||
            callback.kwargs += kwarg_injections
 | 
					            callback.kwargs.update(kwarg_injections)
 | 
				
			||||||
            callback.injections += arg_injections + kwarg_injections
 | 
					 | 
				
			||||||
            return callback
 | 
					            return callback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @six.wraps(callback)
 | 
					        @six.wraps(callback)
 | 
				
			||||||
        def decorated(*args, **kwargs):
 | 
					        def decorated(*args, **kwargs):
 | 
				
			||||||
            """Decorated with dependency injection callback."""
 | 
					            """Decorated with dependency injection callback."""
 | 
				
			||||||
            if decorated.args:
 | 
					            if decorated.args:
 | 
				
			||||||
                args = tuple(arg.value for arg in decorated.args) + args
 | 
					                args = tuple(arg.provide_injection()
 | 
				
			||||||
 | 
					                             for arg in decorated.args) + args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for kwarg in decorated.kwargs:
 | 
					            for name, arg in six.iteritems(decorated.kwargs):
 | 
				
			||||||
                if kwarg.name not in kwargs:
 | 
					                if name not in kwargs:
 | 
				
			||||||
                    kwargs[kwarg.name] = kwarg.value
 | 
					                    kwargs[name] = arg.provide_injection()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return callback(*args, **kwargs)
 | 
					            return callback(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -252,25 +90,6 @@ def inject(*args, **kwargs):
 | 
				
			||||||
        decorated.origin = callback
 | 
					        decorated.origin = callback
 | 
				
			||||||
        decorated.args = arg_injections
 | 
					        decorated.args = arg_injections
 | 
				
			||||||
        decorated.kwargs = kwarg_injections
 | 
					        decorated.kwargs = kwarg_injections
 | 
				
			||||||
        decorated.injections = arg_injections + kwarg_injections
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return decorated
 | 
					        return decorated
 | 
				
			||||||
    return decorator
 | 
					    return decorator
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _parse_args_injections(args):
 | 
					 | 
				
			||||||
    """Parse positional argument injections according to current syntax."""
 | 
					 | 
				
			||||||
    return tuple(Arg(arg) if not is_injection(arg) else arg
 | 
					 | 
				
			||||||
                 for arg in args
 | 
					 | 
				
			||||||
                 if not is_injection(arg) or is_arg_injection(arg))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def _parse_kwargs_injections(args, kwargs):
 | 
					 | 
				
			||||||
    """Parse keyword argument injections according to current syntax."""
 | 
					 | 
				
			||||||
    kwarg_injections = tuple(injection
 | 
					 | 
				
			||||||
                             for injection in args
 | 
					 | 
				
			||||||
                             if is_kwarg_injection(injection))
 | 
					 | 
				
			||||||
    if kwargs:
 | 
					 | 
				
			||||||
        kwarg_injections += tuple(KwArg(name, value)
 | 
					 | 
				
			||||||
                                  for name, value in six.iteritems(kwargs))
 | 
					 | 
				
			||||||
    return kwarg_injections
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,10 @@
 | 
				
			||||||
from dependency_injector.providers.base import (
 | 
					from dependency_injector.providers.base import (
 | 
				
			||||||
    Provider,
 | 
					    Provider,
 | 
				
			||||||
    Delegate,
 | 
					    Delegate,
 | 
				
			||||||
    Static,
 | 
					    Object,
 | 
				
			||||||
    StaticProvider,
 | 
					 | 
				
			||||||
    ExternalDependency,
 | 
					    ExternalDependency,
 | 
				
			||||||
 | 
					    OverridingContext,
 | 
				
			||||||
 | 
					    override,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from dependency_injector.providers.callable import (
 | 
					from dependency_injector.providers.callable import (
 | 
				
			||||||
    Callable,
 | 
					    Callable,
 | 
				
			||||||
| 
						 | 
					@ -17,28 +18,17 @@ from dependency_injector.providers.creational import (
 | 
				
			||||||
    Singleton,
 | 
					    Singleton,
 | 
				
			||||||
    DelegatedSingleton,
 | 
					    DelegatedSingleton,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from dependency_injector.providers.static import (
 | 
					 | 
				
			||||||
    Object,
 | 
					 | 
				
			||||||
    Value,
 | 
					 | 
				
			||||||
    Class,
 | 
					 | 
				
			||||||
    Function,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from dependency_injector.providers.config import (
 | 
					 | 
				
			||||||
    Config,
 | 
					 | 
				
			||||||
    ChildConfig,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from dependency_injector.providers.utils import (
 | 
					 | 
				
			||||||
    OverridingContext,
 | 
					 | 
				
			||||||
    override,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = (
 | 
					__all__ = (
 | 
				
			||||||
    'Provider',
 | 
					    'Provider',
 | 
				
			||||||
    'Delegate',
 | 
					    'Delegate',
 | 
				
			||||||
    'Static', 'StaticProvider',
 | 
					    'Object',
 | 
				
			||||||
    'ExternalDependency',
 | 
					    'ExternalDependency',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    'OverridingContext',
 | 
				
			||||||
 | 
					    'override',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'Callable',
 | 
					    'Callable',
 | 
				
			||||||
    'DelegatedCallable',
 | 
					    'DelegatedCallable',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,15 +36,4 @@ __all__ = (
 | 
				
			||||||
    'DelegatedFactory',
 | 
					    'DelegatedFactory',
 | 
				
			||||||
    'Singleton',
 | 
					    'Singleton',
 | 
				
			||||||
    'DelegatedSingleton',
 | 
					    'DelegatedSingleton',
 | 
				
			||||||
 | 
					 | 
				
			||||||
    'Object',
 | 
					 | 
				
			||||||
    'Value',
 | 
					 | 
				
			||||||
    'Class',
 | 
					 | 
				
			||||||
    'Function',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    'Config',
 | 
					 | 
				
			||||||
    'ChildConfig',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    'OverridingContext',
 | 
					 | 
				
			||||||
    'override',
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector.providers.utils import OverridingContext
 | 
					 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
from dependency_injector.utils import (
 | 
					from dependency_injector.utils import (
 | 
				
			||||||
    is_provider,
 | 
					    is_provider,
 | 
				
			||||||
| 
						 | 
					@ -52,7 +51,7 @@ class Provider(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    All providers should extend this class.
 | 
					    All providers should extend this class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: overridden_by
 | 
					    .. py:attribute:: overridden
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Tuple of overriding providers, if any.
 | 
					        Tuple of overriding providers, if any.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,11 +60,11 @@ class Provider(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __IS_PROVIDER__ = True
 | 
					    __IS_PROVIDER__ = True
 | 
				
			||||||
    __OPTIMIZED_CALLS__ = True
 | 
					    __OPTIMIZED_CALLS__ = True
 | 
				
			||||||
    __slots__ = ('overridden_by', 'provide', '__call__')
 | 
					    __slots__ = ('overridden', 'provide', '__call__')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        """Initializer."""
 | 
					        """Initializer."""
 | 
				
			||||||
        self.overridden_by = None
 | 
					        self.overridden = tuple()
 | 
				
			||||||
        super(Provider, self).__init__()
 | 
					        super(Provider, self).__init__()
 | 
				
			||||||
        # Enable __call__() / _provide() optimization
 | 
					        # Enable __call__() / _provide() optimization
 | 
				
			||||||
        if self.__class__.__OPTIMIZED_CALLS__:
 | 
					        if self.__class__.__OPTIMIZED_CALLS__:
 | 
				
			||||||
| 
						 | 
					@ -82,23 +81,16 @@ class Provider(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _call_last_overriding(self, *args, **kwargs):
 | 
					    def _call_last_overriding(self, *args, **kwargs):
 | 
				
			||||||
        """Call last overriding provider and return result."""
 | 
					        """Call last overriding provider and return result."""
 | 
				
			||||||
        return self.last_overriding(*args, **kwargs)
 | 
					        return (self.overridden[-1](*args, **kwargs)
 | 
				
			||||||
 | 
					                if self.overridden
 | 
				
			||||||
 | 
					                else None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    def provide_injection(self):
 | 
				
			||||||
    def is_overridden(self):
 | 
					        """Injection strategy implementation.
 | 
				
			||||||
        """Read-only property that is set to ``True`` if provider is overridden.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: bool
 | 
					        :rtype: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        return bool(self.overridden_by)
 | 
					        return self.provide()
 | 
				
			||||||
 | 
					 | 
				
			||||||
    @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):
 | 
					    def override(self, provider):
 | 
				
			||||||
        """Override provider with another provider.
 | 
					        """Override provider with another provider.
 | 
				
			||||||
| 
						 | 
					@ -116,12 +108,9 @@ class Provider(object):
 | 
				
			||||||
                        'with itself'.format(self))
 | 
					                        'with itself'.format(self))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not is_provider(provider):
 | 
					        if not is_provider(provider):
 | 
				
			||||||
            provider = Static(provider)
 | 
					            provider = Object(provider)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not self.is_overridden:
 | 
					        self.overridden += (ensure_is_provider(provider),)
 | 
				
			||||||
            self.overridden_by = (ensure_is_provider(provider),)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            self.overridden_by += (ensure_is_provider(provider),)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Disable __call__() / _provide() optimization
 | 
					        # Disable __call__() / _provide() optimization
 | 
				
			||||||
        if self.__class__.__OPTIMIZED_CALLS__:
 | 
					        if self.__class__.__OPTIMIZED_CALLS__:
 | 
				
			||||||
| 
						 | 
					@ -137,11 +126,12 @@ class Provider(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if not self.overridden_by:
 | 
					        if not self.overridden:
 | 
				
			||||||
            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
					            raise Error('Provider {0} is not overridden'.format(str(self)))
 | 
				
			||||||
        self.overridden_by = self.overridden_by[:-1]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not self.is_overridden:
 | 
					        self.overridden = self.overridden[:-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not self.overridden:
 | 
				
			||||||
            # Enable __call__() / _provide() optimization
 | 
					            # Enable __call__() / _provide() optimization
 | 
				
			||||||
            if self.__class__.__OPTIMIZED_CALLS__:
 | 
					            if self.__class__.__OPTIMIZED_CALLS__:
 | 
				
			||||||
                self.__call__ = self.provide = self._provide
 | 
					                self.__call__ = self.provide = self._provide
 | 
				
			||||||
| 
						 | 
					@ -151,7 +141,7 @@ class Provider(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: None
 | 
					        :rtype: None
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.overridden_by = None
 | 
					        self.overridden = tuple()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Enable __call__() / _provide() optimization
 | 
					        # Enable __call__() / _provide() optimization
 | 
				
			||||||
        if self.__class__.__OPTIMIZED_CALLS__:
 | 
					        if self.__class__.__OPTIMIZED_CALLS__:
 | 
				
			||||||
| 
						 | 
					@ -229,11 +219,8 @@ class Delegate(Provider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					@six.python_2_unicode_compatible
 | 
				
			||||||
class Static(Provider):
 | 
					class Object(Provider):
 | 
				
			||||||
    """:py:class:`Static` provider returns provided instance "as is".
 | 
					    """:py:class:`Object` provider returns provided instance "as is".
 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`Static` provider is base implementation that provides exactly
 | 
					 | 
				
			||||||
    the same as it got on input.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: provides
 | 
					    .. py:attribute:: provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -251,7 +238,7 @@ class Static(Provider):
 | 
				
			||||||
        :type provides: object
 | 
					        :type provides: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.provides = provides
 | 
					        self.provides = provides
 | 
				
			||||||
        super(Static, self).__init__()
 | 
					        super(Object, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _provide(self, *args, **kwargs):
 | 
					    def _provide(self, *args, **kwargs):
 | 
				
			||||||
        """Return provided instance.
 | 
					        """Return provided instance.
 | 
				
			||||||
| 
						 | 
					@ -276,10 +263,6 @@ class Static(Provider):
 | 
				
			||||||
    __repr__ = __str__
 | 
					    __repr__ = __str__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
StaticProvider = Static
 | 
					 | 
				
			||||||
# Backward compatibility for versions < 1.11.1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					@six.python_2_unicode_compatible
 | 
				
			||||||
class ExternalDependency(Provider):
 | 
					class ExternalDependency(Provider):
 | 
				
			||||||
    """:py:class:`ExternalDependency` provider describes dependency interface.
 | 
					    """:py:class:`ExternalDependency` provider describes dependency interface.
 | 
				
			||||||
| 
						 | 
					@ -312,6 +295,7 @@ class ExternalDependency(Provider):
 | 
				
			||||||
            raise Error('ExternalDependency provider expects to get class, ' +
 | 
					            raise Error('ExternalDependency provider expects to get class, ' +
 | 
				
			||||||
                        'got {0} instead'.format(str(instance_of)))
 | 
					                        'got {0} instead'.format(str(instance_of)))
 | 
				
			||||||
        self.instance_of = instance_of
 | 
					        self.instance_of = instance_of
 | 
				
			||||||
 | 
					        self.provide = self.__call__
 | 
				
			||||||
        super(ExternalDependency, self).__init__()
 | 
					        super(ExternalDependency, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __call__(self, *args, **kwargs):
 | 
					    def __call__(self, *args, **kwargs):
 | 
				
			||||||
| 
						 | 
					@ -327,10 +311,10 @@ class ExternalDependency(Provider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: object
 | 
					        :rtype: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if not self.is_overridden:
 | 
					        if not self.overridden:
 | 
				
			||||||
            raise Error('Dependency is not defined')
 | 
					            raise Error('Dependency is not defined')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        instance = self.last_overriding(*args, **kwargs)
 | 
					        instance = self._call_last_overriding(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not isinstance(instance, self.instance_of):
 | 
					        if not isinstance(instance, self.instance_of):
 | 
				
			||||||
            raise Error('{0} is not an '.format(instance) +
 | 
					            raise Error('{0} is not an '.format(instance) +
 | 
				
			||||||
| 
						 | 
					@ -356,3 +340,77 @@ class ExternalDependency(Provider):
 | 
				
			||||||
        return represent_provider(provider=self, provides=self.instance_of)
 | 
					        return represent_provider(provider=self, provides=self.instance_of)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __repr__ = __str__
 | 
					    __repr__ = __str__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OverridingContext(object):
 | 
				
			||||||
 | 
					    """Provider overriding context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :py:class:`OverridingContext` is used by :py:meth:`Provider.override` for
 | 
				
			||||||
 | 
					    implemeting ``with`` contexts. When :py:class:`OverridingContext` is
 | 
				
			||||||
 | 
					    closed, overriding that was created in this context is dropped also.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with provider.override(another_provider):
 | 
				
			||||||
 | 
					            assert provider.overridden
 | 
				
			||||||
 | 
					        assert not provider.overridden
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, overridden, overriding):
 | 
				
			||||||
 | 
					        """Initializer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param overridden: Overridden provider.
 | 
				
			||||||
 | 
					        :type overridden: :py:class:`Provider`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :param overriding: Overriding provider.
 | 
				
			||||||
 | 
					        :type overriding: :py:class:`Provider`
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.overridden = overridden
 | 
				
			||||||
 | 
					        self.overriding = overriding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __enter__(self):
 | 
				
			||||||
 | 
					        """Do nothing."""
 | 
				
			||||||
 | 
					        return self.overriding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __exit__(self, *_):
 | 
				
			||||||
 | 
					        """Exit overriding context."""
 | 
				
			||||||
 | 
					        self.overridden.reset_last_overriding()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def override(overridden):
 | 
				
			||||||
 | 
					    """Decorator for overriding providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This decorator overrides ``overridden`` provider by decorated one.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Factory
 | 
				
			||||||
 | 
					        class SomeClass(object):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @override(SomeClass)
 | 
				
			||||||
 | 
					        @Factory
 | 
				
			||||||
 | 
					        class ExtendedSomeClass(SomeClass.cls):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param overridden: Provider that should be overridden.
 | 
				
			||||||
 | 
					    :type overridden: :py:class:`Provider`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :return: Overriding provider.
 | 
				
			||||||
 | 
					    :rtype: :py:class:`Provider`
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    def decorator(overriding):
 | 
				
			||||||
 | 
					        overridden.override(overriding)
 | 
				
			||||||
 | 
					        return overriding
 | 
				
			||||||
 | 
					    return decorator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _parse_positional_injections(args):
 | 
				
			||||||
 | 
					    return tuple(arg if is_provider(arg) else Object(arg)
 | 
				
			||||||
 | 
					                 for arg in args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _parse_keyword_injections(kwargs):
 | 
				
			||||||
 | 
					    return dict((name, arg if is_provider(arg) else Object(arg))
 | 
				
			||||||
 | 
					                for name, arg in six.iteritems(kwargs))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,10 +2,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector.providers.base import Provider
 | 
					from dependency_injector.providers.base import (
 | 
				
			||||||
from dependency_injector.injections import (
 | 
					    Provider,
 | 
				
			||||||
    _parse_args_injections,
 | 
					    _parse_positional_injections,
 | 
				
			||||||
    _parse_kwargs_injections,
 | 
					    _parse_keyword_injections,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from dependency_injector.utils import represent_provider
 | 
					from dependency_injector.utils import represent_provider
 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
| 
						 | 
					@ -13,45 +13,27 @@ from dependency_injector.errors import Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					@six.python_2_unicode_compatible
 | 
				
			||||||
class Callable(Provider):
 | 
					class Callable(Provider):
 | 
				
			||||||
    """:py:class:`Callable` provider calls wrapped callable on every call.
 | 
					    r""":py:class:`Callable` provider calls wrapped callable on every call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :py:class:`Callable` provider provides callable that is called on every
 | 
					    :py:class:`Callable` supports positional and keyword argument injections:
 | 
				
			||||||
    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
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # simplified syntax for passing positional and keyword argument
 | 
					 | 
				
			||||||
        # injections:
 | 
					 | 
				
			||||||
        some_function = Callable(some_function, 'arg1', 'arg2', arg3=3, arg4=4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # extended (full) syntax for passing positional and keyword argument
 | 
					 | 
				
			||||||
        # injections:
 | 
					 | 
				
			||||||
        some_function = Callable(some_function,
 | 
					        some_function = Callable(some_function,
 | 
				
			||||||
                                 injections.Arg(1),
 | 
					                                 'positional_arg1', 'positional_arg2',
 | 
				
			||||||
                                 injections.Arg(2),
 | 
					                                 keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
                                 injections.KwArg('some_arg', 3),
 | 
					 | 
				
			||||||
                                 injections.KwArg('other_arg', 4))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: provides
 | 
					        # or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Provided callable.
 | 
					        some_function = Callable(some_function) \
 | 
				
			||||||
 | 
					            .add_args('positional_arg1', 'positional_arg2') \
 | 
				
			||||||
 | 
					            .add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: callable
 | 
					        # or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: args
 | 
					        some_function = Callable(some_function)
 | 
				
			||||||
 | 
					        some_function.add_args('positional_arg1', 'positional_arg2')
 | 
				
			||||||
        Tuple of positional argument injections.
 | 
					        some_function.add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: kwargs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of keyword argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __slots__ = ('provides', 'args', 'kwargs')
 | 
					    __slots__ = ('provides', 'args', 'kwargs')
 | 
				
			||||||
| 
						 | 
					@ -61,12 +43,6 @@ class Callable(Provider):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param provides: Wrapped callable.
 | 
					        :param provides: Wrapped callable.
 | 
				
			||||||
        :type provides: callable
 | 
					        :type provides: callable
 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param args: Tuple of injections.
 | 
					 | 
				
			||||||
        :type args: tuple
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param kwargs: Dictionary of injections.
 | 
					 | 
				
			||||||
        :type kwargs: dict
 | 
					 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if not callable(provides):
 | 
					        if not callable(provides):
 | 
				
			||||||
            raise Error('Provider {0} expected to get callable, '
 | 
					            raise Error('Provider {0} expected to get callable, '
 | 
				
			||||||
| 
						 | 
					@ -77,31 +53,34 @@ class Callable(Provider):
 | 
				
			||||||
        self.provides = provides
 | 
					        self.provides = provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.args = tuple()
 | 
					        self.args = tuple()
 | 
				
			||||||
        self.kwargs = tuple()
 | 
					        self.kwargs = dict()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.add_injections(*args, **kwargs)
 | 
					        self.add_args(*args)
 | 
				
			||||||
 | 
					        self.add_kwargs(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        super(Callable, self).__init__()
 | 
					        super(Callable, self).__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    def add_args(self, *args):
 | 
				
			||||||
    def injections(self):
 | 
					        """Add postional argument injections.
 | 
				
			||||||
        """Read-only tuple of all injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.args + self.kwargs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def add_injections(self, *args, **kwargs):
 | 
					 | 
				
			||||||
        """Add provider injections.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param args: Tuple of injections.
 | 
					        :param args: Tuple of injections.
 | 
				
			||||||
        :type args: tuple
 | 
					        :type args: tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.args += _parse_positional_injections(args)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add_kwargs(self, **kwargs):
 | 
				
			||||||
 | 
					        """Add keyword argument injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param kwargs: Dictionary of injections.
 | 
					        :param kwargs: Dictionary of injections.
 | 
				
			||||||
        :type kwargs: dict
 | 
					        :type kwargs: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.args += _parse_args_injections(args)
 | 
					        self.kwargs.update(_parse_keyword_injections(kwargs))
 | 
				
			||||||
        self.kwargs += _parse_kwargs_injections(args, kwargs)
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _provide(self, *args, **kwargs):
 | 
					    def _provide(self, *args, **kwargs):
 | 
				
			||||||
        """Return provided instance.
 | 
					        """Return provided instance.
 | 
				
			||||||
| 
						 | 
					@ -115,11 +94,11 @@ class Callable(Provider):
 | 
				
			||||||
        :rtype: object
 | 
					        :rtype: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if self.args:
 | 
					        if self.args:
 | 
				
			||||||
            args = tuple(arg.value for arg in self.args) + args
 | 
					            args = tuple(arg.provide_injection() for arg in self.args) + args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for kwarg in self.kwargs:
 | 
					        for name, arg in six.iteritems(self.kwargs):
 | 
				
			||||||
            if kwarg.name not in kwargs:
 | 
					            if name not in kwargs:
 | 
				
			||||||
                kwargs[kwarg.name] = kwarg.value
 | 
					                kwargs[name] = arg.provide_injection()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return self.provides(*args, **kwargs)
 | 
					        return self.provides(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,24 +117,11 @@ class DelegatedCallable(Callable):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :py:class:`DelegatedCallable` is a :py:class:`Callable`, that is injected
 | 
					    :py:class:`DelegatedCallable` is a :py:class:`Callable`, that is injected
 | 
				
			||||||
    "as is".
 | 
					    "as is".
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provides
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Provided callable.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: callable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: args
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of positional argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: kwargs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of keyword argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __IS_DELEGATED__ = True
 | 
					    def provide_injection(self):
 | 
				
			||||||
 | 
					        """Injection strategy implementation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: object
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,138 +0,0 @@
 | 
				
			||||||
"""Dependency injector config providers."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import six
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.providers.base import Provider
 | 
					 | 
				
			||||||
from dependency_injector.utils import represent_provider
 | 
					 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class Config(Provider):
 | 
					 | 
				
			||||||
    """:py:class:`Config` provider provide dict values.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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:
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    value = value[path]
 | 
					 | 
				
			||||||
                except KeyError:
 | 
					 | 
				
			||||||
                    raise Error('Config key '
 | 
					 | 
				
			||||||
                                '"{0}" is undefined'.format('.'.join(paths)))
 | 
					 | 
				
			||||||
        return value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def update_from(self, value):
 | 
					 | 
				
			||||||
        """Update current value from another one.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param value: Configuration dictionary.
 | 
					 | 
				
			||||||
        :type value: dict[str, object]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: None
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.value.update(value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """Return string representation of provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return represent_provider(provider=self, provides=self.value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __repr__ = __str__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@six.python_2_unicode_compatible
 | 
					 | 
				
			||||||
class ChildConfig(Provider):
 | 
					 | 
				
			||||||
    """:py:class:`ChildConfig` provider provides value from :py:class:`Config`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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
 | 
					 | 
				
			||||||
        self.root_config = root_config
 | 
					 | 
				
			||||||
        super(ChildConfig, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __getattr__(self, item):
 | 
					 | 
				
			||||||
        """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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __str__(self):
 | 
					 | 
				
			||||||
        """Return string representation of provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: str
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return represent_provider(provider=self,
 | 
					 | 
				
			||||||
                                  provides='.'.join(self.parents))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    __repr__ = __str__
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,41 +1,53 @@
 | 
				
			||||||
"""Dependency injector creational providers."""
 | 
					"""Dependency injector creational providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector.providers.callable import Callable
 | 
					from dependency_injector.providers.callable import Callable
 | 
				
			||||||
from dependency_injector.utils import (
 | 
					from dependency_injector.providers.base import _parse_keyword_injections
 | 
				
			||||||
    is_attribute_injection,
 | 
					from dependency_injector.utils import GLOBAL_LOCK
 | 
				
			||||||
    is_method_injection,
 | 
					 | 
				
			||||||
    GLOBAL_LOCK,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					from dependency_injector.errors import Error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Factory(Callable):
 | 
					class Factory(Callable):
 | 
				
			||||||
    """:py:class:`Factory` provider creates new instance on every call.
 | 
					    r""":py:class:`Factory` provider creates new instance on every call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :py:class:`Factory` supports different syntaxes of passing injections:
 | 
					    :py:class:`Factory` supports positional & keyword argument injections,
 | 
				
			||||||
 | 
					    as well as attribute injections.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Positional and keyword argument injections could be defined like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. code-block:: python
 | 
					    .. 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,
 | 
					        factory = Factory(SomeClass,
 | 
				
			||||||
                          injections.Arg(1),
 | 
					                          'positional_arg1', 'positional_arg2',
 | 
				
			||||||
                          injections.Arg(2),
 | 
					                          keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
                          injections.KwArg('some_arg', 3),
 | 
					
 | 
				
			||||||
                          injections.KwArg('other_arg', 4),
 | 
					        # or
 | 
				
			||||||
                          injections.Attribute('some_attribute', 5))
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass) \
 | 
				
			||||||
 | 
					            .add_args('positional_arg1', 'positional_arg2') \
 | 
				
			||||||
 | 
					            .add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass)
 | 
				
			||||||
 | 
					        factory.add_args('positional_arg1', 'positional_arg2')
 | 
				
			||||||
 | 
					        factory.add_kwargs(keyword_argument1=3, keyword_argument=4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Attribute injections are defined by using :py:meth:`Factory.attributes`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        factory = Factory(SomeClass) \
 | 
				
			||||||
 | 
					            .add_attributes(attribute1=1, attribute2=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Retrieving of provided instance can be performed via calling
 | 
					    Retrieving of provided instance can be performed via calling
 | 
				
			||||||
    :py:class:`Factory` object:
 | 
					    :py:class:`Factory` object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. code-block:: python
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        factory = Factory(SomeClass,
 | 
					        factory = Factory(SomeClass)
 | 
				
			||||||
                          some_arg1=1,
 | 
					 | 
				
			||||||
                          some_arg2=2)
 | 
					 | 
				
			||||||
        some_object = factory()
 | 
					        some_object = factory()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: provided_type
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
| 
						 | 
					@ -46,47 +58,17 @@ class Factory(Callable):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: type | None
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: provides
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class or other callable that provides object.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | callable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Class that provides object.
 | 
					        Class that provides object.
 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: type
 | 
					        :type: type
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: args
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of positional argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: kwargs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of keyword argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: attributes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of attribute injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Attribute`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: methods
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of method injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Method`]
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    provided_type = None
 | 
					    provided_type = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __slots__ = ('cls', 'attributes', 'methods')
 | 
					    __slots__ = ('cls', 'attributes')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, provides, *args, **kwargs):
 | 
					    def __init__(self, provides, *args, **kwargs):
 | 
				
			||||||
        """Initializer.
 | 
					        """Initializer.
 | 
				
			||||||
| 
						 | 
					@ -94,51 +76,28 @@ class Factory(Callable):
 | 
				
			||||||
        :param provides: Class or other callable that provides object
 | 
					        :param provides: Class or other callable that provides object
 | 
				
			||||||
            for creation.
 | 
					            for creation.
 | 
				
			||||||
        :type provides: type | callable
 | 
					        :type provides: type | callable
 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param args: Tuple of injections.
 | 
					 | 
				
			||||||
        :type args: tuple
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param kwargs: Dictionary of injections.
 | 
					 | 
				
			||||||
        :type kwargs: dict
 | 
					 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if (self.__class__.provided_type and
 | 
					        if (self.__class__.provided_type and
 | 
				
			||||||
                not issubclass(provides, self.__class__.provided_type)):
 | 
					                not issubclass(provides, self.__class__.provided_type)):
 | 
				
			||||||
            raise Error('{0} can provide only {1} instances'.format(
 | 
					            raise Error('{0} can provide only {1} instances'.format(
 | 
				
			||||||
                self.__class__, self.__class__.provided_type))
 | 
					                self.__class__, self.__class__.provided_type))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.attributes = tuple()
 | 
					        self.attributes = dict()
 | 
				
			||||||
        self.methods = tuple()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        super(Factory, self).__init__(provides, *args, **kwargs)
 | 
					        super(Factory, self).__init__(provides, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.cls = self.provides
 | 
					        self.cls = self.provides
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    def add_attributes(self, **kwargs):
 | 
				
			||||||
    def injections(self):
 | 
					        """Add attribute injections.
 | 
				
			||||||
        """Read-only tuple of all injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        return self.args + self.kwargs + self.attributes + self.methods
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def add_injections(self, *args, **kwargs):
 | 
					 | 
				
			||||||
        """Add provider injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param args: Tuple of injections.
 | 
					 | 
				
			||||||
        :type args: tuple
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param kwargs: Dictionary of injections.
 | 
					        :param kwargs: Dictionary of injections.
 | 
				
			||||||
        :type kwargs: dict
 | 
					        :type kwargs: dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :return: Reference ``self``
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.attributes += tuple(injection
 | 
					        self.attributes.update(_parse_keyword_injections(kwargs))
 | 
				
			||||||
                                 for injection in args
 | 
					        return self
 | 
				
			||||||
                                 if is_attribute_injection(injection))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.methods += tuple(injection
 | 
					 | 
				
			||||||
                              for injection in args
 | 
					 | 
				
			||||||
                              if is_method_injection(injection))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        super(Factory, self).add_injections(*args, **kwargs)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _provide(self, *args, **kwargs):
 | 
					    def _provide(self, *args, **kwargs):
 | 
				
			||||||
        """Return provided instance.
 | 
					        """Return provided instance.
 | 
				
			||||||
| 
						 | 
					@ -151,19 +110,10 @@ class Factory(Callable):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: object
 | 
					        :rtype: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if self.args:
 | 
					        instance = super(Factory, self)._provide(*args, **kwargs)
 | 
				
			||||||
            args = tuple(arg.value for arg in self.args) + args
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for kwarg in self.kwargs:
 | 
					        for name, arg in six.iteritems(self.attributes):
 | 
				
			||||||
            if kwarg.name not in kwargs:
 | 
					            setattr(instance, name, arg.provide_injection())
 | 
				
			||||||
                kwargs[kwarg.name] = kwarg.value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        instance = self.provides(*args, **kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for attribute in self.attributes:
 | 
					 | 
				
			||||||
            setattr(instance, attribute.name, attribute.value)
 | 
					 | 
				
			||||||
        for method in self.methods:
 | 
					 | 
				
			||||||
            getattr(instance, method.name)(method.value)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return instance
 | 
					        return instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -182,45 +132,20 @@ class DelegatedFactory(Factory):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: type | None
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: provides
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class or other callable that provides object.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | callable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Class that provides object.
 | 
					        Class that provides object.
 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: type
 | 
					        :type: type
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: args
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of positional argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: kwargs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of keyword argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: attributes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of attribute injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Attribute`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: methods
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of method injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Method`]
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __IS_DELEGATED__ = True
 | 
					    def provide_injection(self):
 | 
				
			||||||
 | 
					        """Injection strategy implementation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: object
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Singleton(Factory):
 | 
					class Singleton(Factory):
 | 
				
			||||||
| 
						 | 
					@ -238,9 +163,7 @@ class Singleton(Factory):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. code-block:: python
 | 
					    .. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        singleton = Singleton(SomeClass,
 | 
					        singleton = Singleton(SomeClass)
 | 
				
			||||||
                              some_arg1=1,
 | 
					 | 
				
			||||||
                              some_arg2=2)
 | 
					 | 
				
			||||||
        some_object = singleton()
 | 
					        some_object = singleton()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: provided_type
 | 
					    .. py:attribute:: provided_type
 | 
				
			||||||
| 
						 | 
					@ -251,48 +174,12 @@ class Singleton(Factory):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: type | None
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: instance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Read-only reference to singleton's instance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: object
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provides
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class or other callable that provides object.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | callable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Class that provides object.
 | 
					        Class that provides object.
 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: type
 | 
					        :type: type
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: args
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of positional argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: kwargs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of keyword argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: attributes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of attribute injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Attribute`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: methods
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of method injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Method`]
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __slots__ = ('instance',)
 | 
					    __slots__ = ('instance',)
 | 
				
			||||||
| 
						 | 
					@ -303,12 +190,6 @@ class Singleton(Factory):
 | 
				
			||||||
        :param provides: Class or other callable that provides object
 | 
					        :param provides: Class or other callable that provides object
 | 
				
			||||||
            for creation.
 | 
					            for creation.
 | 
				
			||||||
        :type provides: type | callable
 | 
					        :type provides: type | callable
 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param args: Tuple of injections.
 | 
					 | 
				
			||||||
        :type args: tuple
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param kwargs: Dictionary of injections.
 | 
					 | 
				
			||||||
        :type kwargs: dict
 | 
					 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        self.instance = None
 | 
					        self.instance = None
 | 
				
			||||||
        super(Singleton, self).__init__(provides, *args, **kwargs)
 | 
					        super(Singleton, self).__init__(provides, *args, **kwargs)
 | 
				
			||||||
| 
						 | 
					@ -331,12 +212,10 @@ class Singleton(Factory):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :rtype: object
 | 
					        :rtype: object
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        if self.instance:
 | 
					 | 
				
			||||||
            return self.instance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        with GLOBAL_LOCK:
 | 
					        with GLOBAL_LOCK:
 | 
				
			||||||
            self.instance = super(Singleton, self)._provide(*args, **kwargs)
 | 
					            if self.instance is None:
 | 
				
			||||||
 | 
					                self.instance = super(Singleton, self)._provide(*args,
 | 
				
			||||||
 | 
					                                                                **kwargs)
 | 
				
			||||||
        return self.instance
 | 
					        return self.instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,48 +233,17 @@ class DelegatedSingleton(Singleton):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: type | None
 | 
					        :type: type | None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .. py:attribute:: instance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Read-only reference to singleton's instance.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: object
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: provides
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Class or other callable that provides object.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: type | callable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: cls
 | 
					    .. py:attribute:: cls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Class that provides object.
 | 
					        Class that provides object.
 | 
				
			||||||
        Alias for :py:attr:`provides`.
 | 
					        Alias for :py:attr:`provides`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :type: type
 | 
					        :type: type
 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: args
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of positional argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Arg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: kwargs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of keyword argument injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.KwArg`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: attributes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of attribute injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Attribute`]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. py:attribute:: methods
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Tuple of method injections.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :type: tuple[:py:class:`dependency_injector.injections.Method`]
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    __IS_DELEGATED__ = True
 | 
					    def provide_injection(self):
 | 
				
			||||||
 | 
					        """Injection strategy implementation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :rtype: object
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,43 +0,0 @@
 | 
				
			||||||
"""Dependency injector static providers."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector.providers.base import Static
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Class(Static):
 | 
					 | 
				
			||||||
    """:py:class:`Class` returns provided class "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        cls_provider = Class(object)
 | 
					 | 
				
			||||||
        object_cls = cls_provider()
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Object(Static):
 | 
					 | 
				
			||||||
    """:py:class:`Object` returns provided object "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        object_provider = Object(object())
 | 
					 | 
				
			||||||
        object_instance = object_provider()
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Function(Static):
 | 
					 | 
				
			||||||
    """:py:class:`Function` returns provided function "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        function_provider = Function(len)
 | 
					 | 
				
			||||||
        len_function = function_provider()
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Value(Static):
 | 
					 | 
				
			||||||
    """:py:class:`Value` returns provided value "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        value_provider = Value(31337)
 | 
					 | 
				
			||||||
        value = value_provider()
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,65 +0,0 @@
 | 
				
			||||||
"""Dependency injector provider utils."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class OverridingContext(object):
 | 
					 | 
				
			||||||
    """Provider overriding context.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :py:class:`OverridingContext` is used by :py:meth:`Provider.override` for
 | 
					 | 
				
			||||||
    implemeting ``with`` contexts. When :py:class:`OverridingContext` is
 | 
					 | 
				
			||||||
    closed, overriding that was created in this context is dropped also.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        with provider.override(another_provider):
 | 
					 | 
				
			||||||
            assert provider.is_overridden
 | 
					 | 
				
			||||||
        assert not provider.is_overridden
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, overridden, overriding):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param overridden: Overridden provider.
 | 
					 | 
				
			||||||
        :type overridden: :py:class:`Provider`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param overriding: Overriding provider.
 | 
					 | 
				
			||||||
        :type overriding: :py:class:`Provider`
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.overridden = overridden
 | 
					 | 
				
			||||||
        self.overriding = overriding
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __enter__(self):
 | 
					 | 
				
			||||||
        """Do nothing."""
 | 
					 | 
				
			||||||
        return self.overriding
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __exit__(self, *_):
 | 
					 | 
				
			||||||
        """Exit overriding context."""
 | 
					 | 
				
			||||||
        self.overridden.reset_last_overriding()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def override(overridden):
 | 
					 | 
				
			||||||
    """Decorator for overriding providers.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    This decorator overrides ``overridden`` provider by decorated one.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    .. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @Factory
 | 
					 | 
				
			||||||
        class SomeClass(object):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @override(SomeClass)
 | 
					 | 
				
			||||||
        @Factory
 | 
					 | 
				
			||||||
        class ExtendedSomeClass(SomeClass.cls):
 | 
					 | 
				
			||||||
            pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :param overridden: Provider that should be overridden.
 | 
					 | 
				
			||||||
    :type overridden: :py:class:`Provider`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :return: Overriding provider.
 | 
					 | 
				
			||||||
    :rtype: :py:class:`Provider`
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    def decorator(overriding):
 | 
					 | 
				
			||||||
        overridden.override(overriding)
 | 
					 | 
				
			||||||
        return overriding
 | 
					 | 
				
			||||||
    return decorator
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,13 +1,13 @@
 | 
				
			||||||
"""Utils module."""
 | 
					"""Dependency injector utils module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import copy
 | 
					import copy as _copy
 | 
				
			||||||
import types
 | 
					import types
 | 
				
			||||||
import threading
 | 
					import threading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import six
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector.errors import Error
 | 
					from dependency_injector import errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLOBAL_LOCK = threading.RLock()
 | 
					GLOBAL_LOCK = threading.RLock()
 | 
				
			||||||
| 
						 | 
					@ -23,9 +23,9 @@ else:  # pragma: no cover
 | 
				
			||||||
    _OBJECT_INIT = None
 | 
					    _OBJECT_INIT = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if six.PY2:  # pragma: no cover
 | 
					if six.PY2:  # pragma: no cover
 | 
				
			||||||
    copy._deepcopy_dispatch[types.MethodType] = \
 | 
					    _copy._deepcopy_dispatch[types.MethodType] = \
 | 
				
			||||||
        lambda obj, memo: type(obj)(obj.im_func,
 | 
					        lambda obj, memo: type(obj)(obj.im_func,
 | 
				
			||||||
                                    copy.deepcopy(obj.im_self, memo),
 | 
					                                    _copy.deepcopy(obj.im_self, memo),
 | 
				
			||||||
                                    obj.im_class)
 | 
					                                    obj.im_class)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,168 +54,21 @@ def ensure_is_provider(instance):
 | 
				
			||||||
    :rtype: :py:class:`dependency_injector.providers.Provider`
 | 
					    :rtype: :py:class:`dependency_injector.providers.Provider`
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    if not is_provider(instance):
 | 
					    if not is_provider(instance):
 | 
				
			||||||
        raise Error('Expected provider instance, '
 | 
					        raise errors.Error('Expected provider instance, '
 | 
				
			||||||
                    'got {0}'.format(str(instance)))
 | 
					                           'got {0}'.format(str(instance)))
 | 
				
			||||||
    return instance
 | 
					    return instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_delegated_provider(instance):
 | 
					def is_container(instance):
 | 
				
			||||||
    """Check if instance is delegated provider instance.
 | 
					    """Check if instance is container instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :param instance: Instance to be checked.
 | 
					    :param instance: Instance to be checked.
 | 
				
			||||||
    :type instance: object
 | 
					    :type instance: object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    :rtype: bool
 | 
					    :rtype: bool
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    return (is_provider(instance) and
 | 
					    return (hasattr(instance, '__IS_CONTAINER__') and
 | 
				
			||||||
            hasattr(instance, '__IS_DELEGATED__') and
 | 
					            getattr(instance, '__IS_CONTAINER__', False) is True)
 | 
				
			||||||
            getattr(instance, '__IS_DELEGATED__') is True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def 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 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)))
 | 
					 | 
				
			||||||
    return instance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def is_arg_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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def ensure_is_catalog_bundle(instance):
 | 
					 | 
				
			||||||
    """Check if instance is catalog bundle 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 catalog bundle.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    :rtype: :py:class:`dependency_injector.catalogs.CatalogBundle`
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    if not is_catalog_bundle(instance):
 | 
					 | 
				
			||||||
        raise Error('Expected catalog bundle instance, '
 | 
					 | 
				
			||||||
                    'got {0}'.format(str(instance)))
 | 
					 | 
				
			||||||
    return instance
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def represent_provider(provider, provides):
 | 
					def represent_provider(provider, provides):
 | 
				
			||||||
| 
						 | 
					@ -255,6 +108,6 @@ def fetch_cls_init(cls):
 | 
				
			||||||
        return cls_init
 | 
					        return cls_init
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _copy_providers(providers, memo=None):
 | 
					def deepcopy(instance, memo=None):
 | 
				
			||||||
    """Make full copy of providers dictionary."""
 | 
					    """Make full copy of instance."""
 | 
				
			||||||
    return copy.deepcopy(providers, memo)
 | 
					    return _copy.deepcopy(instance, memo)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +0,0 @@
 | 
				
			||||||
``dependency_injector.catalogs``
 | 
					 | 
				
			||||||
--------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. automodule:: dependency_injector.catalogs
 | 
					 | 
				
			||||||
   :members:
 | 
					 | 
				
			||||||
   :special-members:
 | 
					 | 
				
			||||||
							
								
								
									
										6
									
								
								docs/api/containers.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					``dependency_injector.containers``
 | 
				
			||||||
 | 
					--------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. automodule:: dependency_injector.containers
 | 
				
			||||||
 | 
					   :members:
 | 
				
			||||||
 | 
					   :special-members:
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ API Documentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    top_level
 | 
					    top_level
 | 
				
			||||||
    providers
 | 
					    providers
 | 
				
			||||||
 | 
					    containers
 | 
				
			||||||
    injections
 | 
					    injections
 | 
				
			||||||
    catalogs
 | 
					 | 
				
			||||||
    utils
 | 
					    utils
 | 
				
			||||||
    errors
 | 
					    errors
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,3 +4,4 @@
 | 
				
			||||||
.. automodule:: dependency_injector.injections
 | 
					.. automodule:: dependency_injector.injections
 | 
				
			||||||
   :members:
 | 
					   :members:
 | 
				
			||||||
   :inherited-members:
 | 
					   :inherited-members:
 | 
				
			||||||
 | 
					   :show-inheritance:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,10 @@
 | 
				
			||||||
``dependency_injector.providers``
 | 
					``dependency_injector.providers``
 | 
				
			||||||
---------------------------------
 | 
					---------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. image:: /images/providers/providers_class_diagram.png
 | 
				
			||||||
 | 
					    :width: 100%
 | 
				
			||||||
 | 
					    :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. automodule:: dependency_injector.providers
 | 
					.. automodule:: dependency_injector.providers
 | 
				
			||||||
   :members:
 | 
					   :members:
 | 
				
			||||||
   :inherited-members:
 | 
					   :inherited-members:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,63 +0,0 @@
 | 
				
			||||||
Catalog provider bundles
 | 
					 | 
				
			||||||
------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. currentmodule:: dependency_injector.catalogs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
    :width: 100%
 | 
					 | 
				
			||||||
    :align: center
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Listing of `services.py`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/bundles/services.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Listing of `views.py`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/bundles/views.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Listing of `catalogs.py`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/bundles/catalogs.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,64 +0,0 @@
 | 
				
			||||||
Declarative catalogs
 | 
					 | 
				
			||||||
--------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. currentmodule:: 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
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Example of declarative catalogs inheritance:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. image:: /images/catalogs/declarative_inheritance.png
 | 
					 | 
				
			||||||
    :width: 100%
 | 
					 | 
				
			||||||
    :align: center
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/declarative_inheritance.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,31 +0,0 @@
 | 
				
			||||||
Dynamic catalogs
 | 
					 | 
				
			||||||
----------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. currentmodule:: 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
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Next one example demonstrates creation and runtime filling of dynamic catalog:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/dynamic_runtime_creation.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,28 +0,0 @@
 | 
				
			||||||
Catalogs
 | 
					 | 
				
			||||||
========
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Catalogs are collections of providers. Main purpose of catalogs is to group
 | 
					 | 
				
			||||||
providers. 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
There are, actually, several popular cases of catalogs usage:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Grouping of providers from the same architectural layer (for example, 
 | 
					 | 
				
			||||||
  ``Services``, ``Models`` and ``Forms`` catalogs).
 | 
					 | 
				
			||||||
- Grouping of providers from the same functional groups (for example,
 | 
					 | 
				
			||||||
  catalog ``Users``, that contains all functional parts of ``Users``
 | 
					 | 
				
			||||||
  component).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    declarative
 | 
					 | 
				
			||||||
    dynamic
 | 
					 | 
				
			||||||
    bundles
 | 
					 | 
				
			||||||
    specialization
 | 
					 | 
				
			||||||
    overriding
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,52 +0,0 @@
 | 
				
			||||||
Overriding of catalogs
 | 
					 | 
				
			||||||
----------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. currentmodule:: 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 :py:class:`DeclarativeCatalog` with another 
 | 
					 | 
				
			||||||
catalog:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Use :py:meth:`DeclarativeCatalog.override` method.
 | 
					 | 
				
			||||||
- Use :py:func:`override` class decorator.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Example of overriding catalog using :py:meth:`DeclarativeCatalog.override` 
 | 
					 | 
				
			||||||
method:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/override_declarative.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Example of overriding catalog using :py:func:`override` decorator:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/override_declarative_decorator.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Also there are several useful :py:class:`DeclarativeCatalog`  methods and 
 | 
					 | 
				
			||||||
properties that help to work with catalog overridings:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- :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
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,45 +0,0 @@
 | 
				
			||||||
Specialization of catalogs
 | 
					 | 
				
			||||||
--------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. currentmodule:: dependency_injector.catalogs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
:py:class:`DeclarativeCatalog` and :py:class:`DynamicCatalog` could be 
 | 
					 | 
				
			||||||
specialized for any kind of needs via declaring its subclasses. 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
One of such `builtin` features is a limitation to 
 | 
					 | 
				
			||||||
:py:class:`DeclarativeCatalog` (and :py:class:`DynamicCatalog`) provider type. 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Next example shows usage of this feature with :py:class:`DeclarativeCatalog` 
 | 
					 | 
				
			||||||
in couple with feature of :py:class:`dependency_injector.providers.Factory` 
 | 
					 | 
				
			||||||
for limitation of its provided type:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Listing of `services.py`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/declarative_provider_type/services.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Listing of `catalog.py`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/declarative_provider_type/catalog.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Limitation to provider type could be used with :py:class:`DynamicCatalog` 
 | 
					 | 
				
			||||||
as well.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Next example does the same that previous one, but use 
 | 
					 | 
				
			||||||
:py:class:`DynamicCatalog` instead of :py:class:`DeclarativeCatalog`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Listing of `services.py`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/dynamic_provider_type/services.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Listing of `catalog.py`:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/catalogs/dynamic_provider_type/catalog.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
							
								
								
									
										55
									
								
								docs/containers/declarative.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					Declarative containers
 | 
				
			||||||
 | 
					----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. currentmodule:: dependency_injector.containers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:py:class:`DeclarativeContainer` is inversion of control container that 
 | 
				
			||||||
 | 
					could be defined in declarative manner. It should cover most of the cases 
 | 
				
			||||||
 | 
					when list of providers that would be included in container is deterministic 
 | 
				
			||||||
 | 
					(container will not change its structure in runtime).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Declarative containers have to extend base declarative container class - 
 | 
				
			||||||
 | 
					:py:class:`dependency_injector.containers.DeclarativeContainer`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Declarative container's providers have to be defined like container's class 
 | 
				
			||||||
 | 
					attributes. Every provider in container has name. This name should follow 
 | 
				
			||||||
 | 
					``some_provider`` convention, that is standard naming convention for 
 | 
				
			||||||
 | 
					attribute names in Python.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. note::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Declarative containers have several features that could be useful 
 | 
				
			||||||
 | 
					    for some kind of operations on container's providers, please visit API 
 | 
				
			||||||
 | 
					    documentation for getting full list of features - 
 | 
				
			||||||
 | 
					    :py:class:`dependency_injector.containers.DeclarativeContainer`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Here is an simple example of defining declarative container with several 
 | 
				
			||||||
 | 
					factories:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. image:: /images/containers/declarative.png
 | 
				
			||||||
 | 
					    :width: 85%
 | 
				
			||||||
 | 
					    :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/declarative.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example of declarative containers inheritance:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. image:: /images/containers/declarative_inheritance.png
 | 
				
			||||||
 | 
					    :width: 100%
 | 
				
			||||||
 | 
					    :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/declarative_inheritance.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example of declarative containers's provider injections:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. image:: /images/containers/declarative_injections.png
 | 
				
			||||||
 | 
					    :width: 100%
 | 
				
			||||||
 | 
					    :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/declarative_injections.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
							
								
								
									
										27
									
								
								docs/containers/dynamic.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					Dynamic containers
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. currentmodule:: dependency_injector.containers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:py:class:`DynamicContainer` is an inversion of control container with dynamic 
 | 
				
			||||||
 | 
					structure. It should cover most of the cases when list of providers that 
 | 
				
			||||||
 | 
					would be included in container is non-deterministic and depends on 
 | 
				
			||||||
 | 
					application's flow or its configuration (container's structure could be 
 | 
				
			||||||
 | 
					determined just after application will be started and will do some initial 
 | 
				
			||||||
 | 
					work, like parsing list of container's providers from the configuration).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					While :py:class:`DeclarativeContainer` acts on class-level, 
 | 
				
			||||||
 | 
					:py:class:`DynamicContainer` does the same on instance-level.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Here is an simple example of defining dynamic container with several factories:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/dynamic.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next example demonstrates creation of dynamic container based on some 
 | 
				
			||||||
 | 
					configuration:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/dynamic_runtime_creation.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
							
								
								
									
										28
									
								
								docs/containers/index.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					IoC Containers
 | 
				
			||||||
 | 
					==============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Containers are collections of providers. Main purpose of containers is to group
 | 
				
			||||||
 | 
					providers. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are, actually, several popular cases of containers usage:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ Keeping all providers in a single container.
 | 
				
			||||||
 | 
					+ Grouping of providers from the same architectural layer (for example, 
 | 
				
			||||||
 | 
					  ``Services``, ``Models`` and ``Forms`` containers).
 | 
				
			||||||
 | 
					+ Grouping of providers from the same functional groups (for example,
 | 
				
			||||||
 | 
					  container ``Users``, that contains all functional parts of ``Users``
 | 
				
			||||||
 | 
					  component).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Containers module API docs - :py:mod:`dependency_injector.containers`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..  toctree::
 | 
				
			||||||
 | 
					    :maxdepth: 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    declarative
 | 
				
			||||||
 | 
					    dynamic
 | 
				
			||||||
 | 
					    specialization
 | 
				
			||||||
 | 
					    overriding
 | 
				
			||||||
							
								
								
									
										40
									
								
								docs/containers/overriding.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					Overriding of containers
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. currentmodule:: dependency_injector.containers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Containers can be overridden by other containers. This, actually, means that 
 | 
				
			||||||
 | 
					all of the providers from overriding container will override providers with 
 | 
				
			||||||
 | 
					the same names in overridden container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There are two ways to override :py:class:`DeclarativeContainer` with another 
 | 
				
			||||||
 | 
					container:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Use :py:meth:`DeclarativeContainer.override` method.
 | 
				
			||||||
 | 
					- Use :py:func:`override` class decorator.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example of overriding container using :py:meth:`DeclarativeContainer.override` 
 | 
				
			||||||
 | 
					method:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/override_declarative.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example of overriding container using :py:func:`override` decorator:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/override_declarative_decorator.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also there are several useful :py:class:`DeclarativeContainer` methods and 
 | 
				
			||||||
 | 
					properties that help to work with container overridings:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- :py:attr:`DeclarativeContainer.overridden` - tuple of all overriding 
 | 
				
			||||||
 | 
					  containers.
 | 
				
			||||||
 | 
					- :py:meth:`DeclarativeContainer.reset_last_overriding()` - reset last 
 | 
				
			||||||
 | 
					  overriding provider for each container providers.
 | 
				
			||||||
 | 
					- :py:meth:`DeclarativeContainer.reset_override()` - reset all overridings 
 | 
				
			||||||
 | 
					  for each container providers. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:py:class:`DynamicContainer` has exactly the same functionality, except of 
 | 
				
			||||||
 | 
					:py:func:`override` decorator.
 | 
				
			||||||
							
								
								
									
										24
									
								
								docs/containers/specialization.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					Specialization of containers
 | 
				
			||||||
 | 
					----------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. currentmodule:: dependency_injector.containers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:py:class:`DeclarativeContainer` could be specialized for any kind of needs 
 | 
				
			||||||
 | 
					via declaring its subclasses. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					One of such `builtin` features is a limitation for providers type.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Next example shows usage of this feature with :py:class:`DeclarativeContainer` 
 | 
				
			||||||
 | 
					in couple with feature of :py:class:`dependency_injector.providers.Factory` 
 | 
				
			||||||
 | 
					for limitation of its provided type:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/declarative_provider_type.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Limitation for providers type could be used with :py:class:`DynamicContainer` 
 | 
				
			||||||
 | 
					as well:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/containers/dynamic_provider_type.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 49 KiB  | 
| 
		 Before Width: | Height: | Size: 78 KiB  | 
| 
		 Before Width: | Height: | Size: 231 KiB  | 
| 
		 Before Width: | Height: | Size: 295 KiB After Width: | Height: | Size: 295 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/containers/declarative.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 23 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/containers/declarative_inheritance.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 64 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/containers/declarative_injections.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 112 KiB  | 
| 
		 Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 8.2 KiB  | 
| 
		 Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 32 KiB  | 
| 
		 Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 41 KiB  | 
| 
		 Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 9.2 KiB  | 
| 
		 Before Width: | Height: | Size: 66 KiB  | 
| 
		 Before Width: | Height: | Size: 66 KiB  | 
| 
		 Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 22 KiB  | 
| 
		 Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 32 KiB  | 
| 
		 Before Width: | Height: | Size: 68 KiB  | 
| 
		 Before Width: | Height: | Size: 72 KiB  | 
| 
		 Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 17 KiB  | 
| 
		 Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 32 KiB  | 
| 
		 Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 10 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/images/providers/providers_class_diagram.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 111 KiB  | 
| 
		 Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 11 KiB  | 
| 
						 | 
					@ -30,9 +30,6 @@ Status
 | 
				
			||||||
| *PyPi*                                | .. image:: https://img.shields.io/pypi/v/dependency_injector.svg                       |
 | 
					| *PyPi*                                | .. image:: https://img.shields.io/pypi/v/dependency_injector.svg                       |
 | 
				
			||||||
|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
					|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
				
			||||||
|                                       |    :alt: Latest Version                                                                |
 | 
					|                                       |    :alt: Latest Version                                                                |
 | 
				
			||||||
|                                       | .. image:: https://img.shields.io/pypi/dm/dependency_injector.svg                      |
 | 
					 | 
				
			||||||
|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
					 | 
				
			||||||
|                                       |    :alt: Downloads                                                                     |
 | 
					 | 
				
			||||||
|                                       | .. image:: https://img.shields.io/pypi/l/dependency_injector.svg                       |
 | 
					|                                       | .. image:: https://img.shields.io/pypi/l/dependency_injector.svg                       |
 | 
				
			||||||
|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
					|                                       |    :target: https://pypi.python.org/pypi/dependency_injector/                          |
 | 
				
			||||||
|                                       |    :alt: License                                                                       |
 | 
					|                                       |    :alt: License                                                                       |
 | 
				
			||||||
| 
						 | 
					@ -61,7 +58,7 @@ Contents
 | 
				
			||||||
    introduction/index
 | 
					    introduction/index
 | 
				
			||||||
    main/installation
 | 
					    main/installation
 | 
				
			||||||
    providers/index
 | 
					    providers/index
 | 
				
			||||||
    catalogs/index
 | 
					    containers/index
 | 
				
			||||||
    advanced_usage/index
 | 
					    advanced_usage/index
 | 
				
			||||||
    examples/index
 | 
					    examples/index
 | 
				
			||||||
    api/index
 | 
					    api/index
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -119,9 +119,9 @@ Let's automate ``Engine`` into ``Car`` injections using *Dependency Injector*:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. note::
 | 
					.. note::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ``Components`` from previous example is an inversion of control container. 
 | 
					    ``Container`` from previous example is an inversion of control container. 
 | 
				
			||||||
    It contains a collection of component providers that could be injected 
 | 
					    It contains a collection of component providers that could be injected 
 | 
				
			||||||
    into each other. 
 | 
					    into each other. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Assuming this, ``Components`` could be one and the only place, where 
 | 
					    Assuming this, ``Container`` could be one and the only place, where 
 | 
				
			||||||
    application's structure is being managed on the high level.
 | 
					    application's structure is being managed on the high level.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ of Python objects and their dependencies in formal, pretty way.
 | 
				
			||||||
*Dependency Injector* framework could be used in different application types:
 | 
					*Dependency Injector* framework could be used in different application types:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
+ Web applications based on Flask, Django or any other web framework.
 | 
					+ Web applications based on Flask, Django or any other web framework.
 | 
				
			||||||
+ Asyncronous applications based on asyncio, Tornado and Twisted.
 | 
					+ Asynchronous applications based on asyncio, Tornado and Twisted.
 | 
				
			||||||
+ Standalone frameworks and libraries.
 | 
					+ Standalone frameworks and libraries.
 | 
				
			||||||
+ GUI applications.
 | 
					+ GUI applications.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,8 +5,8 @@ Structure of Dependency Injector
 | 
				
			||||||
   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
					   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
				
			||||||
   :description: This article describes "Dependency Injector" framework 
 | 
					   :description: This article describes "Dependency Injector" framework 
 | 
				
			||||||
                 components and their interaction between each other. 
 | 
					                 components and their interaction between each other. 
 | 
				
			||||||
                 Catalogs, providers and injections are the former 
 | 
					                 Providers and containers are the former components of 
 | 
				
			||||||
                 components of the framework.
 | 
					                 the framework.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Current section describes *Dependency Injector* main entities and their 
 | 
					Current section describes *Dependency Injector* main entities and their 
 | 
				
			||||||
interaction between each other.
 | 
					interaction between each other.
 | 
				
			||||||
| 
						 | 
					@ -15,37 +15,33 @@ interaction between each other.
 | 
				
			||||||
    :width: 100%
 | 
					    :width: 100%
 | 
				
			||||||
    :align: center
 | 
					    :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
There are 3 main entities: providers, injections and catalogs.
 | 
					There are 2 main entities: providers & containers.
 | 
				
			||||||
 | 
					 | 
				
			||||||
+ All of the entities could be used in composition with each other or 
 | 
					 | 
				
			||||||
  separatelly.
 | 
					 | 
				
			||||||
+ Each of the entities could be extended via specialization.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Providers
 | 
					Providers
 | 
				
			||||||
~~~~~~~~~
 | 
					~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Providers are strategies of accesing objects. For example, 
 | 
					Providers are strategies of accessing objects. For example, 
 | 
				
			||||||
:py:class:`dependency_injector.providers.Factory` creates new instance 
 | 
					:py:class:`dependency_injector.providers.Factory` creates new instance 
 | 
				
			||||||
of provided class every time it is called. 
 | 
					of provided class every time it is called. 
 | 
				
			||||||
:py:class:`dependency_injector.providers.Singleton` creates provided 
 | 
					:py:class:`dependency_injector.providers.Singleton` creates provided 
 | 
				
			||||||
instance once and returns it on every next call. Providers could be 
 | 
					instance once and returns it on every next call. Base class is - 
 | 
				
			||||||
injected into each other. Providers could be overridden by another 
 | 
					 | 
				
			||||||
providers. Base class is - 
 | 
					 | 
				
			||||||
:py:class:`dependency_injector.providers.Provider`.
 | 
					:py:class:`dependency_injector.providers.Provider`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Injections
 | 
					Providers could be:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ Injected into each other.
 | 
				
			||||||
 | 
					+ Overridden by each other.
 | 
				
			||||||
 | 
					+ Extended.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Containers 
 | 
				
			||||||
~~~~~~~~~~
 | 
					~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Injections are instructions for making dependency injections 
 | 
					Containers are collections of providers. They are used for grouping 
 | 
				
			||||||
(there are several ways how they could be done). Injections are used 
 | 
					 | 
				
			||||||
mostly 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 - 
 | 
					of providers by some principles. Base class is - 
 | 
				
			||||||
:py:class:`dependency_injector.catalogs.DeclarativeCatalog`.
 | 
					:py:class:`dependency_injector.containers.DeclarativeContainer`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Containers could be:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ Overridden by each other.
 | 
				
			||||||
 | 
					+ Copied from each other.
 | 
				
			||||||
 | 
					+ Extended.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,9 +6,7 @@ What is dependency injection and inversion of control?
 | 
				
			||||||
   :description: This article provides definition of dependency injection, 
 | 
					   :description: This article provides definition of dependency injection, 
 | 
				
			||||||
                 inversion of control and dependency inversion. It contains 
 | 
					                 inversion of control and dependency inversion. It contains 
 | 
				
			||||||
                 example code in Python that is refactored to be following 
 | 
					                 example code in Python that is refactored to be following 
 | 
				
			||||||
                 inversion of control principle and then enhanced by 
 | 
					                 inversion of control principle.
 | 
				
			||||||
                 inversion of control container based on "Dependency Injector" 
 | 
					 | 
				
			||||||
                 declarative catalog.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Definition
 | 
					Definition
 | 
				
			||||||
~~~~~~~~~~
 | 
					~~~~~~~~~~
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,19 @@ Development version
 | 
				
			||||||
-------------------
 | 
					-------------------
 | 
				
			||||||
- No features.
 | 
					- No features.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2.0.0
 | 
				
			||||||
 | 
					------
 | 
				
			||||||
 | 
					- Introduce new injections style for ``Callable``, ``Factory`` & 
 | 
				
			||||||
 | 
					  ``Singleton`` providers.
 | 
				
			||||||
 | 
					- Drop providers: ``Static``, ``Value``, ``Function``, ``Class``, ``Config``.
 | 
				
			||||||
 | 
					- Increase performance of making injections in 2 times (+100%).
 | 
				
			||||||
 | 
					- Drop method injections.
 | 
				
			||||||
 | 
					- Simplify providers overriding system.
 | 
				
			||||||
 | 
					- Replace ``catalogs`` package with ``containers`` module.
 | 
				
			||||||
 | 
					- Drop all backward compatibilities for 1.x.
 | 
				
			||||||
 | 
					- Refactor most of the components.
 | 
				
			||||||
 | 
					- Update documentation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1.17.0
 | 
					1.17.0
 | 
				
			||||||
------
 | 
					------
 | 
				
			||||||
- Add ``add_injections()`` method to ``Callable``, ``DelegatedCallable``, 
 | 
					- Add ``add_injections()`` method to ``Callable``, ``DelegatedCallable``, 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,13 +12,13 @@ framework can be installed from PyPi_:
 | 
				
			||||||
    pip install dependency_injector
 | 
					    pip install dependency_injector
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Installing particular version:
 | 
					    # Installing particular version:
 | 
				
			||||||
    pip install dependency_injector==0.11.0
 | 
					    pip install dependency_injector==2.0.0
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
Sources can be cloned from GitHub_:
 | 
					Sources can be cloned from GitHub_:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. code-block:: bash
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    git clone https://github.com/ets-labs/dependency_injector.git
 | 
					    git clone https://github.com/ets-labs/python-dependency-injector.git
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Also all *Dependency Injector* releases can be downloaded from 
 | 
					Also all *Dependency Injector* releases can be downloaded from 
 | 
				
			||||||
`GitHub releases page`_.
 | 
					`GitHub releases page`_.
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ Verification of currently installed version could be done using
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    >>> from dependency_injector import VERSION
 | 
					    >>> from dependency_injector import VERSION
 | 
				
			||||||
    >>> VERSION
 | 
					    >>> VERSION
 | 
				
			||||||
    '0.11.0'
 | 
					    '2.0.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. _PyPi: https://pypi.python.org/pypi/dependency_injector
 | 
					.. _PyPi: https://pypi.python.org/pypi/dependency_injector
 | 
				
			||||||
.. _GitHub: https://github.com/ets-labs/python-dependency-injector
 | 
					.. _GitHub: https://github.com/ets-labs/python-dependency-injector
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,37 +3,26 @@ Callable providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. currentmodule:: dependency_injector.providers
 | 
					.. currentmodule:: dependency_injector.providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Callable` provider is a provider that wraps particular callable with
 | 
					:py:class:`Callable` provider calls wrapped callable on every call.
 | 
				
			||||||
some injections. Every call of this provider returns result of call of initial
 | 
					 | 
				
			||||||
callable.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Callable providers and injections
 | 
					Callable providers and injections
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Callable` takes a various number of positional and keyword 
 | 
					:py:class:`Callable` provider takes a various number of positional and keyword 
 | 
				
			||||||
arguments that are used as decorated callable injections. Every time, when 
 | 
					arguments that are used as wrapped callable injections. Every time, when 
 | 
				
			||||||
:py:class:`Callable` is called, positional and keyword argument injections 
 | 
					:py:class:`Callable` provider is called, positional and keyword argument 
 | 
				
			||||||
would be passed as an callable arguments.
 | 
					injections would be passed as an callable arguments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Such behaviour is very similar to the standard Python ``functools.partial`` 
 | 
					Injections are done according to the next rules:
 | 
				
			||||||
object with several more things: 
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
+ All providers (instances of :py:class:`Provider`) are called every time 
 | 
					+ All providers (instances of :py:class:`Provider`) are called every time 
 | 
				
			||||||
  when injection needs to be done.
 | 
					  when injection needs to be done.
 | 
				
			||||||
+ Providers could be injected "as is" (delegated), if it is defined obviously.
 | 
					+ Providers could be injected "as is" (delegated), if it is defined obviously.
 | 
				
			||||||
  Check out `Callable providers delegation`_.
 | 
					  Check out :ref:`callable_providers_delegation`.
 | 
				
			||||||
+ All other injectable values are provided *"as is"*
 | 
					+ All other injectable values are provided *"as is"*.
 | 
				
			||||||
  
 | 
					+ Positional context arguments will be appended after :py:class:`Callable` 
 | 
				
			||||||
For example, 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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: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 :py:class:`Callable` 
 | 
					 | 
				
			||||||
  positional injections.
 | 
					  positional injections.
 | 
				
			||||||
- Keyword context arguments have priority on :py:class:`Callable` keyword 
 | 
					+ Keyword context arguments have priority on :py:class:`Callable` keyword 
 | 
				
			||||||
  injections and will be merged over them.
 | 
					  injections and will be merged over them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example that shows usage of :py:class:`Callable` with positional argument 
 | 
					Example that shows usage of :py:class:`Callable` with positional argument 
 | 
				
			||||||
| 
						 | 
					@ -54,31 +43,16 @@ injections:
 | 
				
			||||||
   :language: python
 | 
					   :language: python
 | 
				
			||||||
   :linenos:
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. _callable_delegation:
 | 
					.. _callable_providers_delegation:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Callable providers delegation
 | 
					Callable providers delegation
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Callable` provider could be delegated to any other provider via any 
 | 
					:py:class:`Callable` provider could be delegated to any other provider via 
 | 
				
			||||||
kind of injection. Delegation of :py:class:`Callable` providers is the same as 
 | 
					any kind of injection. 
 | 
				
			||||||
:py:class:`Factory` and :py:class:`Singleton` providers delegation, please 
 | 
					 | 
				
			||||||
follow *Factory providers delegation* section for example.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Callable` delegate could be created obviously using 
 | 
					Delegation of :py:class:`Callable` providers is the same as 
 | 
				
			||||||
``Delegate(Callable(...))`` or by calling ``Callable(...).delegate()`` method.
 | 
					:py:class:`Factory` providers delegation, please follow 
 | 
				
			||||||
 | 
					:ref:`factory_providers_delegation` section for examples (with exception 
 | 
				
			||||||
Example:
 | 
					about using :py:class:`DelegatedCallable` instead of 
 | 
				
			||||||
 | 
					:py:class:`DelegatedFactory`).
 | 
				
			||||||
.. literalinclude:: ../../examples/providers/callable_delegation.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Alternative way of doing :py:class:`Callable` delegation is an usage of 
 | 
					 | 
				
			||||||
:py:class:`DelegatedCallable`. :py:class:`DelegatedCallable` is a 
 | 
					 | 
				
			||||||
:py:class:`Callable` that is always injected "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/delegated_callable.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,11 +28,11 @@ Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. note::
 | 
					.. note::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Class ``UserService`` is a part of some library. ``UserService`` has
 | 
					    Class ``UsersService`` is a part of some library. ``UsersService`` has
 | 
				
			||||||
    dependency on database connection, which can be satisfied with any
 | 
					    dependency on database connection, which can be satisfied with any
 | 
				
			||||||
    DBAPI 2.0 database connection. Being a self-sufficient library,
 | 
					    DBAPI 2.0 database connection. Being a self-sufficient library,
 | 
				
			||||||
    ``UserService`` doesn't hardcode any kind of database management logic.
 | 
					    ``UsersService`` doesn't hardcode any kind of database management logic.
 | 
				
			||||||
    Instead of this, ``UserService`` has external dependency, that has to
 | 
					    Instead of this, ``UsersService`` has external dependency, that has to
 | 
				
			||||||
    be satisfied by cleint's code, out of library's scope.
 | 
					    be satisfied by cleint's code, out of library's scope.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. image:: /images/providers/external_dependency.png
 | 
					.. image:: /images/providers/external_dependency.png
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,154 +24,58 @@ that are used as ``__init__()`` injections. Every time, when
 | 
				
			||||||
:py:class:`Factory` creates new one instance, positional and keyword 
 | 
					:py:class:`Factory` creates new one instance, positional and keyword 
 | 
				
			||||||
argument injections would be passed as an instance's arguments.
 | 
					argument injections would be passed as an instance's arguments.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Such behaviour is very similar to the standard Python ``functools.partial`` 
 | 
					Injections are done according to the next rules:
 | 
				
			||||||
object with several more things: 
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
+ All providers (instances of :py:class:`Provider`) are called every time 
 | 
					+ All providers (instances of :py:class:`Provider`) are called every time 
 | 
				
			||||||
  when injection needs to be done.
 | 
					  when injection needs to be done.
 | 
				
			||||||
+ Providers could be injected "as is" (delegated), if it is defined obviously.
 | 
					+ Providers could be injected "as is" (delegated), if it is defined obviously.
 | 
				
			||||||
  Check out `Factory providers delegation`_.
 | 
					  Check out :ref:`factory_providers_delegation`.
 | 
				
			||||||
+ All other injectable values are provided *"as is"*
 | 
					+ All other injectable values are provided *"as is"*.
 | 
				
			||||||
  
 | 
					+ Positional context arguments will be appended after :py:class:`Factory` 
 | 
				
			||||||
 | 
					  positional injections.
 | 
				
			||||||
 | 
					+ Keyword context arguments have priority on :py:class:`Factory` keyword 
 | 
				
			||||||
 | 
					  injections and will be merged over them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For example, if injectable value of injection is a :py:class:`Factory`, it 
 | 
					For example, 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 
 | 
					will provide new one instance (as a result of its call) every time, when 
 | 
				
			||||||
injection needs to be done.
 | 
					injection needs to be done.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example below is a little bit more complicated. It shows how to create 
 | 
					Example below is a little bit more complicated. It shows how to create 
 | 
				
			||||||
:py:class:`Factory` of particular class with ``__init__()`` argument 
 | 
					:py:class:`Factory` of particular class with ``__init__()`` injections which 
 | 
				
			||||||
injections which injectable values are also provided by another factories:
 | 
					injectable values are also provided by another factories:
 | 
				
			||||||
 | 
					 | 
				
			||||||
.. note:: 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Current positional and keyword argument injections syntax (in the examples
 | 
					 | 
				
			||||||
    below) is a **simplified one** version of full syntax. Examples of full 
 | 
					 | 
				
			||||||
    syntax and other types of injections could be found in sections below.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    While positional / keyword argument injections may be the best way of 
 | 
					 | 
				
			||||||
    passing injections, current simplified syntax might be the preferable one 
 | 
					 | 
				
			||||||
    and could be widely used.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. image:: /images/providers/factory_init_injections.png
 | 
					.. image:: /images/providers/factory_init_injections.png
 | 
				
			||||||
    :width: 90%
 | 
					 | 
				
			||||||
    :align: center
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example of usage positional argument injections:
 | 
					.. literalinclude:: ../../examples/providers/factory_init_injections.py
 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/factory_init_args.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					   :language: python
 | 
				
			||||||
   :linenos:
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example of usage keyword argument injections:
 | 
					.. _factory_providers_delegation:
 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/factory_init_kwargs.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Factory providers and __init__ injections priority
 | 
					 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 :py:class:`Factory` 
 | 
					 | 
				
			||||||
  positional injections.
 | 
					 | 
				
			||||||
- Keyword context arguments have priority on :py:class:`Factory` keyword 
 | 
					 | 
				
			||||||
  injections and will be merged over them.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
So, please, follow the example below:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. image:: /images/providers/factory_init_injections_and_contexts.png
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/factory_init_injections_and_contexts.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Factory providers and other types of injections
 | 
					 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
: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 
 | 
					 | 
				
			||||||
: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:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
+ :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 :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 :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.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. image:: /images/providers/factory_attribute_injections.png
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/factory_attribute_injections.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Factory providers and method injections
 | 
					 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
some cases.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. image:: /images/providers/factory_method_injections.png
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/factory_method_injections.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Factory providers delegation
 | 
					Factory providers delegation
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Factory` provider could be delegated to any other provider via any 
 | 
					: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 
 | 
					kind of injection. 
 | 
				
			||||||
injectable value, it will be called every time when injection is done. 
 | 
					
 | 
				
			||||||
 | 
					As it was mentioned earlier, if :py:class:`Factory` is 
 | 
				
			||||||
 | 
					injectable value, it will be called every time when injection needs to be 
 | 
				
			||||||
 | 
					done. But sometimes there is a need to inject :py:class:`Factory` provider 
 | 
				
			||||||
 | 
					itself (not a result of its call) as a dependency. Such injections are called 
 | 
				
			||||||
 | 
					- *delegated provider injections*.
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					Saying in other words, delegation of factories - is a way to inject factories 
 | 
				
			||||||
 | 
					themselves, instead of results of their calls. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Factory` delegation is performed by wrapping delegated 
 | 
					:py:class:`Factory` delegation is performed by wrapping delegated 
 | 
				
			||||||
:py:class:`Factory` into special provider type - :py:class:`Delegate`, that 
 | 
					:py:class:`Factory` into special provider type - :py:class:`Delegate`, that 
 | 
				
			||||||
just returns wrapped :py:class:`Factory`. Saying in other words, delegation 
 | 
					just returns wrapped :py:class:`Factory`. 
 | 
				
			||||||
of factories - is a way to inject factories themselves, instead of results 
 | 
					 | 
				
			||||||
of their calls. 
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Actually, there are two ways of creating factory delegates:
 | 
					Actually, there are three ways for creating factory delegates:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					+ ``DelegatedFactory(...)`` - use special type of factory - 
 | 
				
			||||||
 | 
					  :py:class:`DelegatedFactory`. Such factories are always injected as 
 | 
				
			||||||
 | 
					  delegates ("as is"). 
 | 
				
			||||||
+ ``Delegate(Factory(...))`` - obviously wrapping factory into 
 | 
					+ ``Delegate(Factory(...))`` - obviously wrapping factory into 
 | 
				
			||||||
  :py:class:`Delegate` provider.
 | 
					  :py:class:`Delegate` provider.
 | 
				
			||||||
+ ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate` 
 | 
					+ ``Factory(...).delegate()`` - calling factory :py:meth:`Factory.delegate` 
 | 
				
			||||||
| 
						 | 
					@ -187,24 +91,16 @@ Example:
 | 
				
			||||||
   :language: python
 | 
					   :language: python
 | 
				
			||||||
   :linenos:
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Alternative way of doing :py:class:`Factory` delegation is an usage of 
 | 
					.. _factory_providers_specialization:
 | 
				
			||||||
:py:class:`DelegatedFactory`. :py:class:`DelegatedFactory` is a 
 | 
					 | 
				
			||||||
:py:class:`Factory` that is always injected "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/delegated_factory.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Factory providers specialization
 | 
					Factory providers specialization
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Factory` provider could be specialized for any kind of needs via 
 | 
					:py:class:`Factory` provider could be specialized for any kind of needs via 
 | 
				
			||||||
declaring its subclasses. 
 | 
					creating its subclasses. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
One of such `builtin` features is a limitation to :py:class:`Factory` provided 
 | 
					One of such specialization features is a limitation to :py:class:`Factory` 
 | 
				
			||||||
type:
 | 
					provided type:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. literalinclude:: ../../examples/providers/factory_provided_type.py
 | 
					.. literalinclude:: ../../examples/providers/factory_provided_type.py
 | 
				
			||||||
   :language: python
 | 
					   :language: python
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,9 @@
 | 
				
			||||||
Providers
 | 
					Providers
 | 
				
			||||||
=========
 | 
					=========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Providers are strategies of accessing objects. They describe how particular 
 | 
					Providers are strategies of accessing objects. They define how particular 
 | 
				
			||||||
objects are provided.
 | 
					objects are provided.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Base providers class is - :py:class:`dependency_injector.providers.Provider`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Every provider is callable (implements ``__call__()``). Every call to provider 
 | 
					Every provider is callable (implements ``__call__()``). Every call to provider 
 | 
				
			||||||
instance returns provided result, according to the providing strategy of 
 | 
					instance returns provided result, according to the providing strategy of 
 | 
				
			||||||
particular provider. 
 | 
					particular provider. 
 | 
				
			||||||
| 
						 | 
					@ -17,7 +15,13 @@ of custom providers.
 | 
				
			||||||
All providers are validated in multithreading environment and considered to 
 | 
					All providers are validated in multithreading environment and considered to 
 | 
				
			||||||
be thread safe.
 | 
					be thread safe.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Providers module API docs - :py:mod:`dependency_injector.providers`
 | 
					+ Base providers class is: :py:class:`dependency_injector.providers.Provider`
 | 
				
			||||||
 | 
					+ Providers module API docs: :py:mod:`dependency_injector.providers`
 | 
				
			||||||
 | 
					+ Providers class diagram:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. image:: /images/providers/providers_class_diagram.png
 | 
				
			||||||
 | 
					    :width: 100%
 | 
				
			||||||
 | 
					    :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
..  toctree::
 | 
					..  toctree::
 | 
				
			||||||
    :maxdepth: 2
 | 
					    :maxdepth: 2
 | 
				
			||||||
| 
						 | 
					@ -25,7 +29,7 @@ Providers module API docs - :py:mod:`dependency_injector.providers`
 | 
				
			||||||
    factory
 | 
					    factory
 | 
				
			||||||
    singleton
 | 
					    singleton
 | 
				
			||||||
    callable
 | 
					    callable
 | 
				
			||||||
 | 
					    object
 | 
				
			||||||
    external_dependency
 | 
					    external_dependency
 | 
				
			||||||
    static
 | 
					 | 
				
			||||||
    overriding
 | 
					    overriding
 | 
				
			||||||
    custom
 | 
					    custom
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								docs/providers/object.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					Object providers
 | 
				
			||||||
 | 
					----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. currentmodule:: dependency_injector.providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:py:class:`Object` provider returns provided instance "as is"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/providers/object.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@ Overriding of providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Every provider could be overridden by another provider.
 | 
					Every provider could be overridden by another provider.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This gives opportunity to make system behaviour more flexible in some points.
 | 
					This gives opportunity to make system behaviour more flexible at some point.
 | 
				
			||||||
The main feature is that while your code is using providers, it depends on 
 | 
					The main feature is that while your code is using providers, it depends on 
 | 
				
			||||||
providers, but not on the objects that providers provide. As a result of this, 
 | 
					providers, but not on the objects that providers provide. As a result of this, 
 | 
				
			||||||
you can change providing by provider object to a different one, but still
 | 
					you can change providing by provider object to a different one, but still
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ compatible one, without chaning your previously written code.
 | 
				
			||||||
Provider overriding functionality has such interface:
 | 
					Provider overriding functionality has such interface:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. image:: /images/providers/provider_override.png
 | 
					.. image:: /images/providers/provider_override.png
 | 
				
			||||||
    :width: 45%
 | 
					    :width: 55%
 | 
				
			||||||
    :align: center
 | 
					    :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
+ :py:meth:`Provider.override()` - takes another provider that will be used 
 | 
					+ :py:meth:`Provider.override()` - takes another provider that will be used 
 | 
				
			||||||
| 
						 | 
					@ -22,17 +22,8 @@ Provider overriding functionality has such interface:
 | 
				
			||||||
  In such case, last passed provider would be used as overriding one.
 | 
					  In such case, last passed provider would be used as overriding one.
 | 
				
			||||||
+ :py:meth:`Provider.reset_override()` - resets all overriding providers. 
 | 
					+ :py:meth:`Provider.reset_override()` - resets all overriding providers. 
 | 
				
			||||||
  Provider starts to behave itself like usual.
 | 
					  Provider starts to behave itself like usual.
 | 
				
			||||||
+ :py:attr:`Provider.is_overridden` - bool, ``True`` if provider is overridden.
 | 
					+ :py:meth:`Provider.reset_last_overriding()` - remove last overriding 
 | 
				
			||||||
 | 
					  provider from stack of overriding providers.
 | 
				
			||||||
.. note::
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Actually, initial provider forms stack from overriding providers. There is 
 | 
					 | 
				
			||||||
   some, not so common, but still usefull, functionality that could be used:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   + :py:attr:`Provider.last_overriding` - always keeps reference to last 
 | 
					 | 
				
			||||||
     overriding provider.
 | 
					 | 
				
			||||||
   + :py:meth:`Provider.reset_last_overriding()` - remove last overriding 
 | 
					 | 
				
			||||||
     provider from stack of overriding providers.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example:
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,20 @@ Example:
 | 
				
			||||||
   :language: python
 | 
					   :language: python
 | 
				
			||||||
   :linenos:
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Singleton providers resetting
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 and dependes on garbage collection strategy.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/providers/singleton_reseting.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Singleton providers and injections
 | 
					Singleton providers and injections
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,47 +56,17 @@ provider.
 | 
				
			||||||
    . It makes possible to inject providers *as is*. Please check out 
 | 
					    . It makes possible to inject providers *as is*. Please check out 
 | 
				
			||||||
    `Singleton providers delegation`_ section.
 | 
					    `Singleton providers delegation`_ section.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Singleton providers resetting
 | 
					 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/singleton_reseting.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Singleton providers delegation
 | 
					Singleton providers delegation
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Singleton` provider could be delegated to any other provider via 
 | 
					:py:class:`Singleton` provider could be delegated to any other provider via 
 | 
				
			||||||
any kind of injection. Delegation of :py:class:`Singleton` providers is the 
 | 
					any kind of injection. 
 | 
				
			||||||
same as :py:class:`Factory` providers delegation, please follow *Factory 
 | 
					 | 
				
			||||||
providers delegation* section for example.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
:py:class:`Singleton` delegate could be created obviously using 
 | 
					Delegation of :py:class:`Singleton` providers is the same as 
 | 
				
			||||||
``Delegate(Singleton(...))`` or by calling ``Singleton(...).delegate()`` 
 | 
					:py:class:`Factory` providers delegation, please follow 
 | 
				
			||||||
method.
 | 
					:ref:`factory_providers_delegation` section for examples (with exception 
 | 
				
			||||||
 | 
					about using :py:class:`DelegatedSingleton` instead of 
 | 
				
			||||||
Example:
 | 
					:py:class:`DelegatedFactory`).
 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/singleton_delegation.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Alternative way of doing :py:class:`Singleton` delegation is an usage of 
 | 
					 | 
				
			||||||
:py:class:`DelegatedSingleton`. :py:class:`DelegatedSingleton` is a 
 | 
					 | 
				
			||||||
:py:class:`Singleton` that is always injected "as is".
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/delegated_singleton.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Singleton providers specialization
 | 
					Singleton providers specialization
 | 
				
			||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
| 
						 | 
					@ -90,9 +74,6 @@ Singleton providers specialization
 | 
				
			||||||
:py:class:`Singleton` provider could be specialized for any kind of needs via 
 | 
					:py:class:`Singleton` provider could be specialized for any kind of needs via 
 | 
				
			||||||
declaring its subclasses. 
 | 
					declaring its subclasses. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
One of such `builtin` features is a limitation to :py:class:`Singleton` 
 | 
					Specialization of :py:class:`Singleton` providers is the same as 
 | 
				
			||||||
provided type:
 | 
					:py:class:`Factory` providers specialization, please follow 
 | 
				
			||||||
 | 
					:ref:`factory_providers_specialization` section for examples.
 | 
				
			||||||
.. literalinclude:: ../../examples/providers/singleton_provided_type.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,22 +0,0 @@
 | 
				
			||||||
Static providers
 | 
					 | 
				
			||||||
----------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. currentmodule:: dependency_injector.providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Static providers are family of providers that return their values "as is".
 | 
					 | 
				
			||||||
There are four types of static providers:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    - :py:class:`Class`
 | 
					 | 
				
			||||||
    - :py:class:`Object`
 | 
					 | 
				
			||||||
    - :py:class:`Function`
 | 
					 | 
				
			||||||
    - :py:class:`Value`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. literalinclude:: ../../examples/providers/static.py
 | 
					 | 
				
			||||||
   :language: python
 | 
					 | 
				
			||||||
   :linenos:
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,63 +0,0 @@
 | 
				
			||||||
"""Config provider examples."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import catalogs
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ObjectA(object):
 | 
					 | 
				
			||||||
    """Example class ObjectA, that has dependencies on some setting values."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, fee, price, timezone):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.fee = fee
 | 
					 | 
				
			||||||
        self.price = price
 | 
					 | 
				
			||||||
        self.timezone = timezone
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Catalog(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
    """Catalog of providers."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    config = providers.Config()
 | 
					 | 
				
			||||||
    """:type: providers.Config"""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object_a = providers.Factory(ObjectA,
 | 
					 | 
				
			||||||
                                 fee=config.FEE,
 | 
					 | 
				
			||||||
                                 price=config.PRICE,
 | 
					 | 
				
			||||||
                                 timezone=config.GLOBAL.TIMEZONE)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Setting config value and making some tests.
 | 
					 | 
				
			||||||
Catalog.config.update_from({
 | 
					 | 
				
			||||||
    'FEE': 1.25,
 | 
					 | 
				
			||||||
    'PRICE': 2.99,
 | 
					 | 
				
			||||||
    'GLOBAL': {
 | 
					 | 
				
			||||||
        'TIMEZONE': 'US/Eastern'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object_a1 = Catalog.object_a()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
assert object_a1.fee == 1.25
 | 
					 | 
				
			||||||
assert object_a1.price == 2.99
 | 
					 | 
				
			||||||
assert object_a1.timezone == 'US/Eastern'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Changing config value one more time and making some tests.
 | 
					 | 
				
			||||||
Catalog.config.update_from({
 | 
					 | 
				
			||||||
    'FEE': 5.25,
 | 
					 | 
				
			||||||
    'PRICE': 19.99,
 | 
					 | 
				
			||||||
    'GLOBAL': {
 | 
					 | 
				
			||||||
        'TIMEZONE': 'US/Western'
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object_a2 = Catalog.object_a()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# New one ObjectA has new config values.
 | 
					 | 
				
			||||||
assert object_a2.fee == 5.25
 | 
					 | 
				
			||||||
assert object_a2.price == 19.99
 | 
					 | 
				
			||||||
assert object_a2.timezone == 'US/Western'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# And old one has old ones.
 | 
					 | 
				
			||||||
assert object_a1.fee == 1.25
 | 
					 | 
				
			||||||
assert object_a1.price == 2.99
 | 
					 | 
				
			||||||
assert object_a1.timezone == 'US/Eastern'
 | 
					 | 
				
			||||||
| 
						 | 
					@ -3,8 +3,8 @@
 | 
				
			||||||
import sqlite3
 | 
					import sqlite3
 | 
				
			||||||
import flask
 | 
					import flask
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector import providers
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
from dependency_injector import injections
 | 
					import dependency_injector.injections as injections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
database = providers.Singleton(sqlite3.connect,
 | 
					database = providers.Singleton(sqlite3.connect,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,8 +4,8 @@ import sqlite3
 | 
				
			||||||
import flask
 | 
					import flask
 | 
				
			||||||
import flask.views
 | 
					import flask.views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector import providers
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
from dependency_injector import injections
 | 
					import dependency_injector.injections as injections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
database = providers.Singleton(sqlite3.Connection,
 | 
					database = providers.Singleton(sqlite3.Connection,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,13 +1,13 @@
 | 
				
			||||||
"""`inject()` decorator simple example."""
 | 
					"""`inject()` decorator simple example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector import providers
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
from dependency_injector import injections
 | 
					import dependency_injector.injections as injections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dependency_injector_factory = providers.Factory(object)
 | 
					dependency_injector_factory = providers.Factory(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Example of using `di.inject()` decorator keyword argument injections:
 | 
					# Example of using `inject()` decorator keyword argument injections:
 | 
				
			||||||
@injections.inject(new_object=dependency_injector_factory)
 | 
					@injections.inject(new_object=dependency_injector_factory)
 | 
				
			||||||
@injections.inject(some_setting=1334)
 | 
					@injections.inject(some_setting=1334)
 | 
				
			||||||
def example_callback1(new_object, some_setting):
 | 
					def example_callback1(new_object, some_setting):
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ def example_callback1(new_object, some_setting):
 | 
				
			||||||
    assert some_setting == 1334
 | 
					    assert some_setting == 1334
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Example of using `di.inject()` decorator with positional argument injections:
 | 
					# Example of using `inject()` decorator with positional argument injections:
 | 
				
			||||||
@injections.inject(dependency_injector_factory, 1334)
 | 
					@injections.inject(dependency_injector_factory, 1334)
 | 
				
			||||||
def example_callback2(new_object, some_setting):
 | 
					def example_callback2(new_object, some_setting):
 | 
				
			||||||
    """Example callback that does some asserts for input args."""
 | 
					    """Example callback that does some asserts for input args."""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,59 +0,0 @@
 | 
				
			||||||
"""Catalog bundles example."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import catalogs
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
from dependency_injector import errors
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import services
 | 
					 | 
				
			||||||
import views
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Declaring services catalog:
 | 
					 | 
				
			||||||
class Services(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
    """Example catalog of service providers."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    users = providers.Factory(services.Users)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auth = providers.Factory(services.Auth)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photos = providers.Factory(services.Photos)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Declaring views catalog:
 | 
					 | 
				
			||||||
class Views(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
    """Example catalog of web views."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auth = providers.Factory(views.Auth,
 | 
					 | 
				
			||||||
                             services=Services.Bundle(Services.users,
 | 
					 | 
				
			||||||
                                                      Services.auth))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    photos = providers.Factory(views.Photos,
 | 
					 | 
				
			||||||
                               services=Services.Bundle(Services.users,
 | 
					 | 
				
			||||||
                                                        Services.photos))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Creating example views:
 | 
					 | 
				
			||||||
auth_view = Views.auth()
 | 
					 | 
				
			||||||
photos_view = Views.photos()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
print auth_view.services    # prints: <__main__.Services.Bundle(users, auth)>
 | 
					 | 
				
			||||||
print photos_view.services  # prints <__main__.Services.Bundle(photos, users)>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Making some asserts:
 | 
					 | 
				
			||||||
assert auth_view.services.users is Services.users
 | 
					 | 
				
			||||||
assert auth_view.services.auth is Services.auth
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    auth_view.services.photos
 | 
					 | 
				
			||||||
except errors.Error:
 | 
					 | 
				
			||||||
    # `photos` service provider is not in scope of `auth_view` services bundle,
 | 
					 | 
				
			||||||
    # so `di.Error` will be raised.
 | 
					 | 
				
			||||||
    pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
assert photos_view.services.users is Services.users
 | 
					 | 
				
			||||||
assert photos_view.services.photos is Services.photos
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    photos_view.services.auth
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,17 +0,0 @@
 | 
				
			||||||
"""Example services."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BaseService(object):
 | 
					 | 
				
			||||||
    """Example base class of service."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Users(BaseService):
 | 
					 | 
				
			||||||
    """Example users service."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Auth(BaseService):
 | 
					 | 
				
			||||||
    """Example auth service."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Photos(BaseService):
 | 
					 | 
				
			||||||
    """Example photo service."""
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,21 +0,0 @@
 | 
				
			||||||
"""Example web views."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class BaseWebView(object):
 | 
					 | 
				
			||||||
    """Example base class of web view."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, services):
 | 
					 | 
				
			||||||
        """Initializer.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :param services: Bundle of service providers
 | 
					 | 
				
			||||||
        :type services: catalogs.Services
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.services = services
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Auth(BaseWebView):
 | 
					 | 
				
			||||||
    """Example auth web view."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Photos(BaseWebView):
 | 
					 | 
				
			||||||
    """Example photo processing web view."""
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,22 +0,0 @@
 | 
				
			||||||
"""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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,30 +0,0 @@
 | 
				
			||||||
"""Declarative catalogs inheritance example."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import catalogs
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CatalogA(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
    """Example catalog A."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provider1 = providers.Factory(object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CatalogB(CatalogA):
 | 
					 | 
				
			||||||
    """Example catalog B."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provider2 = providers.Singleton(object)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Making some asserts for `providers` attribute:
 | 
					 | 
				
			||||||
assert CatalogA.providers == dict(provider1=CatalogA.provider1)
 | 
					 | 
				
			||||||
assert CatalogB.providers == dict(provider1=CatalogA.provider1,
 | 
					 | 
				
			||||||
                                  provider2=CatalogB.provider2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Making some asserts for `cls_providers` attribute:
 | 
					 | 
				
			||||||
assert CatalogA.cls_providers == dict(provider1=CatalogA.provider1)
 | 
					 | 
				
			||||||
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)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,47 +0,0 @@
 | 
				
			||||||
"""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:')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    users = providers.Factory(UsersService,
 | 
					 | 
				
			||||||
                              db=database)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auth = providers.Factory(AuthService,
 | 
					 | 
				
			||||||
                             db=database,
 | 
					 | 
				
			||||||
                             users_service=users)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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()
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,73 +0,0 @@
 | 
				
			||||||
"""Specialized declarative catalog example."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import services
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
from dependency_injector import errors
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UsersService(services.Base):
 | 
					 | 
				
			||||||
    """Users service."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, config):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.config = config
 | 
					 | 
				
			||||||
        super(UsersService, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AuthService(services.Base):
 | 
					 | 
				
			||||||
    """Auth service."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, config, users_service):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.config = config
 | 
					 | 
				
			||||||
        self.users_service = users_service
 | 
					 | 
				
			||||||
        super(AuthService, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Services(services.Catalog):
 | 
					 | 
				
			||||||
    """Services catalog."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    users = services.Provider(UsersService,
 | 
					 | 
				
			||||||
                              config={'option1': '111',
 | 
					 | 
				
			||||||
                                      'option2': '222'})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auth = services.Provider(AuthService,
 | 
					 | 
				
			||||||
                             config={'option3': '333',
 | 
					 | 
				
			||||||
                                     'option4': '444'},
 | 
					 | 
				
			||||||
                             users_service=users)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Creating users & auth services:
 | 
					 | 
				
			||||||
users_service = Services.users()
 | 
					 | 
				
			||||||
auth_service = Services.auth()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Making some asserts:
 | 
					 | 
				
			||||||
assert users_service.config == {'option1': '111',
 | 
					 | 
				
			||||||
                                'option2': '222'}
 | 
					 | 
				
			||||||
assert auth_service.config == {'option3': '333',
 | 
					 | 
				
			||||||
                               'option4': '444'}
 | 
					 | 
				
			||||||
assert isinstance(auth_service.users_service, UsersService)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Trying to declare services catalog with other provider type:
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    class Services1(services.Catalog):
 | 
					 | 
				
			||||||
        """Services catalog."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        users = providers.Factory(UsersService)
 | 
					 | 
				
			||||||
except errors.Error as exception:
 | 
					 | 
				
			||||||
    print exception
 | 
					 | 
				
			||||||
    # <__main__.Services1()> can contain only <class 'services.Provider'>
 | 
					 | 
				
			||||||
    # instances
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Trying to declare services catalog with correct provider by invalid provided
 | 
					 | 
				
			||||||
# type:
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    class Services2(services.Catalog):
 | 
					 | 
				
			||||||
        """Services catalog."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        users = services.Provider(object)
 | 
					 | 
				
			||||||
except errors.Error as exception:
 | 
					 | 
				
			||||||
    print exception
 | 
					 | 
				
			||||||
    # <class 'services.Provider'> can provide only <class 'services.Base'>
 | 
					 | 
				
			||||||
    # instances
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,26 +0,0 @@
 | 
				
			||||||
"""Base classes for services."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import catalogs
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Base(object):
 | 
					 | 
				
			||||||
    """Base service class."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Provider(providers.Factory):
 | 
					 | 
				
			||||||
    """Service provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Can provide :py:class:`Base` only.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provided_type = Base
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Catalog(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
    """Base catalog of services.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Can include :py:class:`Provider`'s only.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provider_type = Provider
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,18 +0,0 @@
 | 
				
			||||||
"""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)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,63 +0,0 @@
 | 
				
			||||||
"""Specialized dynamic catalog example."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import services
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
from dependency_injector import errors
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UsersService(services.Base):
 | 
					 | 
				
			||||||
    """Users service."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, config):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.config = config
 | 
					 | 
				
			||||||
        super(UsersService, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AuthService(services.Base):
 | 
					 | 
				
			||||||
    """Auth service."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, config, users_service):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.config = config
 | 
					 | 
				
			||||||
        self.users_service = users_service
 | 
					 | 
				
			||||||
        super(AuthService, self).__init__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
services_catalog = services.Catalog()
 | 
					 | 
				
			||||||
services_catalog.users = services.Provider(UsersService,
 | 
					 | 
				
			||||||
                                           config={'option1': '111',
 | 
					 | 
				
			||||||
                                                   'option2': '222'})
 | 
					 | 
				
			||||||
services_catalog.auth = services.Provider(AuthService,
 | 
					 | 
				
			||||||
                                          config={'option3': '333',
 | 
					 | 
				
			||||||
                                                  'option4': '444'},
 | 
					 | 
				
			||||||
                                          users_service=services_catalog.users)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Creating users & auth services:
 | 
					 | 
				
			||||||
users_service = services_catalog.users()
 | 
					 | 
				
			||||||
auth_service = services_catalog.auth()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Making some asserts:
 | 
					 | 
				
			||||||
assert users_service.config == {'option1': '111',
 | 
					 | 
				
			||||||
                                'option2': '222'}
 | 
					 | 
				
			||||||
assert auth_service.config == {'option3': '333',
 | 
					 | 
				
			||||||
                               'option4': '444'}
 | 
					 | 
				
			||||||
assert isinstance(auth_service.users_service, UsersService)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Trying to declare services catalog with other provider type:
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    services_catalog.users = providers.Factory(UsersService)
 | 
					 | 
				
			||||||
except errors.Error as exception:
 | 
					 | 
				
			||||||
    print exception
 | 
					 | 
				
			||||||
    # <services.Catalog(users, auth)> can contain only
 | 
					 | 
				
			||||||
    # <class 'services.Provider'> instances
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Trying to declare services catalog with correct provider by invalid provided
 | 
					 | 
				
			||||||
# type:
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    services_catalog.users = services.Provider(object)
 | 
					 | 
				
			||||||
except errors.Error as exception:
 | 
					 | 
				
			||||||
    print exception
 | 
					 | 
				
			||||||
    # <class 'services.Provider'> can provide only <class 'services.Base'>
 | 
					 | 
				
			||||||
    # instances
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,26 +0,0 @@
 | 
				
			||||||
"""Base classes for services."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import catalogs
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Base(object):
 | 
					 | 
				
			||||||
    """Base service class."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Provider(providers.Factory):
 | 
					 | 
				
			||||||
    """Service provider.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Can provide :py:class:`Base` only.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provided_type = Base
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Catalog(catalogs.DynamicCatalog):
 | 
					 | 
				
			||||||
    """Base catalog of services.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Can include :py:class:`Provider`'s only.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    provider_type = Provider
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,45 +0,0 @@
 | 
				
			||||||
"""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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object2_factory = providers.Factory(Object2,
 | 
					 | 
				
			||||||
                                        object1=object1_factory)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AnotherCatalog(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
    """Overriding catalog."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object2_factory = providers.Factory(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)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,41 +0,0 @@
 | 
				
			||||||
"""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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object2_factory = providers.Factory(Object2,
 | 
					 | 
				
			||||||
                                        object1=object1_factory)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# 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)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,43 +0,0 @@
 | 
				
			||||||
"""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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object2_factory = providers.Factory(Object2,
 | 
					 | 
				
			||||||
                                        object1=object1_factory)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Overriding `Catalog` with `AnotherCatalog`:
 | 
					 | 
				
			||||||
@catalogs.override(Catalog)
 | 
					 | 
				
			||||||
class AnotherCatalog(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
    """Overriding catalog."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    object2_factory = providers.Factory(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)
 | 
					 | 
				
			||||||
							
								
								
									
										22
									
								
								examples/containers/declarative.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					"""Declarative IoC container simple example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Defining declarative IoC container:
 | 
				
			||||||
 | 
					class Container(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					    """Example IoC container."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    factory1 = providers.Factory(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    factory2 = providers.Factory(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Creating some objects:
 | 
				
			||||||
 | 
					object1 = Container.factory1()
 | 
				
			||||||
 | 
					object2 = Container.factory2()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Making some asserts:
 | 
				
			||||||
 | 
					assert object1 is not object2
 | 
				
			||||||
 | 
					assert isinstance(object1, object)
 | 
				
			||||||
 | 
					assert isinstance(object2, object)
 | 
				
			||||||
							
								
								
									
										30
									
								
								examples/containers/declarative_inheritance.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					"""Declarative IoC containers inheritance example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ContainerA(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					    """Example IoC container A."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    provider1 = providers.Factory(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ContainerB(ContainerA):
 | 
				
			||||||
 | 
					    """Example IoC container B."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    provider2 = providers.Singleton(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Making some asserts for `providers` attribute:
 | 
				
			||||||
 | 
					assert ContainerA.providers == dict(provider1=ContainerA.provider1)
 | 
				
			||||||
 | 
					assert ContainerB.providers == dict(provider1=ContainerA.provider1,
 | 
				
			||||||
 | 
					                                    provider2=ContainerB.provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Making some asserts for `cls_providers` attribute:
 | 
				
			||||||
 | 
					assert ContainerA.cls_providers == dict(provider1=ContainerA.provider1)
 | 
				
			||||||
 | 
					assert ContainerB.cls_providers == dict(provider2=ContainerB.provider2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Making some asserts for `inherited_providers` attribute:
 | 
				
			||||||
 | 
					assert ContainerA.inherited_providers == dict()
 | 
				
			||||||
 | 
					assert ContainerB.inherited_providers == dict(provider1=ContainerB.provider1)
 | 
				
			||||||
							
								
								
									
										35
									
								
								examples/containers/declarative_injections.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					"""Declarative IoC container's provider injections example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sqlite3
 | 
				
			||||||
 | 
					import collections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UsersService = collections.namedtuple('UsersService', ['db'])
 | 
				
			||||||
 | 
					AuthService = collections.namedtuple('AuthService', ['db', 'users_service'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Services(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					    """IoC container of service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    users = providers.Factory(UsersService,
 | 
				
			||||||
 | 
					                              db=database)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auth = providers.Factory(AuthService,
 | 
				
			||||||
 | 
					                             db=database,
 | 
				
			||||||
 | 
					                             users_service=users)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Retrieving service providers from container:
 | 
				
			||||||
 | 
					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()
 | 
				
			||||||
							
								
								
									
										48
									
								
								examples/containers/declarative_provider_type.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					"""Specializing declarative container and factory provider example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import collections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
 | 
					import dependency_injector.errors as errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SequenceProvider(providers.Factory):
 | 
				
			||||||
 | 
					    """Sequence factory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Can provide only sequence objects.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    provided_type = collections.Sequence
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SequencesContainer(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					    """IoC container.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Can contain only sequence providers.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    provider_type = SequenceProvider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        class _SequenceContainer1(SequencesContainer):
 | 
				
			||||||
 | 
					            object_provider = providers.Factory(object)
 | 
				
			||||||
 | 
					    except errors.Error as exception:
 | 
				
			||||||
 | 
					        print exception
 | 
				
			||||||
 | 
					        # <class '__main__._SequenceContainer1'> can contain only
 | 
				
			||||||
 | 
					        # <class '__main__.SequenceProvider'> instances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        class _SequenceContainer2(SequencesContainer):
 | 
				
			||||||
 | 
					            object_provider = SequenceProvider(object)
 | 
				
			||||||
 | 
					    except errors.Error as exception:
 | 
				
			||||||
 | 
					        print exception
 | 
				
			||||||
 | 
					        # <class '__main__.SequenceProvider'> can provide only
 | 
				
			||||||
 | 
					        # <class '_abcoll.Sequence'> instances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class _SequenceContaier3(SequencesContainer):
 | 
				
			||||||
 | 
					        list_provider = SequenceProvider(list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert _SequenceContaier3.list_provider() == list()
 | 
				
			||||||
							
								
								
									
										18
									
								
								examples/containers/dynamic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					"""Dynamic container simple example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Defining dynamic container:
 | 
				
			||||||
 | 
					container = containers.DynamicContainer()
 | 
				
			||||||
 | 
					container.factory1 = providers.Factory(object)
 | 
				
			||||||
 | 
					container.factory2 = providers.Factory(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Creating some objects:
 | 
				
			||||||
 | 
					object1 = container.factory1()
 | 
				
			||||||
 | 
					object2 = container.factory2()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Making some asserts:
 | 
				
			||||||
 | 
					assert object1 is not object2
 | 
				
			||||||
 | 
					assert isinstance(object1, object) and isinstance(object2, object)
 | 
				
			||||||
							
								
								
									
										41
									
								
								examples/containers/dynamic_provider_type.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,41 @@
 | 
				
			||||||
 | 
					"""Specializing dynamic container and factory provider example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import collections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
 | 
					import dependency_injector.errors as errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SequenceProvider(providers.Factory):
 | 
				
			||||||
 | 
					    """Sequence factory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Can provide only sequence objects.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    provided_type = collections.Sequence
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sequences_container = containers.DynamicContainer()
 | 
				
			||||||
 | 
					sequences_container.provider_type = SequenceProvider
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        sequences_container.object_provider = providers.Factory(object)
 | 
				
			||||||
 | 
					    except errors.Error as exception:
 | 
				
			||||||
 | 
					        print exception
 | 
				
			||||||
 | 
					        # <dependency_injector.containers.DynamicContainer object at
 | 
				
			||||||
 | 
					        # 0x107820ed0> can contain only <class '__main__.SequenceProvider'>
 | 
				
			||||||
 | 
					        # instances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        sequences_container.object_provider = SequenceProvider(object)
 | 
				
			||||||
 | 
					    except errors.Error as exception:
 | 
				
			||||||
 | 
					        print exception
 | 
				
			||||||
 | 
					        # <class '__main__.SequenceProvider'> can provide only
 | 
				
			||||||
 | 
					        # <class '_abcoll.Sequence'> instances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sequences_container.list_provider = SequenceProvider(list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert sequences_container.list_provider() == list()
 | 
				
			||||||
| 
						 | 
					@ -1,15 +1,13 @@
 | 
				
			||||||
"""Dynamic catalog creation and runtime filling of it example."""
 | 
					"""Creation of dynamic container based on some configuration example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from dependency_injector import catalogs
 | 
					import collections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Defining several example services:
 | 
					# Defining several example services:
 | 
				
			||||||
class UsersService(object):
 | 
					UsersService = collections.namedtuple('UsersService', [])
 | 
				
			||||||
    """Example users service."""
 | 
					AuthService = collections.namedtuple('AuthService', [])
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AuthService(object):
 | 
					 | 
				
			||||||
    """Example auth service."""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def import_cls(cls_name):
 | 
					def import_cls(cls_name):
 | 
				
			||||||
| 
						 | 
					@ -19,9 +17,7 @@ def import_cls(cls_name):
 | 
				
			||||||
    don't use it in production approaches.
 | 
					    don't use it in production approaches.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    path_components = cls_name.split('.')
 | 
					    path_components = cls_name.split('.')
 | 
				
			||||||
    if len(path_components) == 1:
 | 
					    module = __import__('.'.join(path_components[:-1]),
 | 
				
			||||||
        path_components.insert(0, '__main__')
 | 
					 | 
				
			||||||
    module = __import__('.'.join(path_components[0:-1]),
 | 
					 | 
				
			||||||
                        locals(),
 | 
					                        locals(),
 | 
				
			||||||
                        globals(),
 | 
					                        globals(),
 | 
				
			||||||
                        fromlist=path_components[-1:])
 | 
					                        fromlist=path_components[-1:])
 | 
				
			||||||
| 
						 | 
					@ -32,30 +28,27 @@ def import_cls(cls_name):
 | 
				
			||||||
config = {
 | 
					config = {
 | 
				
			||||||
    'services': {
 | 
					    'services': {
 | 
				
			||||||
        'users': {
 | 
					        'users': {
 | 
				
			||||||
            'class': 'UsersService',
 | 
					            'class': '__main__.UsersService',
 | 
				
			||||||
            'provider_class': 'dependency_injector.providers.Factory',
 | 
					            'provider_class': 'dependency_injector.providers.Factory',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        'auth': {
 | 
					        'auth': {
 | 
				
			||||||
            'class': 'AuthService',
 | 
					            'class': '__main__.AuthService',
 | 
				
			||||||
            'provider_class': 'dependency_injector.providers.Factory',
 | 
					            'provider_class': 'dependency_injector.providers.Factory',
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Defining dynamic service providers catalog:
 | 
					# Creating empty container of service providers:
 | 
				
			||||||
services = catalogs.DynamicCatalog()
 | 
					services = containers.DynamicContainer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Filling dynamic service providers catalog according to the configuration:
 | 
					# Filling dynamic container with service providers using configuration:
 | 
				
			||||||
for service_name, service_info in config['services'].iteritems():
 | 
					for service_name, service_info in config['services'].iteritems():
 | 
				
			||||||
    # Runtime importing of service and service provider classes:
 | 
					    # Runtime importing of service and service provider classes:
 | 
				
			||||||
    service_cls = import_cls(service_info['class'])
 | 
					    service_cls = import_cls(service_info['class'])
 | 
				
			||||||
    service_provider_cls = import_cls(service_info['provider_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:
 | 
					    # Binding service provider to the dynamic service providers catalog:
 | 
				
			||||||
    services.bind_provider(service_name, service_provider)
 | 
					    setattr(services, service_name, service_provider_cls(service_cls))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Creating some objects:
 | 
					# Creating some objects:
 | 
				
			||||||
users_service = services.users()
 | 
					users_service = services.users()
 | 
				
			||||||
							
								
								
									
										28
									
								
								examples/containers/override_declarative.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					"""Declarative IoC container overriding example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Container(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					    """IoC container."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sequence_factory = providers.Factory(list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OverridingContainer(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					    """Overriding IoC container."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sequence_factory = providers.Factory(tuple)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Overriding `Container` with `OverridingContainer`:
 | 
				
			||||||
 | 
					Container.override(OverridingContainer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Creating some objects using overridden container:
 | 
				
			||||||
 | 
					sequence_1 = Container.sequence_factory([1, 2, 3])
 | 
				
			||||||
 | 
					sequence_2 = Container.sequence_factory([3, 2, 1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Making some asserts:
 | 
				
			||||||
 | 
					assert Container.overridden == (OverridingContainer,)
 | 
				
			||||||
 | 
					assert sequence_1 == (1, 2, 3) and sequence_2 == (3, 2, 1)
 | 
				
			||||||
							
								
								
									
										27
									
								
								examples/containers/override_declarative_decorator.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					"""Declarative IoC container overriding using `@override()` decorator."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dependency_injector.containers as containers
 | 
				
			||||||
 | 
					import dependency_injector.providers as providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Container(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					    """IoC container."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sequence_factory = providers.Factory(list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Overriding `Container` with `OverridingContainer`:
 | 
				
			||||||
 | 
					@containers.override(Container)
 | 
				
			||||||
 | 
					class OverridingContainer(containers.DeclarativeContainer):
 | 
				
			||||||
 | 
					    """Overriding IoC container."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sequence_factory = providers.Factory(tuple)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Creating some objects using overridden container:
 | 
				
			||||||
 | 
					sequence_1 = Container.sequence_factory([1, 2, 3])
 | 
				
			||||||
 | 
					sequence_2 = Container.sequence_factory([3, 2, 1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Making some asserts:
 | 
				
			||||||
 | 
					assert Container.overridden == (OverridingContainer,)
 | 
				
			||||||
 | 
					assert sequence_1 == (1, 2, 3) and sequence_2 == (3, 2, 1)
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ class Car(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self):
 | 
				
			||||||
        """Initializer."""
 | 
					        """Initializer."""
 | 
				
			||||||
        self.engine = Engine()
 | 
					        self.engine = Engine()  # Engine is a "hardcoded" dependency
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
"""Refactored Car & Engine example that demostrates inversion of control."""
 | 
					"""Refactored Car & Engine example that demonstrates inversion of control."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Engine(object):
 | 
					class Engine(object):
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ class Car(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, engine):
 | 
					    def __init__(self, engine):
 | 
				
			||||||
        """Initializer."""
 | 
					        """Initializer."""
 | 
				
			||||||
        self.engine = engine
 | 
					        self.engine = engine  # Engine is an "injected" dependency
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||