mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-02-16 19:40:59 +03:00
Add validation of provided type for Factory provider
This commit is contained in:
parent
ee37558946
commit
10e76f65d7
|
@ -246,6 +246,16 @@ class Factory(Provider):
|
||||||
some_object = factory()
|
some_object = factory()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
provided_type = None
|
||||||
|
"""Provided type.
|
||||||
|
|
||||||
|
If provided type is defined, :py:class:`Factory` checks that
|
||||||
|
:py:attr:`Factory.provides` is subclass of
|
||||||
|
:py:attr:`Factory.provided_type`.
|
||||||
|
|
||||||
|
:type: type | None
|
||||||
|
"""
|
||||||
|
|
||||||
__slots__ = ('provides', 'args', 'kwargs', 'attributes', 'methods')
|
__slots__ = ('provides', 'args', 'kwargs', 'attributes', 'methods')
|
||||||
|
|
||||||
def __init__(self, provides, *args, **kwargs):
|
def __init__(self, provides, *args, **kwargs):
|
||||||
|
@ -261,10 +271,7 @@ class Factory(Provider):
|
||||||
:param kwargs: Dictionary of injections.
|
:param kwargs: Dictionary of injections.
|
||||||
:type kwargs: dict
|
:type kwargs: dict
|
||||||
"""
|
"""
|
||||||
if not callable(provides):
|
self.provides = self._ensure_provides_type(provides)
|
||||||
raise Error('Factory provider expects to get callable, ' +
|
|
||||||
'got {0} instead'.format(str(provides)))
|
|
||||||
self.provides = provides
|
|
||||||
"""Class or other callable that provides object for creation.
|
"""Class or other callable that provides object for creation.
|
||||||
|
|
||||||
:type: type | callable
|
:type: type | callable
|
||||||
|
@ -328,6 +335,31 @@ class Factory(Provider):
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
def _ensure_provides_type(self, provides):
|
||||||
|
"""Check if provided type is valid type for this factory.
|
||||||
|
|
||||||
|
:param provides: Factory provided type
|
||||||
|
:type provides: type
|
||||||
|
|
||||||
|
:raise: :py:exc:`dependency_injector.errors.Error` if ``provides``
|
||||||
|
is not callable
|
||||||
|
:raise: :py:exc:`dependency_injector.errors.Error` if ``provides``
|
||||||
|
doesn't meet factory provided type
|
||||||
|
|
||||||
|
:return: validated ``provides``
|
||||||
|
:rtype: type
|
||||||
|
"""
|
||||||
|
if not callable(provides):
|
||||||
|
raise Error('Factory provider expects to get callable, ' +
|
||||||
|
'got {0} instead'.format(str(provides)))
|
||||||
|
if (self.__class__.provided_type and
|
||||||
|
not issubclass(provides, self.__class__.provided_type)):
|
||||||
|
raise Error('{0} can provide only {1} instances'.format(
|
||||||
|
'.'.join((self.__class__.__module__,
|
||||||
|
self.__class__.__name__)),
|
||||||
|
self.__class__.provided_type))
|
||||||
|
return provides
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""Return string representation of provider.
|
"""Return string representation of provider.
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ follows `Semantic versioning`_
|
||||||
|
|
||||||
Development version
|
Development version
|
||||||
-------------------
|
-------------------
|
||||||
- No features.
|
- Add possibility to validate ``Factory`` provided type on ``Factory``
|
||||||
|
initialization.
|
||||||
|
|
||||||
1.11.2
|
1.11.2
|
||||||
------
|
------
|
||||||
|
|
|
@ -176,6 +176,41 @@ class FactoryTests(unittest.TestCase):
|
||||||
"""Test creation of provider with a callable."""
|
"""Test creation of provider with a callable."""
|
||||||
self.assertTrue(providers.Factory(credits))
|
self.assertTrue(providers.Factory(credits))
|
||||||
|
|
||||||
|
def test_init_with_valid_provided_type(self):
|
||||||
|
"""Test creation with not valid provided type."""
|
||||||
|
class ExampleFactory(providers.Factory):
|
||||||
|
"""Example factory."""
|
||||||
|
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
example_factory = ExampleFactory(Example, 1, 2)
|
||||||
|
|
||||||
|
self.assertIsInstance(example_factory(), Example)
|
||||||
|
|
||||||
|
def test_init_with_valid_provided_subtype(self):
|
||||||
|
"""Test creation with not valid provided type."""
|
||||||
|
class ExampleFactory(providers.Factory):
|
||||||
|
"""Example factory."""
|
||||||
|
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
class NewExampe(Example):
|
||||||
|
"""Example class subclass."""
|
||||||
|
|
||||||
|
example_factory = ExampleFactory(NewExampe, 1, 2)
|
||||||
|
|
||||||
|
self.assertIsInstance(example_factory(), NewExampe)
|
||||||
|
|
||||||
|
def test_init_with_invalid_provided_type(self):
|
||||||
|
"""Test creation with not valid provided type."""
|
||||||
|
class ExampleFactory(providers.Factory):
|
||||||
|
"""Example factory."""
|
||||||
|
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
with self.assertRaises(errors.Error):
|
||||||
|
ExampleFactory(list)
|
||||||
|
|
||||||
def test_init_with_not_callable(self):
|
def test_init_with_not_callable(self):
|
||||||
"""Test creation of provider with not a callable."""
|
"""Test creation of provider with not a callable."""
|
||||||
self.assertRaises(errors.Error, providers.Factory, 123)
|
self.assertRaises(errors.Error, providers.Factory, 123)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user