Update docs for declarative catalogs

This commit is contained in:
Roman Mogilatov 2015-11-16 13:28:27 +02:00
parent dc79339cae
commit 9a5e8f4a5a
20 changed files with 176 additions and 59 deletions

View File

@ -330,7 +330,7 @@ class DeclarativeCatalogMetaClass(type):
@six.add_metaclass(DeclarativeCatalogMetaClass)
class DeclarativeCatalog(object):
"""Declarative catalog catalog of providers.
"""Declarative catalog of providers.
``DeclarativeCatalog`` is a catalog of providers that could be defined in
declarative manner. It should cover most of the cases when list of
@ -347,25 +347,27 @@ class DeclarativeCatalog(object):
name = str()
"""Catalog's name.
By default it is catalog's module + class names.
:type: str
"""
cls_providers = dict()
"""Read-only dictionary of current catalog providers.
:type: dict[str, dependency_injector.Provider]
:type: dict[str, :py:class:`dependency_injector.providers.Provider`]
"""
inherited_providers = dict()
"""Read-only dictionary of inherited providers.
:type: dict[str, dependency_injector.Provider]
:type: dict[str, :py:class:`dependency_injector.providers.Provider`]
"""
providers = dict()
"""Read-only dictionary of all providers.
:type: dict[str, dependency_injector.Provider]
:type: dict[str, :py:class:`dependency_injector.providers.Provider`]
"""
overridden_by = tuple()
@ -384,8 +386,8 @@ class DeclarativeCatalog(object):
last_overriding = None
"""Read-only reference to the last overriding catalog, if any.
:type: dependency_injector.DeclarativeCatalog |
dependency_injector.DynamicCatalog
:type: :py:class:`dependency_injector.catalogs.DeclarativeCatalog` |
:py:class:`dependency_injector.catalogs.DynamicCatalog` | None
"""
_catalog = DynamicCatalog
@ -396,8 +398,8 @@ class DeclarativeCatalog(object):
def is_bundle_owner(cls, bundle):
"""Check if catalog is bundle owner.
:param bundle: Catalog's bundle
:type bundle: dependency_injector.CatalogBundle
:param bundle: Catalog's bundle instance
:type bundle: :py:class:`dependency_injector.catalogs.CatalogBundle`
:rtype: bool
"""
@ -408,9 +410,9 @@ class DeclarativeCatalog(object):
"""Return provider's name in catalog.
:param provider: Provider instance
:type provider: dependency_injector.Provider
:type provider: :py:class:`dependency_injector.providers.Provider`
:raise: dependency_injector.UndefinedProviderError
:raise: :py:class:`dependency_injector.errors.UndefinedProviderError`
:return: Provider's name
:rtype: str
@ -422,7 +424,7 @@ class DeclarativeCatalog(object):
"""Check if provider is bound to the catalog.
:param provider: Provider instance
:type provider: dependency_injector.Provider
:type provider: :py:class:`dependency_injector.providers.Provider`
:rtype: bool
"""
@ -433,7 +435,7 @@ class DeclarativeCatalog(object):
"""Return dict of providers, that are instance of provided type.
:param provider_type: Provider type
:type provider_type: dependency_injector.Provider
:type provider: :py:class:`dependency_injector.providers.Provider`
"""
return cls._catalog.filter(provider_type)
@ -442,8 +444,9 @@ class DeclarativeCatalog(object):
"""Override current catalog providers by overriding catalog providers.
:param overriding: Overriding catalog
:type overriding: dependency_injector.DeclarativeCatalog |
dependency_injector.DynamicCatalog
:type overriding:
:py:class:`dependency_injector.catalogs.DeclarativeCatalog` |
:py:class:`dependency_injector.catalogs.DynamicCatalog`
:rtype: None
"""
@ -472,13 +475,15 @@ class DeclarativeCatalog(object):
:param name: Provider's name
:type name: str
:raise: dependency_injector.UndefinedProviderError
:raise: :py:class:`dependency_injector.errors.UndefinedProviderError`
:return: Provider with specified name
:rtype: dependency_injector.providers.Provider
:rtype: :py:class:`dependency_injector.providers.Provider`
"""
return cls._catalog.get_provider(name)
get = get_provider # Backward compatibility for versions < 0.11.*
@classmethod
def bind_provider(cls, name, provider):
"""Bind provider to catalog with specified name.
@ -487,9 +492,9 @@ class DeclarativeCatalog(object):
:type name: str
:param provider: Provider instance
:type provider: dependency_injector.Provider
:type provider: :py:class:`dependency_injector.providers.Provider`
:raise: dependency_injector.Error
:raise: :py:class:`dependency_injector.errors.Error`
:rtype: None
"""
@ -501,9 +506,10 @@ class DeclarativeCatalog(object):
:param providers: Dictionary of providers, where key is a name
and value is a provider
:type providers: dict[str, dependency_injector.Provider]
:type providers:
dict[str, :py:class:`dependency_injector.providers.Provider`]
:raise: dependency_injector.Error
:raise: :py:class:`dependency_injector.errors.Error`
:rtype: None
"""
@ -521,6 +527,8 @@ class DeclarativeCatalog(object):
"""
return hasattr(cls, name)
has = has_provider # Backward compatibility for versions < 0.11.*
@classmethod
def unbind_provider(cls, name):
"""Remove provider binding.
@ -532,8 +540,48 @@ class DeclarativeCatalog(object):
"""
delattr(cls, name)
get = get_provider # Backward compatibility for versions < 0.11.*
has = has_provider # Backward compatibility for versions < 0.11.*
@classmethod
def __getattr__(cls, name):
"""Return provider with specified name or raise en error.
:param name: Attribute's name
:type name: str
:raise: :py:class:`dependency_injector.errors.UndefinedProviderError`
"""
raise NotImplementedError('Implementated in metaclass')
@classmethod
def __setattr__(cls, name, value):
"""Handle setting of catalog attributes.
Setting of attributes works as usual, but if value of attribute is
provider, this provider will be bound to catalog.
:param name: Attribute's name
:type name: str
:param value: Attribute's value
:type value: :py:class:`dependency_injector.providers.Provider` |
object
:rtype: None
"""
raise NotImplementedError('Implementated in metaclass')
@classmethod
def __delattr__(cls, name):
"""Handle deleting of catalog attibute.
Deleting of attributes works as usual, but if value of attribute is
provider, this provider will be unbound from catalog.
:param name: Attribute's name
:type name: str
:rtype: None
"""
raise NotImplementedError('Implementated in metaclass')
# Backward compatibility for versions < 0.11.*

