Merge branch 'release/4.0.5' into master

This commit is contained in:
Roman Mogylatov 2020-10-19 17:35:26 -04:00
commit fa81cadf29
21 changed files with 3516 additions and 3978 deletions

View File

@ -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
-------

View File

@ -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

View File

@ -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/

View File

@ -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::

View File

@ -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

View File

@ -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``:

View File

@ -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:

View File

@ -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/>`_.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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
---

View File

@ -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/>`_.

View File

@ -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

View File

@ -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

View File

@ -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]: ...

View File

@ -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
View 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

View File

@ -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)