mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-06-16 11:33:13 +03:00
Merge remote-tracking branch 'origin/2.0-change-injections-style' into 2.0
This commit is contained in:
commit
5bc6ad0165
115
README.rst
115
README.rst
|
@ -55,20 +55,20 @@ Installation
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
Brief example below demonstrates usage of *Dependency Injector* catalogs 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
|
||||||
from boto.s3.connection import S3Connection
|
import example.services
|
||||||
|
|
||||||
from dependency_injector import catalogs
|
from dependency_injector import catalogs
|
||||||
from dependency_injector import providers
|
from dependency_injector import providers
|
||||||
from dependency_injector import injections
|
|
||||||
|
|
||||||
from example import services
|
|
||||||
|
|
||||||
|
|
||||||
class Platform(catalogs.DeclarativeCatalog):
|
class Platform(catalogs.DeclarativeCatalog):
|
||||||
|
@ -76,7 +76,7 @@ Example
|
||||||
|
|
||||||
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')
|
||||||
|
|
||||||
|
@ -84,32 +84,105 @@ Example
|
||||||
class Services(catalogs.DeclarativeCatalog):
|
class Services(catalogs.DeclarativeCatalog):
|
||||||
"""Catalog of business service providers."""
|
"""Catalog 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,
|
photos = providers.Factory(example.services.Photos,
|
||||||
db=Platform.database,
|
db=Platform.database,
|
||||||
s3=Platform.s3)
|
s3=Platform.s3)
|
||||||
|
|
||||||
auth = providers.Factory(services.Auth,
|
auth = providers.Factory(example.services.Auth,
|
||||||
db=Platform.database,
|
db=Platform.database,
|
||||||
token_ttl=3600)
|
token_ttl=3600)
|
||||||
|
|
||||||
|
Next example demonstrates usage of ``@inject`` decorator with IoC containers
|
||||||
|
defined above:
|
||||||
|
|
||||||
@injections.inject(users_service=Services.users)
|
.. code-block:: python
|
||||||
@injections.inject(auth_service=Services.auth)
|
|
||||||
@injections.inject(photos_service=Services.photos)
|
"""Dependency Injector @inject decorator example."""
|
||||||
def main(argv, users_service, auth_service, photos_service):
|
|
||||||
|
from dependency_injector.injections import inject
|
||||||
|
|
||||||
|
from catalogs import Services
|
||||||
|
|
||||||
|
|
||||||
|
@inject(users_service=Services.users)
|
||||||
|
@inject(auth_service=Services.auth)
|
||||||
|
@inject(photos_service=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(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of platform service providers."""
|
||||||
|
|
||||||
|
database = providers.Singleton(sqlite3.connect) \
|
||||||
|
.args(':memory:')
|
||||||
|
|
||||||
|
s3 = providers.Singleton(boto.s3.connection.S3Connection) \
|
||||||
|
.kwargs(aws_access_key_id='KEY',
|
||||||
|
aws_secret_access_key='SECRET')
|
||||||
|
|
||||||
|
|
||||||
|
class Services(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of business service providers."""
|
||||||
|
|
||||||
|
users = providers.Factory(example.services.Users) \
|
||||||
|
.kwargs(db=Platform.database)
|
||||||
|
|
||||||
|
photos = providers.Factory(example.services.Photos) \
|
||||||
|
.kwargs(db=Platform.database,
|
||||||
|
s3=Platform.s3)
|
||||||
|
|
||||||
|
auth = providers.Factory(example.services.Auth) \
|
||||||
|
.kwargs(db=Platform.database,
|
||||||
|
token_ttl=3600)
|
||||||
|
|
||||||
|
or like this these:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
class Platform(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of platform service providers."""
|
||||||
|
|
||||||
|
database = providers.Singleton(sqlite3.connect)
|
||||||
|
database.args(':memory:')
|
||||||
|
|
||||||
|
s3 = providers.Singleton(boto.s3.connection.S3Connection)
|
||||||
|
s3.kwargs(aws_access_key_id='KEY',
|
||||||
|
aws_secret_access_key='SECRET')
|
||||||
|
|
||||||
|
|
||||||
|
class Services(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of business service providers."""
|
||||||
|
|
||||||
|
users = providers.Factory(example.services.Users)
|
||||||
|
users.kwargs(db=Platform.database)
|
||||||
|
|
||||||
|
photos = providers.Factory(example.services.Photos)
|
||||||
|
photos.kwargs(db=Platform.database,
|
||||||
|
s3=Platform.s3)
|
||||||
|
|
||||||
|
auth = providers.Factory(example.services.Auth)
|
||||||
|
auth.kwargs(db=Platform.database,
|
||||||
|
token_ttl=3600)
|
||||||
|
|
||||||
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,13 +1,15 @@
|
||||||
"""Injections module."""
|
"""Injections module."""
|
||||||
|
|
||||||
|
import itertools
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from dependency_injector.utils import (
|
from dependency_injector.utils import (
|
||||||
is_provider,
|
is_provider,
|
||||||
is_delegated_provider,
|
|
||||||
is_injection,
|
is_injection,
|
||||||
is_arg_injection,
|
is_arg_injection,
|
||||||
is_kwarg_injection,
|
is_kwarg_injection,
|
||||||
|
is_delegated_provider,
|
||||||
fetch_cls_init,
|
fetch_cls_init,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ class Injection(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__IS_INJECTION__ = True
|
__IS_INJECTION__ = True
|
||||||
__slots__ = ('injectable', 'call_injectable')
|
__slots__ = ('injectable', 'get_value')
|
||||||
|
|
||||||
def __init__(self, injectable):
|
def __init__(self, injectable):
|
||||||
"""Initializer.
|
"""Initializer.
|
||||||
|
@ -47,24 +49,14 @@ class Injection(object):
|
||||||
:py:class:`dependency_injector.providers.Provider`
|
:py:class:`dependency_injector.providers.Provider`
|
||||||
"""
|
"""
|
||||||
self.injectable = injectable
|
self.injectable = injectable
|
||||||
self.call_injectable = (is_provider(injectable) and
|
|
||||||
not is_delegated_provider(injectable))
|
if not is_provider(injectable) or is_delegated_provider(injectable):
|
||||||
|
def injectable():
|
||||||
|
return self.injectable
|
||||||
|
self.get_value = injectable
|
||||||
|
|
||||||
super(Injection, self).__init__()
|
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):
|
def __str__(self):
|
||||||
"""Return string representation of provider.
|
"""Return string representation of provider.
|
||||||
|
|
||||||
|
@ -227,11 +219,11 @@ def inject(*args, **kwargs):
|
||||||
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.get_value() for arg in decorated.args) + args
|
||||||
|
|
||||||
for kwarg in decorated.kwargs:
|
for kwarg in decorated.kwargs:
|
||||||
if kwarg.name not in kwargs:
|
if kwarg.name not in kwargs:
|
||||||
kwargs[kwarg.name] = kwarg.value
|
kwargs[kwarg.name] = kwarg.get_value()
|
||||||
|
|
||||||
return callback(*args, **kwargs)
|
return callback(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -246,18 +238,16 @@ def inject(*args, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def _parse_args_injections(args):
|
def _parse_args_injections(args):
|
||||||
"""Parse positional argument injections according to current syntax."""
|
|
||||||
return tuple(Arg(arg) if not is_injection(arg) else arg
|
return tuple(Arg(arg) if not is_injection(arg) else arg
|
||||||
for arg in args
|
for arg in args
|
||||||
if not is_injection(arg) or is_arg_injection(arg))
|
if not is_injection(arg) or is_arg_injection(arg))
|
||||||
|
|
||||||
|
|
||||||
def _parse_kwargs_injections(args, kwargs):
|
def _parse_kwargs_injections(args, kwargs):
|
||||||
"""Parse keyword argument injections according to current syntax."""
|
|
||||||
kwarg_injections = tuple(injection
|
kwarg_injections = tuple(injection
|
||||||
for injection in args
|
for injection in args
|
||||||
if is_kwarg_injection(injection))
|
if is_kwarg_injection(injection))
|
||||||
if kwargs:
|
if kwargs:
|
||||||
kwarg_injections += tuple(KwArg(name, value)
|
kwarg_injections += tuple(itertools.starmap(KwArg,
|
||||||
for name, value in six.iteritems(kwargs))
|
six.iteritems(kwargs)))
|
||||||
return kwarg_injections
|
return kwarg_injections
|
||||||
|
|
|
@ -3,70 +3,46 @@
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from dependency_injector.providers.base import Provider
|
from dependency_injector.providers.base import Provider
|
||||||
from dependency_injector.injections import (
|
from dependency_injector.injections import Arg, KwArg
|
||||||
_parse_args_injections,
|
|
||||||
_parse_kwargs_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
|
||||||
|
|
||||||
|
|
||||||
@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` provider provides callable that is called on every
|
||||||
provider call with some predefined dependency injections.
|
provider call with some predefined dependency injections.
|
||||||
|
|
||||||
:py:class:`Callable` syntax of passing injections is the same like
|
:py:class:`Callable` supports positional and keyword argument injections:
|
||||||
: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) \
|
||||||
|
.args('positional_arg1', 'positional_arg2') \
|
||||||
|
.kwargs(keyword_argument1=3, keyword_argument=4)
|
||||||
|
|
||||||
:type: callable
|
# or
|
||||||
|
|
||||||
.. py:attribute:: args
|
some_function = Callable(some_function)
|
||||||
|
some_function.args('positional_arg1', 'positional_arg2')
|
||||||
Tuple of positional argument injections.
|
some_function.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')
|
||||||
|
|
||||||
def __init__(self, provides, *args, **kwargs):
|
def __init__(self, provides, *args, **kwargs):
|
||||||
"""Initializer.
|
"""Initializer.
|
||||||
|
|
||||||
: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, '
|
||||||
|
@ -74,12 +50,12 @@ class Callable(Provider):
|
||||||
self.__class__.__name__)),
|
self.__class__.__name__)),
|
||||||
provides))
|
provides))
|
||||||
|
|
||||||
self.provides = provides
|
self._provides = provides
|
||||||
|
self._args = tuple()
|
||||||
|
self._kwargs = tuple()
|
||||||
|
|
||||||
self.args = tuple()
|
self.args(*args)
|
||||||
self.kwargs = tuple()
|
self.kwargs(**kwargs)
|
||||||
|
|
||||||
self.add_injections(*args, **kwargs)
|
|
||||||
|
|
||||||
super(Callable, self).__init__()
|
super(Callable, self).__init__()
|
||||||
|
|
||||||
|
@ -89,19 +65,30 @@ class Callable(Provider):
|
||||||
|
|
||||||
:rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
|
:rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
|
||||||
"""
|
"""
|
||||||
return self.args + self.kwargs
|
return self._args + self._kwargs
|
||||||
|
|
||||||
def add_injections(self, *args, **kwargs):
|
def args(self, *args):
|
||||||
"""Add provider injections.
|
"""Add postional argument injections.
|
||||||
|
|
||||||
:param args: Tuple of injections.
|
:param args: Tuple of injections.
|
||||||
:type args: tuple
|
:type args: tuple
|
||||||
|
|
||||||
|
:return: Reference ``self``
|
||||||
|
"""
|
||||||
|
self._args += tuple(Arg(value) for value in args)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def 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 += tuple(KwArg(name, value)
|
||||||
self.kwargs += _parse_kwargs_injections(args, kwargs)
|
for name, value in six.iteritems(kwargs))
|
||||||
|
return self
|
||||||
|
|
||||||
def _provide(self, *args, **kwargs):
|
def _provide(self, *args, **kwargs):
|
||||||
"""Return provided instance.
|
"""Return provided instance.
|
||||||
|
@ -114,21 +101,21 @@ 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.get_value() for arg in self._args) + args
|
||||||
|
|
||||||
for kwarg in self.kwargs:
|
for kwarg in self._kwargs:
|
||||||
if kwarg.name not in kwargs:
|
if kwarg.name not in kwargs:
|
||||||
kwargs[kwarg.name] = kwarg.value
|
kwargs[kwarg.name] = kwarg.get_value()
|
||||||
|
|
||||||
return self.provides(*args, **kwargs)
|
return self._provides(*args, **kwargs)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return string representation of provider.
|
"""Return string representation of provider.
|
||||||
|
|
||||||
:rtype: str
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
return represent_provider(provider=self, provides=self.provides)
|
return represent_provider(provider=self, provides=self._provides)
|
||||||
|
|
||||||
__repr__ = __str__
|
__repr__ = __str__
|
||||||
|
|
||||||
|
@ -138,24 +125,6 @@ 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
|
__IS_DELEGATED__ = True
|
||||||
|
|
|
@ -1,40 +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.injections import Attribute
|
||||||
is_attribute_injection,
|
from dependency_injector.utils import GLOBAL_LOCK
|
||||||
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) \
|
||||||
|
.args('positional_arg1', 'positional_arg2') \
|
||||||
|
.kwargs(keyword_argument1=3, keyword_argument=4)
|
||||||
|
|
||||||
|
# or
|
||||||
|
|
||||||
|
factory = Factory(SomeClass)
|
||||||
|
factory.args('positional_arg1', 'positional_arg2')
|
||||||
|
factory.kwargs(keyword_argument1=3, keyword_argument=4)
|
||||||
|
|
||||||
|
|
||||||
|
Attribute injections are defined by using :py:meth:`Factory.attributes`:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
factory = Factory(SomeClass) \
|
||||||
|
.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
|
||||||
|
@ -45,41 +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`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
provided_type = None
|
provided_type = None
|
||||||
|
|
||||||
__slots__ = ('cls', 'attributes')
|
__slots__ = ('cls', '_attributes')
|
||||||
|
|
||||||
def __init__(self, provides, *args, **kwargs):
|
def __init__(self, provides, *args, **kwargs):
|
||||||
"""Initializer.
|
"""Initializer.
|
||||||
|
@ -87,23 +76,17 @@ 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 = tuple()
|
||||||
|
|
||||||
super(Factory, self).__init__(provides, *args, **kwargs)
|
super(Factory, self).__init__(provides, *args, **kwargs)
|
||||||
|
|
||||||
self.cls = self.provides
|
self.cls = self._provides
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def injections(self):
|
def injections(self):
|
||||||
|
@ -111,22 +94,18 @@ class Factory(Callable):
|
||||||
|
|
||||||
:rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
|
:rtype: tuple[:py:class:`dependency_injector.injections.Injection`]
|
||||||
"""
|
"""
|
||||||
return self.args + self.kwargs + self.attributes
|
return super(Factory, self).injections + self._attributes
|
||||||
|
|
||||||
def add_injections(self, *args, **kwargs):
|
def attributes(self, **kwargs):
|
||||||
"""Add provider injections.
|
"""Add attribute 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
|
||||||
"""
|
|
||||||
self.attributes += tuple(injection
|
|
||||||
for injection in args
|
|
||||||
if is_attribute_injection(injection))
|
|
||||||
|
|
||||||
super(Factory, self).add_injections(*args, **kwargs)
|
:return: Reference ``self``
|
||||||
|
"""
|
||||||
|
self._attributes += tuple(Attribute(name, value)
|
||||||
|
for name, value in six.iteritems(kwargs))
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _provide(self, *args, **kwargs):
|
def _provide(self, *args, **kwargs):
|
||||||
|
@ -140,17 +119,17 @@ class Factory(Callable):
|
||||||
|
|
||||||
:rtype: object
|
:rtype: object
|
||||||
"""
|
"""
|
||||||
if self.args:
|
if self._args:
|
||||||
args = tuple(arg.value for arg in self.args) + args
|
args = tuple(arg.get_value() for arg in self._args) + args
|
||||||
|
|
||||||
for kwarg in self.kwargs:
|
for kwarg in self._kwargs:
|
||||||
if kwarg.name not in kwargs:
|
if kwarg.name not in kwargs:
|
||||||
kwargs[kwarg.name] = kwarg.value
|
kwargs[kwarg.name] = kwarg.get_value()
|
||||||
|
|
||||||
instance = self.provides(*args, **kwargs)
|
instance = self._provides(*args, **kwargs)
|
||||||
|
|
||||||
for attribute in self.attributes:
|
for attribute in self._attributes:
|
||||||
setattr(instance, attribute.name, attribute.value)
|
setattr(instance, attribute.name, attribute.get_value())
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
@ -169,36 +148,12 @@ 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`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__IS_DELEGATED__ = True
|
__IS_DELEGATED__ = True
|
||||||
|
@ -219,9 +174,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
|
||||||
|
@ -232,45 +185,15 @@ 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`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('instance',)
|
__slots__ = ('_instance',)
|
||||||
|
|
||||||
def __init__(self, provides, *args, **kwargs):
|
def __init__(self, provides, *args, **kwargs):
|
||||||
"""Initializer.
|
"""Initializer.
|
||||||
|
@ -278,14 +201,8 @@ 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)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
|
@ -293,7 +210,7 @@ class Singleton(Factory):
|
||||||
|
|
||||||
:rtype: None
|
:rtype: None
|
||||||
"""
|
"""
|
||||||
self.instance = None
|
self._instance = None
|
||||||
|
|
||||||
def _provide(self, *args, **kwargs):
|
def _provide(self, *args, **kwargs):
|
||||||
"""Return provided instance.
|
"""Return provided instance.
|
||||||
|
@ -306,13 +223,13 @@ class Singleton(Factory):
|
||||||
|
|
||||||
:rtype: object
|
:rtype: object
|
||||||
"""
|
"""
|
||||||
if self.instance:
|
if self._instance:
|
||||||
return self.instance
|
return self._instance
|
||||||
|
|
||||||
with GLOBAL_LOCK:
|
with GLOBAL_LOCK:
|
||||||
self.instance = super(Singleton, self)._provide(*args, **kwargs)
|
self._instance = super(Singleton, self)._provide(*args, **kwargs)
|
||||||
|
|
||||||
return self.instance
|
return self._instance
|
||||||
|
|
||||||
|
|
||||||
class DelegatedSingleton(Singleton):
|
class DelegatedSingleton(Singleton):
|
||||||
|
@ -329,42 +246,12 @@ 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`]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__IS_DELEGATED__ = True
|
__IS_DELEGATED__ = True
|
||||||
|
|
|
@ -13,7 +13,9 @@ Development version
|
||||||
|
|
||||||
2.0.0
|
2.0.0
|
||||||
------
|
------
|
||||||
- Drop backward compatibilities of 1.x.
|
- Introduce new injections style for ``Callable``, ``Factory`` &
|
||||||
|
``Singleton`` providers.
|
||||||
|
- Increase performance of retrieving injections in 2 times (+100%).
|
||||||
- Drop providers:
|
- Drop providers:
|
||||||
- ``Static``
|
- ``Static``
|
||||||
- ``Value``
|
- ``Value``
|
||||||
|
@ -21,6 +23,7 @@ Development version
|
||||||
- ``Class``
|
- ``Class``
|
||||||
- ``Config``
|
- ``Config``
|
||||||
- Drop ``Method`` injections.
|
- Drop ``Method`` injections.
|
||||||
|
- Drop backward compatibilities of 1.x.
|
||||||
|
|
||||||
1.17.0
|
1.17.0
|
||||||
------
|
------
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
Dependency Injector example
|
Dependency Injector IoC containers example
|
||||||
===========================
|
==========================================
|
||||||
|
|
||||||
Instructions for running:
|
Instructions for running
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
python main.py dependency-injector secret myself.jpg
|
python main.py
|
||||||
|
|
33
examples/miniapps/services/catalogs.py
Normal file
33
examples/miniapps/services/catalogs.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
"""Example of several Dependency Injector IoC containers."""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
import boto.s3.connection
|
||||||
|
import example.services
|
||||||
|
|
||||||
|
from dependency_injector import catalogs
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
|
||||||
|
class Platform(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of platform service providers."""
|
||||||
|
|
||||||
|
database = providers.Singleton(sqlite3.connect, ':memory:')
|
||||||
|
|
||||||
|
s3 = providers.Singleton(boto.s3.connection.S3Connection,
|
||||||
|
aws_access_key_id='KEY',
|
||||||
|
aws_secret_access_key='SECRET')
|
||||||
|
|
||||||
|
|
||||||
|
class Services(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of business service providers."""
|
||||||
|
|
||||||
|
users = providers.Factory(example.services.Users,
|
||||||
|
db=Platform.database)
|
||||||
|
|
||||||
|
photos = providers.Factory(example.services.Photos,
|
||||||
|
db=Platform.database,
|
||||||
|
s3=Platform.s3)
|
||||||
|
|
||||||
|
auth = providers.Factory(example.services.Auth,
|
||||||
|
db=Platform.database,
|
||||||
|
token_ttl=3600)
|
37
examples/miniapps/services/catalogs_alt_syntax_1.py
Normal file
37
examples/miniapps/services/catalogs_alt_syntax_1.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
"""Example of several Dependency Injector IoC containers.
|
||||||
|
|
||||||
|
Alternative injections definition style #1.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
import boto.s3.connection
|
||||||
|
import example.services
|
||||||
|
|
||||||
|
from dependency_injector import catalogs
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
|
||||||
|
class Platform(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of platform service providers."""
|
||||||
|
|
||||||
|
database = providers.Singleton(sqlite3.connect) \
|
||||||
|
.args(':memory:')
|
||||||
|
|
||||||
|
s3 = providers.Singleton(boto.s3.connection.S3Connection) \
|
||||||
|
.kwargs(aws_access_key_id='KEY',
|
||||||
|
aws_secret_access_key='SECRET')
|
||||||
|
|
||||||
|
|
||||||
|
class Services(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of business service providers."""
|
||||||
|
|
||||||
|
users = providers.Factory(example.services.Users) \
|
||||||
|
.kwargs(db=Platform.database)
|
||||||
|
|
||||||
|
photos = providers.Factory(example.services.Photos) \
|
||||||
|
.kwargs(db=Platform.database,
|
||||||
|
s3=Platform.s3)
|
||||||
|
|
||||||
|
auth = providers.Factory(example.services.Auth) \
|
||||||
|
.kwargs(db=Platform.database,
|
||||||
|
token_ttl=3600)
|
37
examples/miniapps/services/catalogs_alt_syntax_2.py
Normal file
37
examples/miniapps/services/catalogs_alt_syntax_2.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
"""Example of several Dependency Injector IoC containers.
|
||||||
|
|
||||||
|
Alternative injections definition style #2.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
import boto.s3.connection
|
||||||
|
import example.services
|
||||||
|
|
||||||
|
from dependency_injector import catalogs
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
|
||||||
|
class Platform(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of platform service providers."""
|
||||||
|
|
||||||
|
database = providers.Singleton(sqlite3.connect)
|
||||||
|
database.args(':memory:')
|
||||||
|
|
||||||
|
s3 = providers.Singleton(boto.s3.connection.S3Connection)
|
||||||
|
s3.kwargs(aws_access_key_id='KEY',
|
||||||
|
aws_secret_access_key='SECRET')
|
||||||
|
|
||||||
|
|
||||||
|
class Services(catalogs.DeclarativeCatalog):
|
||||||
|
"""Catalog of business service providers."""
|
||||||
|
|
||||||
|
users = providers.Factory(example.services.Users)
|
||||||
|
users.kwargs(db=Platform.database)
|
||||||
|
|
||||||
|
photos = providers.Factory(example.services.Photos)
|
||||||
|
photos.kwargs(db=Platform.database,
|
||||||
|
s3=Platform.s3)
|
||||||
|
|
||||||
|
auth = providers.Factory(example.services.Auth)
|
||||||
|
auth.kwargs(db=Platform.database,
|
||||||
|
token_ttl=3600)
|
|
@ -1,53 +1,19 @@
|
||||||
"""Dependency Injector example."""
|
"""Dependency Injector @inject decorator example."""
|
||||||
|
|
||||||
import sys
|
from dependency_injector.injections import inject
|
||||||
import sqlite3
|
|
||||||
|
|
||||||
from boto.s3.connection import S3Connection
|
from catalogs import Services
|
||||||
|
|
||||||
from dependency_injector import catalogs
|
|
||||||
from dependency_injector import providers
|
|
||||||
from dependency_injector import injections
|
|
||||||
|
|
||||||
from example import services
|
|
||||||
|
|
||||||
|
|
||||||
class Platform(catalogs.DeclarativeCatalog):
|
@inject(users_service=Services.users)
|
||||||
"""Catalog of platform service providers."""
|
@inject(auth_service=Services.auth)
|
||||||
|
@inject(photos_service=Services.photos)
|
||||||
database = providers.Singleton(sqlite3.connect, ':memory:')
|
def main(users_service, auth_service, photos_service):
|
||||||
|
|
||||||
s3 = providers.Singleton(S3Connection,
|
|
||||||
aws_access_key_id='KEY',
|
|
||||||
aws_secret_access_key='SECRET')
|
|
||||||
|
|
||||||
|
|
||||||
class Services(catalogs.DeclarativeCatalog):
|
|
||||||
"""Catalog of business service providers."""
|
|
||||||
|
|
||||||
users = providers.Factory(services.Users,
|
|
||||||
db=Platform.database)
|
|
||||||
|
|
||||||
photos = providers.Factory(services.Photos,
|
|
||||||
db=Platform.database,
|
|
||||||
s3=Platform.s3)
|
|
||||||
|
|
||||||
auth = providers.Factory(services.Auth,
|
|
||||||
db=Platform.database,
|
|
||||||
token_ttl=3600)
|
|
||||||
|
|
||||||
|
|
||||||
@injections.inject(users_service=Services.users)
|
|
||||||
@injections.inject(auth_service=Services.auth)
|
|
||||||
@injections.inject(photos_service=Services.photos)
|
|
||||||
def main(argv, 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()
|
||||||
|
|
|
@ -382,7 +382,8 @@ class CopyingTests(unittest.TestCase):
|
||||||
"""Test catalog providers copying."""
|
"""Test catalog providers copying."""
|
||||||
class CatalogA(catalogs.DeclarativeCatalog):
|
class CatalogA(catalogs.DeclarativeCatalog):
|
||||||
p11 = providers.Object(0)
|
p11 = providers.Object(0)
|
||||||
p12 = providers.Factory(dict, p11=p11)
|
p12 = providers.Factory(dict) \
|
||||||
|
.kwargs(p11=p11)
|
||||||
|
|
||||||
@catalogs.copy(CatalogA)
|
@catalogs.copy(CatalogA)
|
||||||
class CatalogA1(CatalogA):
|
class CatalogA1(CatalogA):
|
||||||
|
|
|
@ -2,12 +2,7 @@
|
||||||
|
|
||||||
import unittest2 as unittest
|
import unittest2 as unittest
|
||||||
|
|
||||||
from dependency_injector import (
|
from dependency_injector import providers, utils, errors
|
||||||
providers,
|
|
||||||
injections,
|
|
||||||
utils,
|
|
||||||
errors,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CallableTests(unittest.TestCase):
|
class CallableTests(unittest.TestCase):
|
||||||
|
@ -35,60 +30,51 @@ class CallableTests(unittest.TestCase):
|
||||||
|
|
||||||
New simplified syntax.
|
New simplified syntax.
|
||||||
"""
|
"""
|
||||||
provider = providers.Callable(self.example, 1, 2, 3, 4)
|
provider = providers.Callable(self.example) \
|
||||||
|
.args(1, 2, 3, 4)
|
||||||
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
||||||
|
|
||||||
def test_call_with_keyword_args(self):
|
def test_call_with_keyword_args(self):
|
||||||
"""Test call with keyword args.
|
"""Test call with keyword args."""
|
||||||
|
provider = providers.Callable(self.example) \
|
||||||
|
.kwargs(arg1=1, arg2=2, arg3=3, arg4=4)
|
||||||
|
|
||||||
New simplified syntax.
|
|
||||||
"""
|
|
||||||
provider = providers.Callable(self.example,
|
|
||||||
arg1=1,
|
|
||||||
arg2=2,
|
|
||||||
arg3=3,
|
|
||||||
arg4=4)
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
||||||
|
|
||||||
def test_call_with_positional_and_keyword_args(self):
|
def test_call_with_positional_and_keyword_args(self):
|
||||||
"""Test call with positional and keyword args.
|
"""Test call with positional and keyword args."""
|
||||||
|
provider = providers.Callable(self.example) \
|
||||||
|
.args(1, 2) \
|
||||||
|
.kwargs(arg3=3, arg4=4)
|
||||||
|
|
||||||
Simplified syntax of positional and keyword arg injections.
|
|
||||||
"""
|
|
||||||
provider = providers.Callable(self.example, 1, 2, arg3=3, arg4=4)
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_positional_and_keyword_args_extended_syntax(self):
|
|
||||||
"""Test call with positional and keyword args.
|
|
||||||
|
|
||||||
Extended syntax of positional and keyword arg injections.
|
|
||||||
"""
|
|
||||||
provider = providers.Callable(self.example,
|
|
||||||
injections.Arg(1),
|
|
||||||
injections.Arg(2),
|
|
||||||
injections.KwArg('arg3', 3),
|
|
||||||
injections.KwArg('arg4', 4))
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
||||||
|
|
||||||
def test_call_with_context_args(self):
|
def test_call_with_context_args(self):
|
||||||
"""Test call with context args."""
|
"""Test call with context args."""
|
||||||
provider = providers.Callable(self.example, 1, 2)
|
provider = providers.Callable(self.example) \
|
||||||
|
.args(1, 2)
|
||||||
|
|
||||||
self.assertTupleEqual(provider(3, 4), (1, 2, 3, 4))
|
self.assertTupleEqual(provider(3, 4), (1, 2, 3, 4))
|
||||||
|
|
||||||
def test_call_with_context_kwargs(self):
|
def test_call_with_context_kwargs(self):
|
||||||
"""Test call with context kwargs."""
|
"""Test call with context kwargs."""
|
||||||
provider = providers.Callable(self.example,
|
provider = providers.Callable(self.example) \
|
||||||
injections.KwArg('arg1', 1))
|
.kwargs(arg1=1)
|
||||||
|
|
||||||
self.assertTupleEqual(provider(arg2=2, arg3=3, arg4=4), (1, 2, 3, 4))
|
self.assertTupleEqual(provider(arg2=2, arg3=3, arg4=4), (1, 2, 3, 4))
|
||||||
|
|
||||||
def test_call_with_context_args_and_kwargs(self):
|
def test_call_with_context_args_and_kwargs(self):
|
||||||
"""Test call with context args and kwargs."""
|
"""Test call with context args and kwargs."""
|
||||||
provider = providers.Callable(self.example, 1)
|
provider = providers.Callable(self.example) \
|
||||||
|
.args(1)
|
||||||
|
|
||||||
self.assertTupleEqual(provider(2, arg3=3, arg4=4), (1, 2, 3, 4))
|
self.assertTupleEqual(provider(2, arg3=3, arg4=4), (1, 2, 3, 4))
|
||||||
|
|
||||||
def test_call_overridden(self):
|
def test_call_overridden(self):
|
||||||
"""Test creation of new instances on overridden provider."""
|
"""Test creation of new instances on overridden provider."""
|
||||||
provider = providers.Callable(self.example)
|
provider = providers.Callable(self.example)
|
||||||
|
|
||||||
provider.override(providers.Object((4, 3, 2, 1)))
|
provider.override(providers.Object((4, 3, 2, 1)))
|
||||||
provider.override(providers.Object((1, 2, 3, 4)))
|
provider.override(providers.Object((1, 2, 3, 4)))
|
||||||
|
|
||||||
|
@ -96,24 +82,20 @@ class CallableTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_injections(self):
|
def test_injections(self):
|
||||||
"""Test getting a full list of injections using injections property."""
|
"""Test getting a full list of injections using injections property."""
|
||||||
provider = providers.Callable(self.example, 1, 2, arg3=3, arg4=4)
|
provider = providers.Callable(self.example) \
|
||||||
|
.args(1, 2) \
|
||||||
|
.kwargs(arg3=3, arg4=4)
|
||||||
|
|
||||||
self.assertEquals(len(provider.injections), 4)
|
self.assertEquals(len(provider.injections), 4)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
"""Test representation of provider."""
|
"""Test representation of provider."""
|
||||||
provider = providers.Callable(self.example,
|
provider = providers.Callable(self.example) \
|
||||||
injections.KwArg(
|
.kwargs(arg1=providers.Factory(dict),
|
||||||
'arg1',
|
arg2=providers.Factory(list),
|
||||||
providers.Factory(dict)),
|
arg3=providers.Factory(set),
|
||||||
injections.KwArg(
|
arg4=providers.Factory(tuple))
|
||||||
'arg2',
|
|
||||||
providers.Factory(list)),
|
|
||||||
injections.KwArg(
|
|
||||||
'arg3',
|
|
||||||
providers.Factory(set)),
|
|
||||||
injections.KwArg(
|
|
||||||
'arg4',
|
|
||||||
providers.Factory(tuple)))
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.callable.'
|
'<dependency_injector.providers.callable.'
|
||||||
'Callable({0}) at {1}>'.format(
|
'Callable({0}) at {1}>'.format(
|
||||||
|
|
|
@ -2,12 +2,7 @@
|
||||||
|
|
||||||
import unittest2 as unittest
|
import unittest2 as unittest
|
||||||
|
|
||||||
from dependency_injector import (
|
from dependency_injector import providers, injections, utils, errors
|
||||||
providers,
|
|
||||||
injections,
|
|
||||||
utils,
|
|
||||||
errors,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Example(object):
|
class Example(object):
|
||||||
|
@ -47,7 +42,8 @@ class FactoryTests(unittest.TestCase):
|
||||||
|
|
||||||
provided_type = Example
|
provided_type = Example
|
||||||
|
|
||||||
example_provider = ExampleProvider(Example, 1, 2)
|
example_provider = ExampleProvider(Example) \
|
||||||
|
.args(1, 2)
|
||||||
|
|
||||||
self.assertIsInstance(example_provider(), Example)
|
self.assertIsInstance(example_provider(), Example)
|
||||||
|
|
||||||
|
@ -61,7 +57,8 @@ class FactoryTests(unittest.TestCase):
|
||||||
class NewExampe(Example):
|
class NewExampe(Example):
|
||||||
"""Example class subclass."""
|
"""Example class subclass."""
|
||||||
|
|
||||||
example_provider = ExampleProvider(NewExampe, 1, 2)
|
example_provider = ExampleProvider(NewExampe) \
|
||||||
|
.args(1, 2)
|
||||||
|
|
||||||
self.assertIsInstance(example_provider(), NewExampe)
|
self.assertIsInstance(example_provider(), NewExampe)
|
||||||
|
|
||||||
|
@ -76,8 +73,9 @@ class FactoryTests(unittest.TestCase):
|
||||||
ExampleProvider(list)
|
ExampleProvider(list)
|
||||||
|
|
||||||
def test_call(self):
|
def test_call(self):
|
||||||
"""Test creation of new instances."""
|
"""Test call."""
|
||||||
provider = providers.Factory(Example)
|
provider = providers.Factory(Example)
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
|
||||||
|
@ -86,11 +84,9 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance2, Example)
|
self.assertIsInstance(instance2, Example)
|
||||||
|
|
||||||
def test_call_with_init_positional_args(self):
|
def test_call_with_init_positional_args(self):
|
||||||
"""Test creation of new instances with init positional args.
|
"""Test call with init positional args."""
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
New simplified syntax.
|
.args('i1', 'i2')
|
||||||
"""
|
|
||||||
provider = providers.Factory(Example, 'i1', 'i2')
|
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
@ -106,11 +102,9 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance2, Example)
|
self.assertIsInstance(instance2, Example)
|
||||||
|
|
||||||
def test_call_with_init_keyword_args(self):
|
def test_call_with_init_keyword_args(self):
|
||||||
"""Test creation of new instances with init keyword args.
|
"""Test call with init keyword args."""
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
New simplified syntax.
|
.kwargs(init_arg1='i1', init_arg2='i2')
|
||||||
"""
|
|
||||||
provider = providers.Factory(Example, init_arg1='i1', init_arg2='i2')
|
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
@ -126,33 +120,10 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance2, Example)
|
self.assertIsInstance(instance2, Example)
|
||||||
|
|
||||||
def test_call_with_init_positional_and_keyword_args(self):
|
def test_call_with_init_positional_and_keyword_args(self):
|
||||||
"""Test creation of new instances with init positional and keyword args.
|
"""Test call with init positional and keyword args."""
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
Simplified syntax of positional and keyword arg injections.
|
.args('i1') \
|
||||||
"""
|
.kwargs(init_arg2='i2')
|
||||||
provider = providers.Factory(Example, 'i1', init_arg2='i2')
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
instance2 = provider()
|
|
||||||
|
|
||||||
self.assertEqual(instance1.init_arg1, 'i1')
|
|
||||||
self.assertEqual(instance1.init_arg2, 'i2')
|
|
||||||
|
|
||||||
self.assertEqual(instance2.init_arg1, 'i1')
|
|
||||||
self.assertEqual(instance2.init_arg2, 'i2')
|
|
||||||
|
|
||||||
self.assertIsNot(instance1, instance2)
|
|
||||||
self.assertIsInstance(instance1, Example)
|
|
||||||
self.assertIsInstance(instance2, Example)
|
|
||||||
|
|
||||||
def test_call_with_init_positional_and_keyword_args_extended_syntax(self):
|
|
||||||
"""Test creation of new instances with init positional and keyword args.
|
|
||||||
|
|
||||||
Extended syntax of positional and keyword arg injections.
|
|
||||||
"""
|
|
||||||
provider = providers.Factory(Example,
|
|
||||||
injections.Arg('i1'),
|
|
||||||
injections.KwArg('init_arg2', 'i2'))
|
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
@ -168,10 +139,9 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance2, Example)
|
self.assertIsInstance(instance2, Example)
|
||||||
|
|
||||||
def test_call_with_attributes(self):
|
def test_call_with_attributes(self):
|
||||||
"""Test creation of new instances with attribute injections."""
|
"""Test call with attribute injections."""
|
||||||
provider = providers.Factory(Example,
|
provider = providers.Factory(Example) \
|
||||||
injections.Attribute('attribute1', 'a1'),
|
.attributes(attribute1='a1', attribute2='a2')
|
||||||
injections.Attribute('attribute2', 'a2'))
|
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
@ -187,8 +157,10 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance2, Example)
|
self.assertIsInstance(instance2, Example)
|
||||||
|
|
||||||
def test_call_with_context_args(self):
|
def test_call_with_context_args(self):
|
||||||
"""Test creation of new instances with context args."""
|
"""Test call with context args."""
|
||||||
provider = providers.Factory(Example, 11, 22)
|
provider = providers.Factory(Example) \
|
||||||
|
.args(11, 22)
|
||||||
|
|
||||||
instance = provider(33, 44)
|
instance = provider(33, 44)
|
||||||
|
|
||||||
self.assertEqual(instance.init_arg1, 11)
|
self.assertEqual(instance.init_arg1, 11)
|
||||||
|
@ -197,9 +169,9 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertEqual(instance.init_arg4, 44)
|
self.assertEqual(instance.init_arg4, 44)
|
||||||
|
|
||||||
def test_call_with_context_kwargs(self):
|
def test_call_with_context_kwargs(self):
|
||||||
"""Test creation of new instances with context kwargs."""
|
"""Test call with context kwargs."""
|
||||||
provider = providers.Factory(Example,
|
provider = providers.Factory(Example) \
|
||||||
injections.KwArg('init_arg1', 1))
|
.kwargs(init_arg1=1)
|
||||||
|
|
||||||
instance1 = provider(init_arg2=22)
|
instance1 = provider(init_arg2=22)
|
||||||
self.assertEqual(instance1.init_arg1, 1)
|
self.assertEqual(instance1.init_arg1, 1)
|
||||||
|
@ -210,8 +182,10 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertEqual(instance2.init_arg2, 22)
|
self.assertEqual(instance2.init_arg2, 22)
|
||||||
|
|
||||||
def test_call_with_context_args_and_kwargs(self):
|
def test_call_with_context_args_and_kwargs(self):
|
||||||
"""Test creation of new instances with context args and kwargs."""
|
"""Test call with context args and kwargs."""
|
||||||
provider = providers.Factory(Example, 11)
|
provider = providers.Factory(Example) \
|
||||||
|
.args(11)
|
||||||
|
|
||||||
instance = provider(22, init_arg3=33, init_arg4=44)
|
instance = provider(22, init_arg3=33, init_arg4=44)
|
||||||
|
|
||||||
self.assertEqual(instance.init_arg1, 11)
|
self.assertEqual(instance.init_arg1, 11)
|
||||||
|
@ -220,7 +194,7 @@ class FactoryTests(unittest.TestCase):
|
||||||
self.assertEqual(instance.init_arg4, 44)
|
self.assertEqual(instance.init_arg4, 44)
|
||||||
|
|
||||||
def test_call_overridden(self):
|
def test_call_overridden(self):
|
||||||
"""Test creation of new instances on overridden provider."""
|
"""Test call on overridden provider."""
|
||||||
provider = providers.Factory(Example)
|
provider = providers.Factory(Example)
|
||||||
overriding_provider1 = providers.Factory(dict)
|
overriding_provider1 = providers.Factory(dict)
|
||||||
overriding_provider2 = providers.Factory(list)
|
overriding_provider2 = providers.Factory(list)
|
||||||
|
@ -237,20 +211,19 @@ class FactoryTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_injections(self):
|
def test_injections(self):
|
||||||
"""Test getting a full list of injections using injections property."""
|
"""Test getting a full list of injections using injections property."""
|
||||||
provider = providers.Factory(Example,
|
provider = providers.Factory(Example) \
|
||||||
injections.Arg(1),
|
.args(1) \
|
||||||
injections.KwArg('init_arg2', 2),
|
.kwargs(init_arg2=2) \
|
||||||
injections.Attribute('attribute1', 3),
|
.attributes(attribute1=3, attribute2=4)
|
||||||
injections.Attribute('attribute2', 4))
|
|
||||||
self.assertEquals(len(provider.injections), 4)
|
self.assertEquals(len(provider.injections), 4)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
"""Test representation of provider."""
|
"""Test representation of provider."""
|
||||||
provider = providers.Factory(Example,
|
provider = providers.Factory(Example) \
|
||||||
injections.KwArg('init_arg1',
|
.kwargs(init_arg1=providers.Factory(dict),
|
||||||
providers.Factory(dict)),
|
init_arg2=providers.Factory(list))
|
||||||
injections.KwArg('init_arg2',
|
|
||||||
providers.Factory(list)))
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.creational.'
|
'<dependency_injector.providers.creational.'
|
||||||
'Factory({0}) at {1}>'.format(
|
'Factory({0}) at {1}>'.format(
|
||||||
|
@ -300,7 +273,8 @@ class SingletonTests(unittest.TestCase):
|
||||||
|
|
||||||
provided_type = Example
|
provided_type = Example
|
||||||
|
|
||||||
example_provider = ExampleProvider(Example, 1, 2)
|
example_provider = ExampleProvider(Example) \
|
||||||
|
.args(1, 2)
|
||||||
|
|
||||||
self.assertIsInstance(example_provider(), Example)
|
self.assertIsInstance(example_provider(), Example)
|
||||||
|
|
||||||
|
@ -314,7 +288,8 @@ class SingletonTests(unittest.TestCase):
|
||||||
class NewExampe(Example):
|
class NewExampe(Example):
|
||||||
"""Example class subclass."""
|
"""Example class subclass."""
|
||||||
|
|
||||||
example_provider = ExampleProvider(NewExampe, 1, 2)
|
example_provider = ExampleProvider(NewExampe) \
|
||||||
|
.args(1, 2)
|
||||||
|
|
||||||
self.assertIsInstance(example_provider(), NewExampe)
|
self.assertIsInstance(example_provider(), NewExampe)
|
||||||
|
|
||||||
|
@ -331,6 +306,7 @@ class SingletonTests(unittest.TestCase):
|
||||||
def test_call(self):
|
def test_call(self):
|
||||||
"""Test getting of instances."""
|
"""Test getting of instances."""
|
||||||
provider = providers.Singleton(Example)
|
provider = providers.Singleton(Example)
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
|
||||||
|
@ -339,11 +315,9 @@ class SingletonTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance2, Example)
|
self.assertIsInstance(instance2, Example)
|
||||||
|
|
||||||
def test_call_with_init_positional_args(self):
|
def test_call_with_init_positional_args(self):
|
||||||
"""Test getting of instances with init positional args.
|
"""Test getting of instances with init positional args."""
|
||||||
|
provider = providers.Singleton(Example) \
|
||||||
New simplified syntax.
|
.args('i1', 'i2')
|
||||||
"""
|
|
||||||
provider = providers.Singleton(Example, 'i1', 'i2')
|
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
@ -359,11 +333,9 @@ class SingletonTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance2, Example)
|
self.assertIsInstance(instance2, Example)
|
||||||
|
|
||||||
def test_call_with_init_keyword_args(self):
|
def test_call_with_init_keyword_args(self):
|
||||||
"""Test getting of instances with init keyword args.
|
"""Test getting of instances with init keyword args."""
|
||||||
|
provider = providers.Singleton(Example) \
|
||||||
New simplified syntax.
|
.kwargs(init_arg1='i1', init_arg2='i2')
|
||||||
"""
|
|
||||||
provider = providers.Singleton(Example, init_arg1='i1', init_arg2='i2')
|
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
@ -379,33 +351,10 @@ class SingletonTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance2, Example)
|
self.assertIsInstance(instance2, Example)
|
||||||
|
|
||||||
def test_call_with_init_positional_and_keyword_args(self):
|
def test_call_with_init_positional_and_keyword_args(self):
|
||||||
"""Test getting of instances with init positional and keyword args.
|
"""Test getting of instances with init positional and keyword args."""
|
||||||
|
provider = providers.Singleton(Example) \
|
||||||
Simplified syntax of positional and keyword arg injections.
|
.args('i1') \
|
||||||
"""
|
.kwargs(init_arg2='i2')
|
||||||
provider = providers.Singleton(Example, 'i1', init_arg2='i2')
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
instance2 = provider()
|
|
||||||
|
|
||||||
self.assertEqual(instance1.init_arg1, 'i1')
|
|
||||||
self.assertEqual(instance1.init_arg2, 'i2')
|
|
||||||
|
|
||||||
self.assertEqual(instance2.init_arg1, 'i1')
|
|
||||||
self.assertEqual(instance2.init_arg2, 'i2')
|
|
||||||
|
|
||||||
self.assertIs(instance1, instance2)
|
|
||||||
self.assertIsInstance(instance1, Example)
|
|
||||||
self.assertIsInstance(instance2, Example)
|
|
||||||
|
|
||||||
def test_call_with_init_positional_and_keyword_args_extended_syntax(self):
|
|
||||||
"""Test getting of instances with init positional and keyword args.
|
|
||||||
|
|
||||||
Extended syntax of positional and keyword arg injections.
|
|
||||||
"""
|
|
||||||
provider = providers.Singleton(Example,
|
|
||||||
injections.Arg('i1'),
|
|
||||||
injections.KwArg('init_arg2', 'i2'))
|
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
@ -422,11 +371,8 @@ class SingletonTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_call_with_attributes(self):
|
def test_call_with_attributes(self):
|
||||||
"""Test getting of instances with attribute injections."""
|
"""Test getting of instances with attribute injections."""
|
||||||
provider = providers.Singleton(Example,
|
provider = providers.Singleton(Example) \
|
||||||
injections.Attribute('attribute1',
|
.attributes(attribute1='a1', attribute2='a2')
|
||||||
'a1'),
|
|
||||||
injections.Attribute('attribute2',
|
|
||||||
'a2'))
|
|
||||||
|
|
||||||
instance1 = provider()
|
instance1 = provider()
|
||||||
instance2 = provider()
|
instance2 = provider()
|
||||||
|
@ -444,6 +390,7 @@ class SingletonTests(unittest.TestCase):
|
||||||
def test_call_with_context_args(self):
|
def test_call_with_context_args(self):
|
||||||
"""Test getting of instances with context args."""
|
"""Test getting of instances with context args."""
|
||||||
provider = providers.Singleton(Example)
|
provider = providers.Singleton(Example)
|
||||||
|
|
||||||
instance = provider(11, 22)
|
instance = provider(11, 22)
|
||||||
|
|
||||||
self.assertEqual(instance.init_arg1, 11)
|
self.assertEqual(instance.init_arg1, 11)
|
||||||
|
@ -451,8 +398,8 @@ class SingletonTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_call_with_context_kwargs(self):
|
def test_call_with_context_kwargs(self):
|
||||||
"""Test getting of instances with context kwargs."""
|
"""Test getting of instances with context kwargs."""
|
||||||
provider = providers.Singleton(Example,
|
provider = providers.Singleton(Example) \
|
||||||
injections.KwArg('init_arg1', 1))
|
.kwargs(init_arg1=1)
|
||||||
|
|
||||||
instance1 = provider(init_arg2=22)
|
instance1 = provider(init_arg2=22)
|
||||||
self.assertEqual(instance1.init_arg1, 1)
|
self.assertEqual(instance1.init_arg1, 1)
|
||||||
|
@ -465,7 +412,8 @@ class SingletonTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_call_with_context_args_and_kwargs(self):
|
def test_call_with_context_args_and_kwargs(self):
|
||||||
"""Test getting of instances with context args and kwargs."""
|
"""Test getting of instances with context args and kwargs."""
|
||||||
provider = providers.Singleton(Example, 11)
|
provider = providers.Singleton(Example) \
|
||||||
|
.args(11)
|
||||||
instance = provider(22, init_arg3=33, init_arg4=44)
|
instance = provider(22, init_arg3=33, init_arg4=44)
|
||||||
|
|
||||||
self.assertEqual(instance.init_arg1, 11)
|
self.assertEqual(instance.init_arg1, 11)
|
||||||
|
@ -489,35 +437,13 @@ class SingletonTests(unittest.TestCase):
|
||||||
self.assertIsInstance(instance1, object)
|
self.assertIsInstance(instance1, object)
|
||||||
self.assertIsInstance(instance2, object)
|
self.assertIsInstance(instance2, object)
|
||||||
|
|
||||||
def test_provides_attr(self):
|
|
||||||
"""Test provides attribute."""
|
|
||||||
provider = providers.Singleton(Example)
|
|
||||||
self.assertIs(provider.provides, Example)
|
|
||||||
|
|
||||||
def test_args_attr(self):
|
|
||||||
"""Test args attribute."""
|
|
||||||
provider = providers.Singleton(Example, 1, 2)
|
|
||||||
self.assertEquals(len(provider.args), 2)
|
|
||||||
|
|
||||||
def test_kwargs_attr(self):
|
|
||||||
"""Test kwargs attribute."""
|
|
||||||
provider = providers.Singleton(Example, init_arg1=1, init_arg2=2)
|
|
||||||
self.assertEquals(len(provider.kwargs), 2)
|
|
||||||
|
|
||||||
def test_attributes_attr(self):
|
|
||||||
"""Test attributes attribute."""
|
|
||||||
provider = providers.Singleton(Example,
|
|
||||||
injections.Attribute('attribute1', 1),
|
|
||||||
injections.Attribute('attribute2', 2))
|
|
||||||
self.assertEquals(len(provider.attributes), 2)
|
|
||||||
|
|
||||||
def test_injections(self):
|
def test_injections(self):
|
||||||
"""Test getting a full list of injections using injections property."""
|
"""Test getting a full list of injections using injections property."""
|
||||||
provider = providers.Singleton(Example,
|
provider = providers.Singleton(Example) \
|
||||||
injections.Arg(1),
|
.args(1) \
|
||||||
injections.KwArg('init_arg2', 2),
|
.kwargs(init_arg2=2) \
|
||||||
injections.Attribute('attribute1', 3),
|
.attributes(attribute1=3, attribute2=4)
|
||||||
injections.Attribute('attribute2', 4))
|
|
||||||
self.assertEquals(len(provider.injections), 4)
|
self.assertEquals(len(provider.injections), 4)
|
||||||
|
|
||||||
def test_reset(self):
|
def test_reset(self):
|
||||||
|
@ -536,13 +462,10 @@ class SingletonTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
"""Test representation of provider."""
|
"""Test representation of provider."""
|
||||||
provider = providers.Singleton(Example,
|
provider = providers.Singleton(Example) \
|
||||||
injections.KwArg(
|
.kwargs(init_arg1=providers.Factory(dict),
|
||||||
'init_arg1',
|
init_arg2=providers.Factory(list))
|
||||||
providers.Factory(dict)),
|
|
||||||
injections.KwArg(
|
|
||||||
'init_arg2',
|
|
||||||
providers.Factory(list)))
|
|
||||||
self.assertEqual(repr(provider),
|
self.assertEqual(repr(provider),
|
||||||
'<dependency_injector.providers.creational.'
|
'<dependency_injector.providers.creational.'
|
||||||
'Singleton({0}) at {1}>'.format(
|
'Singleton({0}) at {1}>'.format(
|
||||||
|
|
|
@ -7,6 +7,8 @@ from dependency_injector import (
|
||||||
utils,
|
utils,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: move to test_base
|
||||||
|
|
||||||
|
|
||||||
class ObjectProviderTests(unittest.TestCase):
|
class ObjectProviderTests(unittest.TestCase):
|
||||||
"""Object provider tests."""
|
"""Object provider tests."""
|
||||||
|
|
|
@ -19,12 +19,12 @@ class InjectionTests(unittest.TestCase):
|
||||||
def test_value_with_scalar_injectable(self):
|
def test_value_with_scalar_injectable(self):
|
||||||
"""Test Injection value property with scalar value."""
|
"""Test Injection value property with scalar value."""
|
||||||
injection = injections.Injection('some_value')
|
injection = injections.Injection('some_value')
|
||||||
self.assertEqual(injection.value, 'some_value')
|
self.assertEqual(injection.get_value(), 'some_value')
|
||||||
|
|
||||||
def test_value_with_provider_injectable(self):
|
def test_value_with_provider_injectable(self):
|
||||||
"""Test Injection value property with provider."""
|
"""Test Injection value property with provider."""
|
||||||
injection = injections.Injection(providers.Factory(object))
|
injection = injections.Injection(providers.Factory(object))
|
||||||
self.assertIsInstance(injection.value, object)
|
self.assertIsInstance(injection.get_value(), object)
|
||||||
|
|
||||||
def test_value_with_catalog_bundle_injectable(self):
|
def test_value_with_catalog_bundle_injectable(self):
|
||||||
"""Test Injection value property with catalog bundle."""
|
"""Test Injection value property with catalog bundle."""
|
||||||
|
@ -35,7 +35,7 @@ class InjectionTests(unittest.TestCase):
|
||||||
injection = injections.Injection(
|
injection = injections.Injection(
|
||||||
TestCatalog.Bundle(TestCatalog.provider))
|
TestCatalog.Bundle(TestCatalog.provider))
|
||||||
|
|
||||||
self.assertIsInstance(injection.value, TestCatalog.Bundle)
|
self.assertIsInstance(injection.get_value(), TestCatalog.Bundle)
|
||||||
|
|
||||||
def test_repr(self):
|
def test_repr(self):
|
||||||
"""Test Injection representation."""
|
"""Test Injection representation."""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user