From bef0a952b5690750c786ffb26fb050fcc996edee Mon Sep 17 00:00:00 2001 From: Roman Mogilatov Date: Mon, 16 May 2016 11:18:00 +0300 Subject: [PATCH] Fix bug with accessing declarative catalog attributes from instance level --- dependency_injector/catalogs/declarative.py | 139 ++++++++++++-------- docs/main/changelog.rst | 1 + tests/catalogs/test_declarative.py | 29 ++++ 3 files changed, 111 insertions(+), 58 deletions(-) diff --git a/dependency_injector/catalogs/declarative.py b/dependency_injector/catalogs/declarative.py index c6fa485d..5ba031cf 100644 --- a/dependency_injector/catalogs/declarative.py +++ b/dependency_injector/catalogs/declarative.py @@ -44,8 +44,8 @@ class DeclarativeCatalogMetaClass(type): cls._catalog.name = '.'.join((cls.__module__, cls.__name__)) cls._catalog.bind_providers(dict(providers)) - cls.cls_providers = dict(cls_providers) - cls.inherited_providers = dict(inherited_providers) + cls._cls_providers = dict(cls_providers) + cls._inherited_providers = dict(inherited_providers) cls.Bundle = cls._catalog.Bundle @@ -69,6 +69,22 @@ class DeclarativeCatalogMetaClass(type): """ return cls._catalog.providers + @property + def cls_providers(cls): + """Read-only dictionary of current catalog providers. + + :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`] + """ + return cls._cls_providers + + @property + def inherited_providers(cls): + """Read-only dictionary of inherited providers. + + :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`] + """ + return cls._inherited_providers + @property def overridden_by(cls): """Tuple of overriding catalogs. @@ -177,52 +193,6 @@ class DeclarativeCatalog(object): :type: :py:class:`CatalogBundle` - .. py:attribute:: name - - Read-only property that represents catalog's name. - - Catalog's name is catalog's module + catalog's class name. - - :type: str - - .. py:attribute:: cls_providers - - Read-only dictionary of current catalog providers. - - :type: dict[str, :py:class:`dependency_injector.providers.Provider`] - - .. py:attribute:: inherited_providers - - Read-only dictionary of inherited providers. - - :type: dict[str, :py:class:`dependency_injector.providers.Provider`] - - .. py:attribute:: providers - - Read-only dictionary of all providers. - - :type: dict[str, :py:class:`dependency_injector.providers.Provider`] - - .. py:attribute:: overridden_by - - Tuple of overriding catalogs. - - :type: tuple[:py:class:`DeclarativeCatalog` | - :py:class:`DynamicCatalog`] - - .. py:attribute:: is_overridden - - Read-only property that is set to ``True`` if catalog is overridden. - - :type: bool - - .. py:attribute:: is_overridden - - Read-only reference to the last overriding catalog, if any. - - :type: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog` | - None - .. py:attribute:: provider_type If provider type is defined, :py:class:`DeclarativeCatalog` checks that @@ -234,22 +204,75 @@ class DeclarativeCatalog(object): Bundle = CatalogBundle - name = str() - - cls_providers = dict() - inherited_providers = dict() - providers = dict() - - overridden_by = tuple() - is_overridden = bool - last_overriding = None - provider_type = None _catalog = DynamicCatalog + _cls_providers = dict() + _inherited_providers = dict() + __IS_CATALOG__ = True + @property + def name(self): + """Read-only property that represents catalog's name. + + Catalog's name is catalog's module + catalog's class name. + + :rtype: str + """ + return self.__class__.name + + @property + def providers(self): + """Read-only dictionary of all providers. + + :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`] + """ + return self.__class__.providers + + @property + def cls_providers(self): + """Read-only dictionary of current catalog providers. + + :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`] + """ + return self.__class__.cls_providers + + @property + def inherited_providers(self): + """Read-only dictionary of inherited providers. + + :rtype: dict[str, :py:class:`dependency_injector.providers.Provider`] + """ + return self.__class__.inherited_providers + + @property + def overridden_by(self): + """Tuple of overriding catalogs. + + :rtype: tuple[:py:class:`DeclarativeCatalog` | + :py:class:`DynamicCatalog`] + """ + return self.__class__.overridden_by + + @property + def is_overridden(self): + """Read-only property that is set to ``True`` if catalog is overridden. + + :rtype: bool + """ + return self.__class__.is_overridden + + @property + def last_overriding(self): + """Read-only reference to the last overriding catalog, if any. + + :rtype: :py:class:`DeclarativeCatalog` | :py:class:`DynamicCatalog` | + None + """ + return self.__class__.last_overriding + @classmethod def is_bundle_owner(cls, bundle): """Check if catalog is bundle owner. diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 5726767f..32f9882d 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -16,6 +16,7 @@ Development version - Add ``add_injections()`` method to ``Callable``, ``DelegatedCallable``, ``Factory``, ``DelegatedFactory``, ``Singleton`` and ``DelegatedSingleton`` providers. +- Fix bug with accessing to declarative catalog attributes from instance level. 1.16.8 ------ diff --git a/tests/catalogs/test_declarative.py b/tests/catalogs/test_declarative.py index dcd8243c..6a35b0e4 100644 --- a/tests/catalogs/test_declarative.py +++ b/tests/catalogs/test_declarative.py @@ -428,3 +428,32 @@ class CopyingTests(unittest.TestCase): self.assertEqual(CatalogA1.p13(), 11) self.assertEqual(CatalogA2.p13(), 22) + + +class InstantiationTests(unittest.TestCase): + """Declarative catalogs instantiation tests.""" + + def setUp(self): + """Set test environment up.""" + self.catalog = CatalogA() + + def tearDown(self): + """Tear test environment down.""" + self.catalog = None + + def test_access_instance_attributes(self): + """Test accessing declarative catalog instance attributes.""" + self.assertEqual(self.catalog.name, + CatalogA.name) + self.assertEqual(self.catalog.providers, + CatalogA.providers) + self.assertEqual(self.catalog.cls_providers, + CatalogA.cls_providers) + self.assertEqual(self.catalog.inherited_providers, + CatalogA.inherited_providers) + self.assertEqual(self.catalog.overridden_by, + CatalogA.overridden_by) + self.assertEqual(self.catalog.is_overridden, + CatalogA.is_overridden) + self.assertEqual(self.catalog.last_overriding, + CatalogA.last_overriding)