Add protection for wiring only declarative container instances

This commit is contained in:
Roman Mogylatov 2020-09-28 15:52:21 -04:00
parent cc1b6ba3e6
commit d9334ef1fe
4 changed files with 298 additions and 523 deletions

File diff suppressed because it is too large Load Diff

View File

@ -15,10 +15,10 @@ if sys.version_info[:2] >= (3, 6):
from .wiring import wire, unwire
else:
def wire(*args, **kwargs):
raise NotADirectoryError('Wiring requires Python 3.6 or above')
raise NotImplementedError('Wiring requires Python 3.6 or above')
def unwire(*args, **kwargs):
raise NotADirectoryError('Wiring requires Python 3.6 or above')
raise NotImplementedError('Wiring requires Python 3.6 or above')
class DynamicContainer(object):
@ -416,18 +416,6 @@ class DeclarativeContainer(object):
else:
return None
@classmethod
def wire(cls, modules=None, packages=None):
"""Wire container providers with provided packages and modules by name.
:rtype: None
"""
wire(
container=cls,
modules=modules,
packages=packages,
)
def override(object container):
""":py:class:`DeclarativeContainer` overriding decorator.

View File

@ -25,7 +25,7 @@ __all__ = (
)
T = TypeVar('T')
AnyContainer = Any
Container = Any
class ProvidersMap:
@ -135,13 +135,15 @@ class ProvidersMap:
def wire(
container: AnyContainer,
container: Container,
*,
modules: Optional[Iterable[ModuleType]] = None,
packages: Optional[Iterable[ModuleType]] = None,
) -> None:
"""Wire container providers with provided packages and modules."""
# TODO: Add protection to only wire declarative container instances
if not _is_declarative_container_instance(container):
raise Exception('Can wire only an instance of the declarative container')
if not modules:
modules = []
@ -290,6 +292,12 @@ def _get_original_from_patched(fn):
return getattr(fn, '__original__')
def _is_declarative_container_instance(instance: Any) -> bool:
return (not isinstance(instance, type)
and getattr(instance, '__IS_CONTAINER__', False) is True
and getattr(instance, 'declarative_parent', None) is not None)
class ClassGetItemMeta(GenericMeta):
def __getitem__(cls, item):
# Spike for Python 3.6

View File

@ -1,6 +1,8 @@
from decimal import Decimal
import unittest
from dependency_injector.wiring import wire
from . import module, package
from .service import Service
from .container import Container
@ -94,3 +96,11 @@ class WiringTest(unittest.TestCase):
with self.container.config.switch.override('b'):
value_b = module.test_config_invariant()
self.assertEqual(value_b, 2)
def test_wire_with_class_error(self):
with self.assertRaises(Exception):
wire(
container=Container,
modules=[module],
)