mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 11:04:01 +03:00
Moving @override decorator into catalogs module and @inject decorator into injections module
This commit is contained in:
parent
90455beb4c
commit
498465b705
|
@ -4,6 +4,7 @@ Dependency management tool for Python projects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .catalog import AbstractCatalog
|
from .catalog import AbstractCatalog
|
||||||
|
from .catalog import override
|
||||||
|
|
||||||
from .providers import Provider
|
from .providers import Provider
|
||||||
from .providers import Delegate
|
from .providers import Delegate
|
||||||
|
@ -20,9 +21,7 @@ from .providers import Config
|
||||||
from .injections import KwArg
|
from .injections import KwArg
|
||||||
from .injections import Attribute
|
from .injections import Attribute
|
||||||
from .injections import Method
|
from .injections import Method
|
||||||
|
from .injections import inject
|
||||||
from .decorators import override
|
|
||||||
from .decorators import inject
|
|
||||||
|
|
||||||
from .errors import Error
|
from .errors import Error
|
||||||
|
|
||||||
|
|
|
@ -65,3 +65,12 @@ class AbstractCatalog(object):
|
||||||
"""
|
"""
|
||||||
for name, provider in iteritems(overriding.providers):
|
for name, provider in iteritems(overriding.providers):
|
||||||
cls.providers[name].override(provider)
|
cls.providers[name].override(provider)
|
||||||
|
|
||||||
|
|
||||||
|
def override(catalog):
|
||||||
|
"""Catalog overriding decorator."""
|
||||||
|
def decorator(overriding_catalog):
|
||||||
|
"""Overriding decorator."""
|
||||||
|
catalog.override(overriding_catalog)
|
||||||
|
return overriding_catalog
|
||||||
|
return decorator
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
"""Decorators module."""
|
|
||||||
|
|
||||||
from six import wraps
|
|
||||||
|
|
||||||
from .utils import ensure_is_injection
|
|
||||||
from .utils import get_injectable_kwargs
|
|
||||||
|
|
||||||
|
|
||||||
def override(catalog):
|
|
||||||
"""Catalog overriding decorator."""
|
|
||||||
def decorator(overriding_catalog):
|
|
||||||
"""Overriding decorator."""
|
|
||||||
catalog.override(overriding_catalog)
|
|
||||||
return overriding_catalog
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
def inject(injection):
|
|
||||||
"""Dependency injection decorator.
|
|
||||||
|
|
||||||
:type injection: Injection
|
|
||||||
:return: (callable) -> (callable)
|
|
||||||
"""
|
|
||||||
injection = ensure_is_injection(injection)
|
|
||||||
|
|
||||||
def decorator(callback):
|
|
||||||
"""Dependency injection decorator."""
|
|
||||||
if hasattr(callback, '_injections'):
|
|
||||||
callback._injections += (injection,)
|
|
||||||
|
|
||||||
@wraps(callback)
|
|
||||||
def decorated(*args, **kwargs):
|
|
||||||
"""Decorated with dependency injection callback."""
|
|
||||||
return callback(*args,
|
|
||||||
**get_injectable_kwargs(kwargs,
|
|
||||||
getattr(decorated,
|
|
||||||
'_injections')))
|
|
||||||
|
|
||||||
setattr(decorated, '_injections', (injection,))
|
|
||||||
|
|
||||||
return decorated
|
|
||||||
return decorator
|
|
|
@ -1,6 +1,10 @@
|
||||||
"""Injections module."""
|
"""Injections module."""
|
||||||
|
|
||||||
|
from six import wraps
|
||||||
|
|
||||||
from .utils import is_provider
|
from .utils import is_provider
|
||||||
|
from .utils import ensure_is_injection
|
||||||
|
from .utils import get_injectable_kwargs
|
||||||
|
|
||||||
|
|
||||||
class Injection(object):
|
class Injection(object):
|
||||||
|
@ -42,3 +46,30 @@ class Method(Injection):
|
||||||
"""Method injection."""
|
"""Method injection."""
|
||||||
|
|
||||||
__IS_METHOD_INJECTION__ = True
|
__IS_METHOD_INJECTION__ = True
|
||||||
|
|
||||||
|
|
||||||
|
def inject(injection):
|
||||||
|
"""Dependency injection decorator.
|
||||||
|
|
||||||
|
:type injection: Injection
|
||||||
|
:return: (callable) -> (callable)
|
||||||
|
"""
|
||||||
|
injection = ensure_is_injection(injection)
|
||||||
|
|
||||||
|
def decorator(callback):
|
||||||
|
"""Dependency injection decorator."""
|
||||||
|
if hasattr(callback, '_injections'):
|
||||||
|
callback._injections += (injection,)
|
||||||
|
|
||||||
|
@wraps(callback)
|
||||||
|
def decorated(*args, **kwargs):
|
||||||
|
"""Decorated with dependency injection callback."""
|
||||||
|
return callback(*args,
|
||||||
|
**get_injectable_kwargs(kwargs,
|
||||||
|
getattr(decorated,
|
||||||
|
'_injections')))
|
||||||
|
|
||||||
|
setattr(decorated, '_injections', (injection,))
|
||||||
|
|
||||||
|
return decorated
|
||||||
|
return decorator
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import unittest2 as unittest
|
import unittest2 as unittest
|
||||||
|
|
||||||
from objects.catalog import AbstractCatalog
|
from objects.catalog import AbstractCatalog
|
||||||
|
from objects.catalog import override
|
||||||
|
|
||||||
from objects.providers import Object
|
from objects.providers import Object
|
||||||
from objects.providers import Value
|
from objects.providers import Value
|
||||||
|
@ -68,3 +69,29 @@ class CatalogTests(unittest.TestCase):
|
||||||
self.assertIs(Catalog2.provider, Catalog2.providers['provider'])
|
self.assertIs(Catalog2.provider, Catalog2.providers['provider'])
|
||||||
|
|
||||||
self.assertIsNot(Catalog1.provider, Catalog2.provider)
|
self.assertIsNot(Catalog1.provider, Catalog2.provider)
|
||||||
|
|
||||||
|
|
||||||
|
class OverrideTests(unittest.TestCase):
|
||||||
|
|
||||||
|
"""Override decorator test cases."""
|
||||||
|
|
||||||
|
class Catalog(AbstractCatalog):
|
||||||
|
|
||||||
|
"""Test catalog."""
|
||||||
|
|
||||||
|
obj = Object(object())
|
||||||
|
another_obj = Object(object())
|
||||||
|
|
||||||
|
def test_overriding(self):
|
||||||
|
"""Test catalog overriding with another catalog."""
|
||||||
|
@override(self.Catalog)
|
||||||
|
class OverridingCatalog(self.Catalog):
|
||||||
|
|
||||||
|
"""Overriding catalog."""
|
||||||
|
|
||||||
|
obj = Value(1)
|
||||||
|
another_obj = Value(2)
|
||||||
|
|
||||||
|
self.assertEqual(self.Catalog.obj(), 1)
|
||||||
|
self.assertEqual(self.Catalog.another_obj(), 2)
|
||||||
|
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
"""Objects decorators unittests."""
|
|
||||||
|
|
||||||
import unittest2 as unittest
|
|
||||||
|
|
||||||
from objects.decorators import override
|
|
||||||
from objects.decorators import inject
|
|
||||||
|
|
||||||
from objects.catalog import AbstractCatalog
|
|
||||||
|
|
||||||
from objects.providers import Factory
|
|
||||||
from objects.providers import Object
|
|
||||||
from objects.providers import Value
|
|
||||||
|
|
||||||
from objects.injections import KwArg
|
|
||||||
|
|
||||||
from objects.errors import Error
|
|
||||||
|
|
||||||
|
|
||||||
class OverrideTests(unittest.TestCase):
|
|
||||||
|
|
||||||
"""Override decorator test cases."""
|
|
||||||
|
|
||||||
class Catalog(AbstractCatalog):
|
|
||||||
|
|
||||||
"""Test catalog."""
|
|
||||||
|
|
||||||
obj = Object(object())
|
|
||||||
another_obj = Object(object())
|
|
||||||
|
|
||||||
def test_overriding(self):
|
|
||||||
"""Test catalog overriding with another catalog."""
|
|
||||||
@override(self.Catalog)
|
|
||||||
class OverridingCatalog(self.Catalog):
|
|
||||||
|
|
||||||
"""Overriding catalog."""
|
|
||||||
|
|
||||||
obj = Value(1)
|
|
||||||
another_obj = Value(2)
|
|
||||||
|
|
||||||
self.assertEqual(self.Catalog.obj(), 1)
|
|
||||||
self.assertEqual(self.Catalog.another_obj(), 2)
|
|
||||||
|
|
||||||
|
|
||||||
class InjectTests(unittest.TestCase):
|
|
||||||
|
|
||||||
"""Inject decorator test cases."""
|
|
||||||
|
|
||||||
def test_decorated(self):
|
|
||||||
"""Test `inject()` decorated callback."""
|
|
||||||
provider1 = Factory(object)
|
|
||||||
provider2 = Factory(list)
|
|
||||||
|
|
||||||
@inject(KwArg('a', provider1))
|
|
||||||
@inject(KwArg('b', provider2))
|
|
||||||
def test(a, b):
|
|
||||||
return a, b
|
|
||||||
|
|
||||||
a1, b1 = test()
|
|
||||||
a2, b2 = test()
|
|
||||||
|
|
||||||
self.assertIsInstance(a1, object)
|
|
||||||
self.assertIsInstance(a2, object)
|
|
||||||
self.assertIsNot(a1, a2)
|
|
||||||
|
|
||||||
self.assertIsInstance(b1, list)
|
|
||||||
self.assertIsInstance(b2, list)
|
|
||||||
self.assertIsNot(b1, b2)
|
|
||||||
|
|
||||||
def test_decorated_kwargs_priority(self):
|
|
||||||
"""Test `inject()` decorated callback kwargs priority."""
|
|
||||||
provider1 = Factory(object)
|
|
||||||
provider2 = Factory(list)
|
|
||||||
object_a = object()
|
|
||||||
|
|
||||||
@inject(KwArg('a', provider1))
|
|
||||||
@inject(KwArg('b', provider2))
|
|
||||||
def test(a, b):
|
|
||||||
return a, b
|
|
||||||
|
|
||||||
a1, b1 = test(a=object_a)
|
|
||||||
a2, b2 = test(a=object_a)
|
|
||||||
|
|
||||||
self.assertIsInstance(a1, object)
|
|
||||||
self.assertIsInstance(a2, object)
|
|
||||||
self.assertIs(a1, object_a)
|
|
||||||
self.assertIs(a2, object_a)
|
|
||||||
|
|
||||||
self.assertIsInstance(b1, list)
|
|
||||||
self.assertIsInstance(b2, list)
|
|
||||||
self.assertIsNot(b1, b2)
|
|
||||||
|
|
||||||
def test_decorated_with_args(self):
|
|
||||||
"""Test `inject()` decorated callback with args."""
|
|
||||||
provider = Factory(list)
|
|
||||||
object_a = object()
|
|
||||||
|
|
||||||
@inject(KwArg('b', provider))
|
|
||||||
def test(a, b):
|
|
||||||
return a, b
|
|
||||||
|
|
||||||
a1, b1 = test(object_a)
|
|
||||||
a2, b2 = test(object_a)
|
|
||||||
|
|
||||||
self.assertIsInstance(a1, object)
|
|
||||||
self.assertIsInstance(a2, object)
|
|
||||||
self.assertIs(a1, object_a)
|
|
||||||
self.assertIs(a2, object_a)
|
|
||||||
|
|
||||||
self.assertIsInstance(b1, list)
|
|
||||||
self.assertIsInstance(b2, list)
|
|
||||||
self.assertIsNot(b1, b2)
|
|
||||||
|
|
||||||
def test_decorate_with_not_injection(self):
|
|
||||||
"""Test `inject()` decorator with not an injection instance."""
|
|
||||||
self.assertRaises(Error, inject, object)
|
|
|
@ -6,9 +6,12 @@ from objects.injections import Injection
|
||||||
from objects.injections import KwArg
|
from objects.injections import KwArg
|
||||||
from objects.injections import Attribute
|
from objects.injections import Attribute
|
||||||
from objects.injections import Method
|
from objects.injections import Method
|
||||||
|
from objects.injections import inject
|
||||||
|
|
||||||
from objects.providers import Factory
|
from objects.providers import Factory
|
||||||
|
|
||||||
|
from objects.errors import Error
|
||||||
|
|
||||||
|
|
||||||
class InjectionTests(unittest.TestCase):
|
class InjectionTests(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -62,3 +65,77 @@ class MethodTests(unittest.TestCase):
|
||||||
injection = Method('some_arg_name', 'some_value')
|
injection = Method('some_arg_name', 'some_value')
|
||||||
self.assertEqual(injection.name, 'some_arg_name')
|
self.assertEqual(injection.name, 'some_arg_name')
|
||||||
self.assertEqual(injection.injectable, 'some_value')
|
self.assertEqual(injection.injectable, 'some_value')
|
||||||
|
|
||||||
|
|
||||||
|
class InjectTests(unittest.TestCase):
|
||||||
|
|
||||||
|
"""Inject decorator test cases."""
|
||||||
|
|
||||||
|
def test_decorated(self):
|
||||||
|
"""Test `inject()` decorated callback."""
|
||||||
|
provider1 = Factory(object)
|
||||||
|
provider2 = Factory(list)
|
||||||
|
|
||||||
|
@inject(KwArg('a', provider1))
|
||||||
|
@inject(KwArg('b', provider2))
|
||||||
|
def test(a, b):
|
||||||
|
return a, b
|
||||||
|
|
||||||
|
a1, b1 = test()
|
||||||
|
a2, b2 = test()
|
||||||
|
|
||||||
|
self.assertIsInstance(a1, object)
|
||||||
|
self.assertIsInstance(a2, object)
|
||||||
|
self.assertIsNot(a1, a2)
|
||||||
|
|
||||||
|
self.assertIsInstance(b1, list)
|
||||||
|
self.assertIsInstance(b2, list)
|
||||||
|
self.assertIsNot(b1, b2)
|
||||||
|
|
||||||
|
def test_decorated_kwargs_priority(self):
|
||||||
|
"""Test `inject()` decorated callback kwargs priority."""
|
||||||
|
provider1 = Factory(object)
|
||||||
|
provider2 = Factory(list)
|
||||||
|
object_a = object()
|
||||||
|
|
||||||
|
@inject(KwArg('a', provider1))
|
||||||
|
@inject(KwArg('b', provider2))
|
||||||
|
def test(a, b):
|
||||||
|
return a, b
|
||||||
|
|
||||||
|
a1, b1 = test(a=object_a)
|
||||||
|
a2, b2 = test(a=object_a)
|
||||||
|
|
||||||
|
self.assertIsInstance(a1, object)
|
||||||
|
self.assertIsInstance(a2, object)
|
||||||
|
self.assertIs(a1, object_a)
|
||||||
|
self.assertIs(a2, object_a)
|
||||||
|
|
||||||
|
self.assertIsInstance(b1, list)
|
||||||
|
self.assertIsInstance(b2, list)
|
||||||
|
self.assertIsNot(b1, b2)
|
||||||
|
|
||||||
|
def test_decorated_with_args(self):
|
||||||
|
"""Test `inject()` decorated callback with args."""
|
||||||
|
provider = Factory(list)
|
||||||
|
object_a = object()
|
||||||
|
|
||||||
|
@inject(KwArg('b', provider))
|
||||||
|
def test(a, b):
|
||||||
|
return a, b
|
||||||
|
|
||||||
|
a1, b1 = test(object_a)
|
||||||
|
a2, b2 = test(object_a)
|
||||||
|
|
||||||
|
self.assertIsInstance(a1, object)
|
||||||
|
self.assertIsInstance(a2, object)
|
||||||
|
self.assertIs(a1, object_a)
|
||||||
|
self.assertIs(a2, object_a)
|
||||||
|
|
||||||
|
self.assertIsInstance(b1, list)
|
||||||
|
self.assertIsInstance(b2, list)
|
||||||
|
self.assertIsNot(b1, b2)
|
||||||
|
|
||||||
|
def test_decorate_with_not_injection(self):
|
||||||
|
"""Test `inject()` decorator with not an injection instance."""
|
||||||
|
self.assertRaises(Error, inject, object)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user