View File

@ -39,7 +39,7 @@ class Injection(object):
return self.injectable
class NamedInjection(Injection):
class _NamedInjection(Injection):
"""Base class of named injections."""
__slots__ = ('name',)
@ -47,7 +47,7 @@ class NamedInjection(Injection):
def __init__(self, name, injectable):
"""Initializer."""
self.name = name
super(NamedInjection, self).__init__(injectable)
super(_NamedInjection, self).__init__(injectable)
class Arg(Injection):
@ -56,19 +56,19 @@ class Arg(Injection):
__IS_ARG_INJECTION__ = True
class KwArg(NamedInjection):
class KwArg(_NamedInjection):
"""Keyword argument injection."""
__IS_KWARG_INJECTION__ = True
class Attribute(NamedInjection):
class Attribute(_NamedInjection):
"""Attribute injection."""
__IS_ATTRIBUTE_INJECTION__ = True
class Method(NamedInjection):
class Method(_NamedInjection):
"""Method injection."""
__IS_METHOD_INJECTION__ = True

View File

@ -3,5 +3,5 @@
.. automodule:: dependency_injector.catalogs
:members:
:special-members:
:member-order: bysource
:special-members:

View File

@ -1,12 +1,11 @@
API
===
API Documentation
=================
.. toctree::
:maxdepth: 2
top_level
providers
injections
catalogs
errors
utils
errors

7
docs/api/injections.rst Normal file
View File

@ -0,0 +1,7 @@
``dependency_injector.injections``
----------------------------------
.. automodule:: dependency_injector.injections
:members:
:member-order: bysource
:inherited-members:

View File

@ -3,6 +3,4 @@
.. automodule:: dependency_injector.providers
:members:
:special-members:
:private-members:
:member-order: bysource

