diff --git a/dependency_injector/catalogs.py b/dependency_injector/catalogs.py index d788ea7e..5c8b5ff3 100644 --- a/dependency_injector/catalogs.py +++ b/dependency_injector/catalogs.py @@ -7,6 +7,7 @@ from .errors import UndefinedProviderError from .utils import is_provider from .utils import is_catalog +from .utils import is_declarative_catalog from .utils import ensure_is_provider from .utils import ensure_is_catalog_bundle @@ -252,10 +253,16 @@ class DynamicCatalog(object): :param overriding: Overriding catalog. :type overriding: :py:class:`DeclarativeCatalog` | - :py:class:`DynamicCatalog` + :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) @@ -673,8 +680,14 @@ class DeclarativeCatalog(object): :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 diff --git a/tests/test_catalogs.py b/tests/test_catalogs.py index 7af5798a..3ba48e20 100644 --- a/tests/test_catalogs.py +++ b/tests/test_catalogs.py @@ -474,6 +474,23 @@ class OverrideTests(unittest.TestCase): self.assertEqual(CatalogA.p12(), 2) self.assertEqual(len(CatalogA.overridden_by), 1) + def test_override_declarative_catalog_with_itself(self): + """Test catalog overriding of declarative catalog with itself.""" + with self.assertRaises(errors.Error): + CatalogA.override(CatalogA) + + def test_override_declarative_catalog_with_subclass(self): + """Test catalog overriding of declarative catalog with subclass.""" + with self.assertRaises(errors.Error): + CatalogB.override(CatalogA) + + def test_override_dynamic_catalog_with_itself(self): + """Test catalog overriding of dynamic catalog with itself.""" + catalog = catalogs.DynamicCatalog(p11=providers.Value(1), + p12=providers.Value(2)) + with self.assertRaises(errors.Error): + catalog.override(catalog) + def test_overriding_with_dynamic_catalog(self): """Test catalog overriding with another dynamic catalog.""" CatalogA.override(catalogs.DynamicCatalog(p11=providers.Value(1),