mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-01-30 19:24:31 +03:00
Merge branch 'release/4.0.5' into master
This commit is contained in:
commit
fa81cadf29
42
README.rst
42
README.rst
|
@ -39,8 +39,8 @@
|
|||
:target: https://travis-ci.org/ets-labs/python-dependency-injector
|
||||
:alt: Build Status
|
||||
|
||||
.. image:: http://readthedocs.org/projects/python-dependency-injector/badge/?version=latest
|
||||
:target: http://python-dependency-injector.ets-labs.org/
|
||||
.. image:: https://readthedocs.org/projects/python-dependency-injector/badge/?version=latest
|
||||
:target: https://python-dependency-injector.ets-labs.org/
|
||||
:alt: Docs Status
|
||||
|
||||
.. image:: https://coveralls.io/repos/github/ets-labs/python-dependency-injector/badge.svg?branch=master
|
||||
|
@ -58,20 +58,20 @@ Key features of the ``Dependency Injector``:
|
|||
|
||||
- **Providers**. Provides ``Factory``, ``Singleton``, ``Callable``, ``Coroutine``, ``Object``,
|
||||
``List``, ``Configuration``, ``Dependency`` and ``Selector`` providers that help assembling your
|
||||
objects. See `Providers <http://python-dependency-injector.ets-labs.org/providers/index.html>`_.
|
||||
objects. See `Providers <https://python-dependency-injector.ets-labs.org/providers/index.html>`_.
|
||||
- **Overriding**. Can override any provider by another provider on the fly. This helps in testing
|
||||
and configuring dev / stage environment to replace API clients with stubs etc. See
|
||||
`Provider overriding <http://python-dependency-injector.ets-labs.org/providers/overriding.html>`_.
|
||||
`Provider overriding <https://python-dependency-injector.ets-labs.org/providers/overriding.html>`_.
|
||||
- **Configuration**. Read configuration from ``yaml`` & ``ini`` files, environment variables
|
||||
and dictionaries.
|
||||
See `Configuration provider <http://python-dependency-injector.ets-labs.org/providers/configuration.html>`_.
|
||||
See `Configuration provider <https://python-dependency-injector.ets-labs.org/providers/configuration.html>`_.
|
||||
- **Containers**. Provides declarative and dynamic containers.
|
||||
See `Containers <http://python-dependency-injector.ets-labs.org/containers/index.html>`_.
|
||||
See `Containers <https://python-dependency-injector.ets-labs.org/containers/index.html>`_.
|
||||
- **Wiring**. Injects dependencies into functions and methods. Helps integrating with
|
||||
other frameworks: Django, Flask, Aiohttp, etc.
|
||||
See `Wiring <http://python-dependency-injector.ets-labs.org/wiring.html>`_.
|
||||
See `Wiring <https://python-dependency-injector.ets-labs.org/wiring.html>`_.
|
||||
- **Typing**. Provides typing stubs, ``mypy``-friendly.
|
||||
See `Typing and mypy <http://python-dependency-injector.ets-labs.org/providers/typing_mypy.html>`_.
|
||||
See `Typing and mypy <https://python-dependency-injector.ets-labs.org/providers/typing_mypy.html>`_.
|
||||
- **Performance**. Fast. Written in ``Cython``.
|
||||
- **Maturity**. Mature and production-ready. Well-tested, documented and supported.
|
||||
|
||||
|
@ -130,7 +130,7 @@ This makes easier to understand and change how application works.
|
|||
:target: https://github.com/ets-labs/python-dependency-injector
|
||||
|
||||
Visit the docs to know more about the
|
||||
`Dependency injection and inversion of control in Python <http://python-dependency-injector.ets-labs.org/introduction/di_in_python.html>`_.
|
||||
`Dependency injection and inversion of control in Python <https://python-dependency-injector.ets-labs.org/introduction/di_in_python.html>`_.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
@ -142,30 +142,30 @@ The package is available on the `PyPi`_::
|
|||
Documentation
|
||||
-------------
|
||||
|
||||
The documentation is available on the `Read The Docs <http://python-dependency-injector.ets-labs.org/>`_
|
||||
The documentation is available on the `Read The Docs <https://python-dependency-injector.ets-labs.org/>`_
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Choose one of the following:
|
||||
|
||||
- `Application example (single container) <http://python-dependency-injector.ets-labs.org/examples/application-single-container.html>`_
|
||||
- `Application example (multiple containers) <http://python-dependency-injector.ets-labs.org/examples/application-multiple-containers.html>`_
|
||||
- `Decoupled packages example (multiple containers) <http://python-dependency-injector.ets-labs.org/examples/decoupled-packages.html>`_
|
||||
- `Django example <http://python-dependency-injector.ets-labs.org/examples/django.html>`_
|
||||
- `Flask example <http://python-dependency-injector.ets-labs.org/examples/flask.html>`_
|
||||
- `Aiohttp example <http://python-dependency-injector.ets-labs.org/examples/aiohttp.html>`_
|
||||
- `Sanic example <http://python-dependency-injector.ets-labs.org/examples/sanic.html>`_
|
||||
- `Application example (single container) <https://python-dependency-injector.ets-labs.org/examples/application-single-container.html>`_
|
||||
- `Application example (multiple containers) <https://python-dependency-injector.ets-labs.org/examples/application-multiple-containers.html>`_
|
||||
- `Decoupled packages example (multiple containers) <https://python-dependency-injector.ets-labs.org/examples/decoupled-packages.html>`_
|
||||
- `Django example <https://python-dependency-injector.ets-labs.org/examples/django.html>`_
|
||||
- `Flask example <https://python-dependency-injector.ets-labs.org/examples/flask.html>`_
|
||||
- `Aiohttp example <https://python-dependency-injector.ets-labs.org/examples/aiohttp.html>`_
|
||||
- `Sanic example <https://python-dependency-injector.ets-labs.org/examples/sanic.html>`_
|
||||
|
||||
Tutorials
|
||||
---------
|
||||
|
||||
Choose one of the following:
|
||||
|
||||
- `Flask web application tutorial <http://python-dependency-injector.ets-labs.org/tutorials/flask.html>`_
|
||||
- `Aiohttp REST API tutorial <http://python-dependency-injector.ets-labs.org/tutorials/aiohttp.html>`_
|
||||
- `Asyncio monitoring daemon tutorial <http://python-dependency-injector.ets-labs.org/tutorials/asyncio-daemon.html>`_
|
||||
- `CLI application tutorial <http://python-dependency-injector.ets-labs.org/tutorials/cli.html>`_
|
||||
- `Flask web application tutorial <https://python-dependency-injector.ets-labs.org/tutorials/flask.html>`_
|
||||
- `Aiohttp REST API tutorial <https://python-dependency-injector.ets-labs.org/tutorials/aiohttp.html>`_
|
||||
- `Asyncio monitoring daemon tutorial <https://python-dependency-injector.ets-labs.org/tutorials/asyncio-daemon.html>`_
|
||||
- `CLI application tutorial <https://python-dependency-injector.ets-labs.org/tutorials/cli.html>`_
|
||||
|
||||
Concept
|
||||
-------
|
||||
|
|
|
@ -54,8 +54,8 @@ Dependency Injector --- Dependency injection framework for Python
|
|||
:target: https://travis-ci.org/ets-labs/python-dependency-injector
|
||||
:alt: Build Status
|
||||
|
||||
.. image:: http://readthedocs.org/projects/python-dependency-injector/badge/?version=latest
|
||||
:target: http://python-dependency-injector.ets-labs.org/
|
||||
.. image:: https://readthedocs.org/projects/python-dependency-injector/badge/?version=latest
|
||||
:target: https://python-dependency-injector.ets-labs.org/
|
||||
:alt: Docs Status
|
||||
|
||||
.. image:: https://coveralls.io/repos/github/ets-labs/python-dependency-injector/badge.svg?branch=master
|
||||
|
|
|
@ -7,6 +7,11 @@ that were made in every particular version.
|
|||
From version 0.7.6 *Dependency Injector* framework strictly
|
||||
follows `Semantic versioning`_
|
||||
|
||||
4.0.5
|
||||
-----
|
||||
- Move ``.provided`` attribute to ``providers.Provider``.
|
||||
- Update all links in documentation and examples to use ``https://`` instead of ``http``.
|
||||
|
||||
4.0.4
|
||||
-----
|
||||
- Fix typing stubs for ``container.override()`` method.
|
||||
|
@ -1191,4 +1196,4 @@ Previous versions
|
|||
.. disqus::
|
||||
|
||||
|
||||
.. _Semantic versioning: http://semver.org/
|
||||
.. _Semantic versioning: https://semver.org/
|
||||
|
|
|
@ -35,24 +35,4 @@ You can do nested constructions:
|
|||
:emphasize-lines: 26-32
|
||||
:lines: 3-
|
||||
|
||||
The ``.provided`` attribute is available for the next providers:
|
||||
|
||||
- :py:class:`Factory` and its subclasses
|
||||
- :py:class:`Singleton` and its subclasses
|
||||
- :py:class:`Callable` and its subclasses
|
||||
- :py:class:`Object`
|
||||
- :py:class:`List`
|
||||
- :py:class:`Selector`
|
||||
- :py:class:`Dependency`
|
||||
|
||||
When you create a new provider subclass and want to implement the ``.provided`` attribute, you
|
||||
should use the :py:class:`ProvidedInstance` provider. Add the ``.provided`` property
|
||||
implementation to a new subclass:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
return ProvidedInstance(self)
|
||||
|
||||
.. disqus::
|
||||
|
|
|
@ -304,7 +304,7 @@ and put next into it:
|
|||
|
||||
class GiphyClient:
|
||||
|
||||
API_URL = 'http://api.giphy.com/v1'
|
||||
API_URL = 'https://api.giphy.com/v1'
|
||||
|
||||
def __init__(self, api_key, timeout):
|
||||
self._api_key = api_key
|
||||
|
|
|
@ -738,14 +738,14 @@ You should see:
|
|||
|
||||
Our daemon can monitor `http://example.com <http://example.com>`_ availability.
|
||||
|
||||
Let's add a monitor for the `http://httpbin.org <http://httpbin.org>`_.
|
||||
Let's add a monitor for the `https://httpbin.org <https://httpbin.org>`_.
|
||||
|
||||
Httpbin.org monitor
|
||||
-------------------
|
||||
|
||||
Adding of a monitor for the `httpbin.org`_ will be much easier because we have all the
|
||||
components ready. We just need to create a new provider in the container and update the
|
||||
configuration.
|
||||
Adding of a monitor for the `https://httpbin.org <https://httpbin.org>`_ will be much
|
||||
easier because we have all the components ready. We just need to create a new provider
|
||||
in the container and update the configuration.
|
||||
|
||||
Edit ``containers.py``:
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ How does Movie Lister work?
|
|||
Movie Lister is a naive example from Martin Fowler's article about the dependency injection and
|
||||
inversion of control:
|
||||
|
||||
http://www.martinfowler.com/articles/injection.html
|
||||
https://www.martinfowler.com/articles/injection.html
|
||||
|
||||
Here is a class diagram of the Movie Lister application:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ Aiohttp + Dependency Injector Example
|
|||
=====================================
|
||||
|
||||
This is an `Aiohttp <https://docs.aiohttp.org/>`_ +
|
||||
`Dependency Injector <http://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
`Dependency Injector <https://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
|
||||
The example application is a REST API that searches for funny GIFs on the `Giphy <https://giphy.com/>`_.
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from aiohttp import ClientSession, ClientTimeout
|
|||
|
||||
class GiphyClient:
|
||||
|
||||
API_URL = 'http://api.giphy.com/v1'
|
||||
API_URL = 'https://api.giphy.com/v1'
|
||||
|
||||
def __init__(self, api_key, timeout):
|
||||
self._api_key = api_key
|
||||
|
|
|
@ -2,7 +2,7 @@ Asyncio Daemon + Dependency Injector Example
|
|||
============================================
|
||||
|
||||
This is an `asyncio <https://docs.python.org/3/library/asyncio.html>`_ +
|
||||
`Dependency Injector <http://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
`Dependency Injector <https://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
|
||||
The example application is a daemon that monitors availability of web services.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ Django + Dependency Injector Example
|
|||
====================================
|
||||
|
||||
This is a `Django <https://www.djangoproject.com/>`_ +
|
||||
`Dependency Injector <http://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
`Dependency Injector <https://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
|
||||
The example application helps to search for repositories on the Github.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ Flask + Dependency Injector Example
|
|||
===================================
|
||||
|
||||
This is a `Flask <https://flask.palletsprojects.com/>`_ +
|
||||
`Dependency Injector <http://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
`Dependency Injector <https://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
|
||||
The example application helps to search for repositories on the Github.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ Movie lister - a naive example of dependency injection in Python
|
|||
This is a Python implementation of the dependency injection example from Martin Fowler's
|
||||
article:
|
||||
|
||||
http://www.martinfowler.com/articles/injection.html
|
||||
https://www.martinfowler.com/articles/injection.html
|
||||
|
||||
Run
|
||||
---
|
||||
|
|
|
@ -2,7 +2,7 @@ Sanic + Dependency Injector Example
|
|||
===================================
|
||||
|
||||
This is a `Sanic <https://sanic.readthedocs.io/en/latest/index.html>`_ +
|
||||
`Dependency Injector <http://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
`Dependency Injector <https://python-dependency-injector.ets-labs.org/>`_ example application.
|
||||
|
||||
The example application is a REST API that searches for funny GIFs on the `Giphy <https://giphy.com/>`_.
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from aiohttp import ClientSession, ClientTimeout
|
|||
|
||||
class GiphyClient:
|
||||
|
||||
API_URL = 'http://api.giphy.com/v1'
|
||||
API_URL = 'https://api.giphy.com/v1'
|
||||
|
||||
def __init__(self, api_key, timeout):
|
||||
self._api_key = api_key
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Top-level package."""
|
||||
|
||||
__version__ = '4.0.4'
|
||||
__version__ = '4.0.5'
|
||||
"""Version number.
|
||||
|
||||
:type: str
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,14 +42,14 @@ class Provider(Generic[T]):
|
|||
def delegate(self) -> Provider: ...
|
||||
@property
|
||||
def provider(self) -> Provider: ...
|
||||
@property
|
||||
def provided(self) -> ProvidedInstance: ...
|
||||
def _copy_overridings(self, copied: Provider, memo: Optional[Dict[Any, Any]]) -> None: ...
|
||||
|
||||
|
||||
class Object(Provider, Generic[T]):
|
||||
def __init__(self, provides: T) -> None: ...
|
||||
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
|
||||
@property
|
||||
def provided(self) -> ProvidedInstance: ...
|
||||
|
||||
|
||||
class Delegate(Provider):
|
||||
|
@ -63,8 +63,6 @@ class Dependency(Provider, Generic[T]):
|
|||
def __init__(self, instance_of: Type[T] = object) -> None: ...
|
||||
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
|
||||
@property
|
||||
def provided(self) -> ProvidedInstance: ...
|
||||
@property
|
||||
def instance_of(self) -> Type[T]: ...
|
||||
def provided_by(self, provider: Provider) -> OverridingContext: ...
|
||||
|
||||
|
@ -85,8 +83,6 @@ class Callable(Provider, Generic[T]):
|
|||
@property
|
||||
def provides(self) -> T: ...
|
||||
@property
|
||||
def provided(self) -> ProvidedInstance: ...
|
||||
@property
|
||||
def args(self) -> Tuple[Injection]: ...
|
||||
def add_args(self, *args: Injection) -> Callable[T]: ...
|
||||
def set_args(self, *args: Injection) -> Callable[T]: ...
|
||||
|
@ -173,8 +169,6 @@ class Factory(Provider, Generic[T]):
|
|||
@property
|
||||
def provides(self) -> T: ...
|
||||
@property
|
||||
def provided(self) -> ProvidedInstance: ...
|
||||
@property
|
||||
def args(self) -> Tuple[Injection]: ...
|
||||
def add_args(self, *args: Injection) -> Factory[T]: ...
|
||||
def set_args(self, *args: Injection) -> Factory[T]: ...
|
||||
|
@ -217,8 +211,6 @@ class BaseSingleton(Provider, Generic[T]):
|
|||
@property
|
||||
def cls(self) -> T: ...
|
||||
@property
|
||||
def provided(self) -> ProvidedInstance: ...
|
||||
@property
|
||||
def args(self) -> Tuple[Injection]: ...
|
||||
def add_args(self, *args: Injection) -> Factory[T]: ...
|
||||
def set_args(self, *args: Injection) -> Factory[T]: ...
|
||||
|
@ -266,8 +258,6 @@ class List(Provider):
|
|||
def __init__(self, *args: Injection): ...
|
||||
def __call__(self, *args: Injection, **kwargs: Injection) -> _List[Any]: ...
|
||||
@property
|
||||
def provided(self) -> ProvidedInstance: ...
|
||||
@property
|
||||
def args(self) -> Tuple[Injection]: ...
|
||||
def add_args(self, *args: Injection) -> List: ...
|
||||
def set_args(self, *args: Injection) -> List: ...
|
||||
|
@ -288,8 +278,6 @@ class Selector(Provider):
|
|||
def __call__(self, *args: Injection, **kwargs: Injection) -> Any: ...
|
||||
def __getattr__(self, name: str) -> Provider: ...
|
||||
@property
|
||||
def provided(self) -> ProvidedInstance: ...
|
||||
@property
|
||||
def providers(self) -> Dict[str, Provider]: ...
|
||||
|
||||
|
||||
|
|
|
@ -273,6 +273,11 @@ cdef class Provider(object):
|
|||
"""
|
||||
return Delegate(self)
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
"""Return :py:class:`ProvidedInstance` provider."""
|
||||
return ProvidedInstance(self)
|
||||
|
||||
cpdef object _provide(self, tuple args, dict kwargs):
|
||||
"""Providing strategy implementation.
|
||||
|
||||
|
@ -333,11 +338,6 @@ cdef class Object(Provider):
|
|||
"""
|
||||
return self.__str__()
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
"""Return :py:class:`ProvidedInstance` provider."""
|
||||
return ProvidedInstance(self)
|
||||
|
||||
cpdef object _provide(self, tuple args, dict kwargs):
|
||||
"""Return provided instance.
|
||||
|
||||
|
@ -498,11 +498,6 @@ cdef class Dependency(Provider):
|
|||
"""
|
||||
return self.__str__()
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
"""Return :py:class:`ProvidedInstance` provider."""
|
||||
return ProvidedInstance(self)
|
||||
|
||||
@property
|
||||
def instance_of(self):
|
||||
"""Return class of required dependency."""
|
||||
|
@ -793,11 +788,6 @@ cdef class Callable(Provider):
|
|||
"""Return wrapped callable."""
|
||||
return self.__provides
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
"""Return :py:class:`ProvidedInstance` provider."""
|
||||
return ProvidedInstance(self)
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
"""Return positional argument injections."""
|
||||
|
@ -1651,11 +1641,6 @@ cdef class Factory(Provider):
|
|||
"""Return provided type."""
|
||||
return self.__instantiator.provides
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
"""Return :py:class:`ProvidedInstance` provider."""
|
||||
return ProvidedInstance(self)
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
"""Return positional argument injections."""
|
||||
|
@ -1989,11 +1974,6 @@ cdef class BaseSingleton(Provider):
|
|||
"""Return provided type."""
|
||||
return self.__instantiator.cls
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
"""Return :py:class:`ProvidedInstance` provider."""
|
||||
return ProvidedInstance(self)
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
"""Return positional argument injections."""
|
||||
|
@ -2422,11 +2402,6 @@ cdef class List(Provider):
|
|||
"""
|
||||
return represent_provider(provider=self, provides=list(self.args))
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
"""Return :py:class:`ProvidedInstance` provider."""
|
||||
return ProvidedInstance(self)
|
||||
|
||||
@property
|
||||
def args(self):
|
||||
"""Return positional argument injections."""
|
||||
|
@ -2608,11 +2583,6 @@ cdef class Selector(Provider):
|
|||
address=hex(id(self)),
|
||||
)
|
||||
|
||||
@property
|
||||
def provided(self):
|
||||
"""Return :py:class:`ProvidedInstance` provider."""
|
||||
return ProvidedInstance(self)
|
||||
|
||||
@property
|
||||
def providers(self):
|
||||
"""Return providers."""
|
||||
|
|
6
tests/typing/provider.py
Normal file
6
tests/typing/provider.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from dependency_injector import providers
|
||||
|
||||
|
||||
# Test 1: to check .provided attribute
|
||||
provider1: providers.Provider[int] = providers.Object(1)
|
||||
provided: providers.ProvidedInstance = provider1.provided
|
|
@ -137,3 +137,10 @@ class ProvidedInstancePuzzleTests(unittest.TestCase):
|
|||
'foo-bar',
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class ProvidedInstanceInBaseClassTests(unittest.TestCase):
|
||||
|
||||
def test_provided_attribute(self):
|
||||
provider = providers.Provider()
|
||||
assert isinstance(provider.provided, providers.ProvidedInstance)
|
||||
|
|
Loading…
Reference in New Issue
Block a user