View File

@ -2,5 +2,3 @@
-----------------------
.. automodule:: dependency_injector
:members:
:special-members:

View File

@ -3,3 +3,4 @@
.. automodule:: dependency_injector.utils
:members:
:member-order: bysource

View File

@ -1,17 +1,27 @@
Declarative catalogs
--------------------
:py:class:`dependency_injector.catalogs.DeclarativeCatalog` is a catalog of
providers that could be defined in declarative manner. It should cover most
of the cases when list of providers that would be included in catalog is
deterministic (catalog will not change its structure in runtime).
.. module:: dependency_injector.catalogs
:py:class:`DeclarativeCatalog` is a catalog of providers that could be
defined in declarative manner. It should cover most of the cases when
list of providers that would be included in catalog is deterministic
(catalog will not change its structure in runtime).
Declarative catalogs have to extend base declarative catalog class -
:py:class:`dependency_injector.catalogs.DeclarativeCatalog`.
Providers have to be defined like catalog's class attributes. Every provider in
catalog has name. This name should follow ``some_provider`` convention,
that is standard naming convention for attribute names in Python.
Declarative catalog's providers have to be defined like catalog's class
attributes. Every provider in catalog has name. This name should follow
``some_provider`` convention, that is standard naming convention for
attribute names in Python.
.. note::
Declarative catalogs have several features that could be useful
for some kind of operations on catalog's providers, please visit API
documentation for getting full list of features -
:py:class:`dependency_injector.catalogs.DeclarativeCatalog`.
.. note::
@ -31,16 +41,20 @@ Here is an simple example of declarative catalog with several factories:
.. literalinclude:: ../../examples/catalogs/declarative.py
:language: python
:py:class:`dependency_injector.catalogs.DeclarativeCatalog` has several
features that could be useful for some kind of operations on catalog's
providers (please visit API docs for getting full list of feautes -
:py:class:`dependency_injector.catalogs.DeclarativeCatalog`):
Example of declarative catalogs inheritance:
Example:
.. image:: /images/catalogs/declarative_api.png
.. image:: /images/catalogs/declarative_inheritance.png
:width: 100%
:align: center
.. literalinclude:: ../../examples/catalogs/declarative_api.py
.. literalinclude:: ../../examples/catalogs/declarative_inheritance.py
:language: python
Example of declarative catalog's provider injections:
.. image:: /images/catalogs/declarative_injections.png
:width: 100%
:align: center
.. literalinclude:: ../../examples/catalogs/declarative_injections.py
:language: python

View File

@ -1,2 +1,4 @@
Dynamic catalogs
----------------
.. module:: dependency_injector.catalogs

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View File

@ -1,4 +1,4 @@
"""Declarative catalog example."""
"""Declarative catalog simple example."""
from dependency_injector import catalogs
from dependency_injector import providers

View File

@ -1,4 +1,4 @@
"""Declarative catalog API example."""
"""Declarative catalogs inheritance example."""
from dependency_injector import catalogs
from dependency_injector import providers

View File

@ -0,0 +1,50 @@
"""Declarative catalog's provider injections example."""
import sqlite3
from dependency_injector import catalogs
from dependency_injector import providers
class UsersService(object):
"""Users service, that has dependency on database."""
def __init__(self, db):
"""Initializer."""
self.db = db
class AuthService(object):
"""Auth service, that has dependencies on users service and database."""
def __init__(self, db, users_service):
"""Initializer."""
self.db = db
self.users_service = users_service
class Services(catalogs.DeclarativeCatalog):
"""Catalog of service providers."""
database = providers.Singleton(sqlite3.connect, ':memory:')
""":type: providers.Provider -> sqlite3.Connection"""
users = providers.Factory(UsersService,
db=database)
""":type: providers.Provider -> UsersService"""
auth = providers.Factory(AuthService,
db=database,
users_service=users)
""":type: providers.Provider -> AuthService"""
# Retrieving catalog providers:
users_service = Services.users()
auth_service = Services.auth()
# Making some asserts:
assert users_service.db is auth_service.db is Services.database()
assert isinstance(auth_service.users_service, UsersService)
assert users_service is not Services.users()
assert auth_service is not Services.auth()