diff --git a/README.rst b/README.rst index 3b729206..4b14a9a0 100644 --- a/README.rst +++ b/README.rst @@ -87,7 +87,7 @@ Examples self.users_service = users_service - class Services(di.AbstractCatalog): + class Services(di.DeclarativeCatalog): """Catalog of service providers.""" database = di.Singleton(sqlite3.connect, ':memory:') diff --git a/dependency_injector/__init__.py b/dependency_injector/__init__.py index 97e40afb..24a49858 100644 --- a/dependency_injector/__init__.py +++ b/dependency_injector/__init__.py @@ -1,5 +1,6 @@ """Dependency injector.""" +from .catalog import DeclarativeCatalog from .catalog import AbstractCatalog from .catalog import CatalogBundle from .catalog import override @@ -44,6 +45,7 @@ VERSION = '0.10.5' __all__ = ( # Catalogs + 'DeclarativeCatalog', 'AbstractCatalog', 'CatalogBundle', 'override', diff --git a/dependency_injector/catalog.py b/dependency_injector/catalog.py index d3085678..41ea95b1 100644 --- a/dependency_injector/catalog.py +++ b/dependency_injector/catalog.py @@ -14,7 +14,7 @@ class CatalogBundle(object): """Bundle of catalog providers.""" catalog = None - """:type: AbstractCatalog""" + """:type: DeclarativeCatalog""" __IS_CATALOG_BUNDLE__ = True __slots__ = ('providers', '__dict__') @@ -67,12 +67,21 @@ class CatalogBundle(object): __str__ = __repr__ +class Catalog(object): + """Catalog of providers.""" + + def __init__(self, name, **providers): + """Initializer.""" + self.name = name + self.providers = providers + + @six.python_2_unicode_compatible -class CatalogMetaClass(type): - """Catalog meta class.""" +class DeclarativeCatalogMetaClass(type): + """Declarative catalog meta class.""" def __new__(mcs, class_name, bases, attributes): - """Catalog class factory.""" + """Declarative catalog class factory.""" cls_providers = dict((name, provider) for name, provider in six.iteritems(attributes) if is_provider(provider)) @@ -131,9 +140,9 @@ class CatalogMetaClass(type): __str__ = __repr__ -@six.add_metaclass(CatalogMetaClass) -class AbstractCatalog(object): - """Abstract providers catalog. +@six.add_metaclass(DeclarativeCatalogMetaClass) +class DeclarativeCatalog(object): + """Declarative catalog catalog of providers. :type Bundle: CatalogBundle :param Bundle: Catalog's bundle class @@ -149,14 +158,14 @@ class AbstractCatalog(object): :param inherited_providers: Dict of providers, that are inherited from parent catalogs - :type overridden_by: tuple[AbstractCatalog] + :type overridden_by: tuple[DeclarativeCatalog] :param overridden_by: Tuple of overriding catalogs :type is_overridden: bool :param is_overridden: Read-only, evaluated in runtime, property that is set to True if catalog is overridden - :type last_overriding: AbstractCatalog | None + :type last_overriding: DeclarativeCatalog | None :param last_overriding: Reference to the last overriding catalog, if any """ @@ -188,7 +197,7 @@ class AbstractCatalog(object): def override(cls, overriding): """Override current catalog providers by overriding catalog providers. - :type overriding: AbstractCatalog + :type overriding: DeclarativeCatalog """ cls.overridden_by += (overriding,) for name, provider in six.iteritems(overriding.cls_providers): @@ -225,6 +234,10 @@ class AbstractCatalog(object): return name in cls.providers +# Backward compatibility for versions < 0.11.* +AbstractCatalog = DeclarativeCatalog + + class ProviderBinding(object): """Catalog provider binding.""" diff --git a/docs/catalogs/bundles.rst b/docs/catalogs/bundles.rst index 49e916e2..50c76866 100644 --- a/docs/catalogs/bundles.rst +++ b/docs/catalogs/bundles.rst @@ -1,20 +1,20 @@ Creating catalog provider bundles --------------------------------- -``di.AbstractCatalog.Bundle`` is a limited collection of catalog providers. +``di.DeclarativeCatalog.Bundle`` is a limited collection of catalog providers. While catalog could be used as a centralized place for particular providers group, such bundles of catalog providers can be used for creating several limited scopes that could be passed to different subsystems. -``di.AbstractCatalog.Bundle`` has exactly the same API as -``di.AbstractCatalog`` except of the limitations on getting providers. +``di.DeclarativeCatalog.Bundle`` has exactly the same API as +``di.DeclarativeCatalog`` except of the limitations on getting providers. -Each ``di.AbstractCatalog`` has a reference to its bundle class - -``di.AbstractCatalog.Bundle``. For example, if some concrete catalog has name +Each ``di.DeclarativeCatalog`` has a reference to its bundle class - +``di.DeclarativeCatalog.Bundle``. For example, if some concrete catalog has name ``SomeCatalog``, then its bundle class could be reached as ``SomeCatalog.Bundle``. -``di.AbstractCatalog.Bundle`` expects to get the list of its catalog providers +``di.DeclarativeCatalog.Bundle`` expects to get the list of its catalog providers as positional arguments and will limit the scope of created bundle to this list. diff --git a/docs/catalogs/operating.rst b/docs/catalogs/operating.rst index 4b344b4e..1841c4a3 100644 --- a/docs/catalogs/operating.rst +++ b/docs/catalogs/operating.rst @@ -1,23 +1,24 @@ Operating with catalogs ----------------------- -``di.AbstractCatalog`` has several features that could be useful for some kind -of operations on catalog's providers: +``di.DeclarativeCatalog`` has several features that could be useful for some +kind of operations on catalog's providers: -- ``di.AbstractCatalog.providers`` is read-only attribute that contains +- ``di.DeclarativeCatalog.providers`` is read-only attribute that contains ``dict`` of all catalog providers, including providers that are inherited from parent catalogs, where key is the name of provider and value is provider itself. -- ``di.AbstractCatalog.cls_providers`` is read-only attribute contains ``dict`` - of current catalog providers, where key is the name of provider and value is - provider itself. -- ``di.AbstractCatalog.inherited_providers`` is read-only attribute contains - ``dict`` of all providers that are inherited from parent catalogs, where key - is the name of provider and value is provider itself. -- ``di.AbstractCatalog.filter(provider_type=di.Provider)`` is a class method - that could be used for filtering catalog providers by provider types +- ``di.DeclarativeCatalog.cls_providers`` is read-only attribute contains + ``dict`` of current catalog providers, where key is the name of provider + and value is provider itself. +- ``di.DeclarativeCatalog.inherited_providers`` is read-only attribute + contains ``dict`` of all providers that are inherited from parent catalogs, + where key is the name of provider and value is provider itself. +- ``di.DeclarativeCatalog.filter(provider_type=di.Provider)`` is a class + method that could be used for filtering catalog providers by provider types (for example, for getting all ``di.Factory`` providers). - ``di.AbstractCatalog.filter()`` method use ``di.AbstractCatalog.providers``. + ``di.DeclarativeCatalog.filter()`` method use + ``di.DeclarativeCatalog.providers``. Example: diff --git a/docs/catalogs/overriding.rst b/docs/catalogs/overriding.rst index 03ba19e6..feb6dfa5 100644 --- a/docs/catalogs/overriding.rst +++ b/docs/catalogs/overriding.rst @@ -7,10 +7,11 @@ same names in overridden catalog. There are two ways to override catalog by another catalog: -- Use ``di.AbstractCatalog.override(AnotherCatalog)`` method. +- Use ``di.DeclarativeCatalog.override(AnotherCatalog)`` method. - Use ``@di.override(AnotherCatalog)`` class decorator. -Example of overriding catalog using ``di.AbstractCatalog.override()`` method: +Example of overriding catalog using ``di.DeclarativeCatalog.override()`` +method: .. literalinclude:: ../../examples/catalogs/override.py :language: python @@ -23,12 +24,12 @@ Example of overriding catalog using ``@di.override()`` decorator: Also there are several useful methods and properties that help to work with catalog overridings: -- ``di.AbstractCatalog.is_overridden`` - read-only, evaluated in runtime, +- ``di.DeclarativeCatalog.is_overridden`` - read-only, evaluated in runtime, property that is set to True if catalog is overridden. -- ``di.AbstractCatalog.last_overriding`` - reference to the last overriding +- ``di.DeclarativeCatalog.last_overriding`` - reference to the last overriding catalog, if any. -- ``di.AbstractCatalog.overridden_by`` - tuple of all overriding catalogs. -- ``di.AbstractCatalog.reset_last_overriding()`` - reset last overriding +- ``di.DeclarativeCatalog.overridden_by`` - tuple of all overriding catalogs. +- ``di.DeclarativeCatalog.reset_last_overriding()`` - reset last overriding catalog. -- ``di.AbstractCatalog.reset_override()`` - reset all overridings for all +- ``di.DeclarativeCatalog.reset_override()`` - reset all overridings for all catalog providers. diff --git a/docs/catalogs/writing.rst b/docs/catalogs/writing.rst index 1db1c3c4..c6ee929f 100644 --- a/docs/catalogs/writing.rst +++ b/docs/catalogs/writing.rst @@ -1,7 +1,7 @@ Writing catalogs ---------------- -Catalogs have to extend base catalog class ``di.AbstractCatalog``. +Catalogs have to extend base catalog class ``di.DeclarativeCatalog``. Providers have to be defined like catalog's attributes. Every provider in catalog has name. This name should follow ``some_provider`` convention, diff --git a/docs/images/catalogs/bundles.png b/docs/images/catalogs/bundles.png index 14a20d22..29ff4e48 100644 Binary files a/docs/images/catalogs/bundles.png and b/docs/images/catalogs/bundles.png differ diff --git a/docs/images/catalogs/operating_with_providers.png b/docs/images/catalogs/operating_with_providers.png index 7c1a9ac7..759ce094 100644 Binary files a/docs/images/catalogs/operating_with_providers.png and b/docs/images/catalogs/operating_with_providers.png differ diff --git a/docs/images/catalogs/writing_catalogs.png b/docs/images/catalogs/writing_catalogs.png index a2bc6791..fdc84ec5 100644 Binary files a/docs/images/catalogs/writing_catalogs.png and b/docs/images/catalogs/writing_catalogs.png differ diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index f7aa28f3..6bcb2693 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -7,6 +7,11 @@ that were made in every particular version. From version 0.7.6 *Dependency Injector* framework strictly follows `Semantic versioning`_ +Development version +------------------- +- Rename ``di.AbstractCatalog`` to ``di.DeclarativeCatalog`` + (with backward compatibility). + 0.10.5 ------ - Add more representable implementation for ``di.AbstractCatalog`` and diff --git a/examples/catalogs/bundles/catalogs.py b/examples/catalogs/bundles/catalogs.py index 0b30db2d..2a9a7056 100644 --- a/examples/catalogs/bundles/catalogs.py +++ b/examples/catalogs/bundles/catalogs.py @@ -7,7 +7,7 @@ import views # Declaring services catalog: -class Services(di.AbstractCatalog): +class Services(di.DeclarativeCatalog): """Example catalog of service providers.""" users = di.Factory(services.UsersService) @@ -21,7 +21,7 @@ class Services(di.AbstractCatalog): # Declaring views catalog: -class Views(di.AbstractCatalog): +class Views(di.DeclarativeCatalog): """Example catalog of web views.""" auth = di.Factory(views.AuthView, diff --git a/examples/catalogs/operating_with_providers.py b/examples/catalogs/operating_with_providers.py index c978c41b..ebbac118 100644 --- a/examples/catalogs/operating_with_providers.py +++ b/examples/catalogs/operating_with_providers.py @@ -3,7 +3,7 @@ import dependency_injector as di -class CatalogA(di.AbstractCatalog): +class CatalogA(di.DeclarativeCatalog): """Example catalog A.""" provider1 = di.Factory(object) diff --git a/examples/catalogs/override.py b/examples/catalogs/override.py index a77982cd..5f5648c4 100644 --- a/examples/catalogs/override.py +++ b/examples/catalogs/override.py @@ -10,7 +10,7 @@ Object2 = collections.namedtuple('Object2', ['object1']) ExtendedObject2 = collections.namedtuple('ExtendedObject2', []) -class Catalog(di.AbstractCatalog): +class Catalog(di.DeclarativeCatalog): """Providers catalog.""" object1_factory = di.Factory(Object1, @@ -23,7 +23,7 @@ class Catalog(di.AbstractCatalog): """:type: di.Provider -> Object2""" -class AnotherCatalog(di.AbstractCatalog): +class AnotherCatalog(di.DeclarativeCatalog): """Another providers catalog.""" object2_factory = di.Factory(ExtendedObject2) diff --git a/examples/catalogs/override_decorator.py b/examples/catalogs/override_decorator.py index cba9b464..423d95e1 100644 --- a/examples/catalogs/override_decorator.py +++ b/examples/catalogs/override_decorator.py @@ -10,7 +10,7 @@ Object2 = collections.namedtuple('Object2', ['object1']) ExtendedObject2 = collections.namedtuple('ExtendedObject2', []) -class Catalog(di.AbstractCatalog): +class Catalog(di.DeclarativeCatalog): """Providers catalog.""" object1_factory = di.Factory(Object1, @@ -25,7 +25,7 @@ class Catalog(di.AbstractCatalog): # Overriding `Catalog` with `AnotherCatalog`: @di.override(Catalog) -class AnotherCatalog(di.AbstractCatalog): +class AnotherCatalog(di.DeclarativeCatalog): """Another providers catalog.""" object2_factory = di.Factory(ExtendedObject2) diff --git a/examples/catalogs/writing_catalogs.py b/examples/catalogs/writing_catalogs.py index 5b82050d..ebb89746 100644 --- a/examples/catalogs/writing_catalogs.py +++ b/examples/catalogs/writing_catalogs.py @@ -3,7 +3,7 @@ import dependency_injector as di -class Catalog(di.AbstractCatalog): +class Catalog(di.DeclarativeCatalog): """Providers catalog.""" factory1 = di.Factory(object) diff --git a/examples/concept.py b/examples/concept.py index 84c56f2a..af357c55 100644 --- a/examples/concept.py +++ b/examples/concept.py @@ -21,7 +21,7 @@ class AuthService(object): self.users_service = users_service -class Services(di.AbstractCatalog): +class Services(di.DeclarativeCatalog): """Catalog of service providers.""" database = di.Singleton(sqlite3.connect, ':memory:') diff --git a/tests/test_catalog.py b/tests/test_catalog.py index 779a343d..5a28d050 100644 --- a/tests/test_catalog.py +++ b/tests/test_catalog.py @@ -4,7 +4,7 @@ import unittest2 as unittest import dependency_injector as di -class CatalogA(di.AbstractCatalog): +class CatalogA(di.DeclarativeCatalog): """Test catalog A.""" p11 = di.Provider() @@ -29,7 +29,7 @@ class CatalogsInheritanceTests(unittest.TestCase): """Catalogs inheritance tests.""" def test_cls_providers(self): - """Test `di.AbstractCatalog.cls_providers` contents.""" + """Test `di.DeclarativeCatalog.cls_providers` contents.""" self.assertDictEqual(CatalogA.cls_providers, dict(p11=CatalogA.p11, p12=CatalogA.p12)) @@ -41,7 +41,7 @@ class CatalogsInheritanceTests(unittest.TestCase): p32=CatalogC.p32)) def test_inherited_providers(self): - """Test `di.AbstractCatalog.inherited_providers` contents.""" + """Test `di.DeclarativeCatalog.inherited_providers` contents.""" self.assertDictEqual(CatalogA.inherited_providers, dict()) self.assertDictEqual(CatalogB.inherited_providers, dict(p11=CatalogA.p11, @@ -53,7 +53,7 @@ class CatalogsInheritanceTests(unittest.TestCase): p22=CatalogB.p22)) def test_providers(self): - """Test `di.AbstractCatalog.inherited_providers` contents.""" + """Test `di.DeclarativeCatalog.inherited_providers` contents.""" self.assertDictEqual(CatalogA.providers, dict(p11=CatalogA.p11, p12=CatalogA.p12)) @@ -84,7 +84,8 @@ class CatalogProvidersBindingTests(unittest.TestCase): def test_provider_rebinding(self): """Test that provider could not be bound twice.""" - self.assertRaises(di.Error, type, 'TestCatalog', (di.AbstractCatalog,), + self.assertRaises(di.Error, type, 'TestCatalog', + (di.DeclarativeCatalog,), dict(some_name=CatalogA.p11)) @@ -136,7 +137,7 @@ class CatalogBundleTests(unittest.TestCase): def test_create_bundle_with_another_catalog_provider(self): """Test that bundle can not contain another catalog's provider.""" - class TestCatalog(di.AbstractCatalog): + class TestCatalog(di.DeclarativeCatalog): """Test catalog.""" provider = di.Provider() @@ -146,7 +147,7 @@ class CatalogBundleTests(unittest.TestCase): def test_create_bundle_with_another_catalog_provider_with_same_name(self): """Test that bundle can not contain another catalog's provider.""" - class TestCatalog(di.AbstractCatalog): + class TestCatalog(di.DeclarativeCatalog): """Test catalog.""" p31 = di.Provider() @@ -200,7 +201,7 @@ class CatalogTests(unittest.TestCase): class OverrideTests(unittest.TestCase): """Catalog overriding and override decorator test cases.""" - class Catalog(di.AbstractCatalog): + class Catalog(di.DeclarativeCatalog): """Test catalog.""" obj = di.Object(object()) @@ -295,3 +296,11 @@ class OverrideTests(unittest.TestCase): self.assertIsInstance(self.Catalog.obj(), object) self.assertIsInstance(self.Catalog.another_obj(), object) + + +class AbstractCatalogCompatibilityTest(unittest.TestCase): + """Test backward compatibility with di.AbstractCatalog.""" + + def test_compatibility(self): + """Test that di.AbstractCatalog is available.""" + self.assertIs(di.DeclarativeCatalog, di.AbstractCatalog)