Typing stubs (#286)

* Add basic setup

* Add more tests for factory

* Add mypy checks to CI

* Add mypy checks to makefile command

* Add typing for the factories

* Add stub for Callable providers

* Add typing module and object provider stubs

* Fix typing test issue

* Remove typing module

* Add Delegate stub

* Add stub for Dependency provider

* Add stub for ExternalDependency

* Add stubs for providers module functions

* Add stubs for the DependenciesContainer provider

* Add stub for the CallableDelegate provider

* Add stubs for Coroutine providers

* Add stubs for the configuration options

* Add stub for the FactoryDelegate

* Add stub for the FactoryAggregate provider

* Add singleton stubs

* Add stubs for singletons

* Add stub for the List provider

* Add stub for the Container provider

* Add stub for the Selector provider

* Add stubs for the dynamic container

* Add stub for the declarative container

* Add stubs for the extensions

* Add types module for explicit provider typing

* Set absolute import mode for the providers module and add types module test

* Skip typing test for Python 3.5

* Remove coroutine test from py35

* Fix py35 tests

* Add \n to the tox.ini
This commit is contained in:
Roman Mogylatov 2020-08-26 22:24:20 -04:00 committed by GitHub
parent 47f4279ccd
commit 2e940adb50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 4863 additions and 4037 deletions

View File

@ -22,6 +22,10 @@ jobs:
env: TOXENV=pydocstyle env: TOXENV=pydocstyle
install: pip install tox install: pip install tox
script: tox script: tox
- python: 3.6
env: TOXENV=mypy
install: pip install tox
script: tox
- python: 2.7 - python: 2.7
env: TOXENV=py27 env: TOXENV=py27
install: pip install tox install: pip install tox

View File

@ -1,4 +1,4 @@
recursive-include src/dependency_injector *.py *.pyx *.pxd *.c recursive-include src/dependency_injector *.py* *.c
recursive-include tests *.py recursive-include tests *.py
include README.rst include README.rst
include CONTRIBUTORS.rst include CONTRIBUTORS.rst
@ -6,3 +6,4 @@ include LICENSE.rst
include requirements.txt include requirements.txt
include setup.py include setup.py
include tox.ini include tox.ini
include py.typed

View File

@ -60,13 +60,14 @@ test-py3: build
coverage html --rcfile=./.coveragerc coverage html --rcfile=./.coveragerc
check: check:
# Static analysis
flake8 src/dependency_injector/ flake8 src/dependency_injector/
flake8 examples/ flake8 examples/
# Code style analysis
pydocstyle src/dependency_injector/ pydocstyle src/dependency_injector/
pydocstyle examples/ pydocstyle examples/
mypy tests/typing
test-publish: cythonize test-publish: cythonize
# Create distributions # Create distributions
python setup.py sdist python setup.py sdist

View File

@ -6,5 +6,6 @@ flake8
pydocstyle pydocstyle
sphinx_autobuild sphinx_autobuild
pip pip
mypy
-r requirements-ext.txt -r requirements-ext.txt

View File

@ -1,3 +1,7 @@
[flake8] [flake8]
max_line_length = 99 max_line_length = 100
max_complexity = 10 max_complexity = 10
exclude = types.py
[pydocstyle]
ignore = D100,D101,D102,D105,D106,D107,D203,D213

View File

@ -47,7 +47,7 @@ setup(name='dependency-injector',
'': 'src', '': 'src',
}, },
package_data={ package_data={
'dependency_injector': ['*.pxd'], 'dependency_injector': ['*.pxd', '*.pyi', 'py.typed'],
}, },
ext_modules=[ ext_modules=[
Extension('dependency_injector.containers', Extension('dependency_injector.containers',

View File

View File

@ -0,0 +1,34 @@
from typing import Type, Dict, Tuple, Optional, Any, Union, ClassVar, Callable as _Callable
from .providers import Provider
class Container:
provider_type: Type[Provider] = Provider
providers: Dict[str, Provider]
overridden: Tuple[Provider]
def __init__(self) -> None: ...
def __deepcopy__(self, memo: Optional[Dict[str, Any]]) -> Provider: ...
def __setattr__(self, name: str, value: Union[Provider, Any]) -> None: ...
def __delattr__(self, name: str) -> None: ...
def set_providers(self, **providers: Provider): ...
def override(self, overriding: DynamicContainer) -> None: ...
def override_providers(self, **overriding_providers: Provider) -> None: ...
def reset_last_overriding(self) -> None: ...
def reset_override(self) -> None: ...
class DynamicContainer(Container): ...
class DeclarativeContainer(Container):
cls_providers: ClassVar[Dict[str, Provider]]
inherited_providers: ClassVar[Dict[str, Provider]]
def override(container: Container) -> _Callable[[Container], Container]: ...
def copy(container: Container) -> _Callable[[Container], Container]: ...
def is_container(instance: Any) -> bool: ...

View File

View File

@ -0,0 +1,23 @@
from typing import Awaitable as _Awaitable
from dependency_injector import providers
class Application(providers.Singleton): ...
class Extension(providers.Singleton): ...
class Middleware(providers.DelegatedCallable): ...
class MiddlewareFactory(providers.Factory): ...
class View(providers.Callable):
def as_view(self) -> _Awaitable: ...
class ClassBasedView(providers.Factory):
def as_view(self) -> _Awaitable: ...

View File

@ -0,0 +1,24 @@
from typing import Union, Optional, Callable as _Callable, Any
from flask import request as flask_request
from dependency_injector import providers
request: providers.Object[flask_request]
class Application(providers.Singleton): ...
class Extension(providers.Singleton): ...
class View(providers.Callable):
def as_view(self) -> _Callable[..., Any]: ...
class ClassBasedView(providers.Factory):
def as_view(self, name: str) -> _Callable[..., Any]: ...
def as_view(provider: Union[View, ClassBasedView], name: Optional[str] = None) -> _Callable[..., Any]: ...

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,321 @@
from __future__ import annotations
from typing import (
TypeVar,
Generic,
Type,
Callable as _Callable,
Any,
Tuple,
List as _List,
Optional,
Dict,
Union,
Coroutine as _Coroutine,
)
from .types import Provider as _Provider
Injection = Any
T = TypeVar('T')
class OverridingContext:
def __init__(self, overridden: Provider, overriding: Provider): ...
def __enter__(self) -> Provider: ...
def __exit__(self, *_: Any) -> None: ...
class Provider(_Provider):
def __init__(self) -> None: ...
def __call__(self, *args: Injection, **kwargs: Injection) -> Any: ...
def __deepcopy__(self, memo: Optional[Dict[str, Any]]) -> Provider: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
@property
def overridden(self) -> Tuple[Provider]: ...
@property
def last_overriding(self) -> Optional[Provider]: ...
def override(self, provider: Union[Provider, Any]) -> OverridingContext: ...
def reset_last_overriding(self) -> None: ...
def reset_override(self) -> None: ...
def delegate(self) -> Provider: ...
@property
def provider(self) -> Provider: ...
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):
def __init__(self, provides: Provider) -> None: ...
def __call__(self, *args: Injection, **kwargs: Injection) -> Provider: ...
class Dependency(Provider, Generic[T]):
def __init__(self, instance_of: Type[T]) -> 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: ...
class ExternalDependency(Dependency): ...
class DependenciesContainer(Object):
def __init__(self, **dependencies: Provider) -> None: ...
def __getattr__(self, name: str) -> Provider: ...
@property
def providers(self) -> Dict[str, Provider]: ...
class Callable(Provider, Generic[T]):
def __init__(self, provides: _Callable[..., T], *args: Injection, **kwargs: Injection) -> None: ...
def __call__(self, *args: Injection, **kwargs: Injection) -> 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]: ...
def clear_args(self) -> Callable[T]: ...
@property
def kwargs(self) -> Dict[str, Injection]: ...
def add_kwargs(self, **kwargs: Injection) -> Callable[T]: ...
def set_kwargs(self, **kwargs: Injection) -> Callable[T]: ...
def clear_kwargs(self) -> Callable[T]: ...
class DelegatedCallable(Callable): ...
class AbstractCallable(Callable):
def override(self, provider: Callable) -> OverridingContext: ...
class CallableDelegate(Delegate):
def __init__(self, callable: Callable) -> None: ...
class Coroutine(Callable): ...
class DelegatedCoroutine(Coroutine): ...
class AbstractCoroutine(Coroutine):
def override(self, provider: Coroutine) -> OverridingContext: ...
class CoroutineDelegate(Delegate):
def __init__(self, coroutine: Coroutine) -> None: ...
class ConfigurationOption(Provider):
UNDEFINED: object
def __init__(self, name: str, root: Configuration) -> None: ...
def __call__(self, *args: Injection, **kwargs: Injection) -> Any: ...
def __getattr__(self, item: str) -> ConfigurationOption: ...
def __getitem__(self, item: str) -> ConfigurationOption: ...
def get_name(self) -> str: ...
def as_int(self) -> Callable[int]: ...
def as_float(self) -> Callable[float]: ...
def as_(self, callback: _Callable[..., T], *args: Injection, **kwargs: Injection) -> Callable[T]: ...
def update(self, value: Any) -> None: ...
def from_ini(self, filepath: str) -> None: ...
def from_yaml(self, filepath: str) -> None: ...
def from_dict(self, options: Dict[str, Any]) -> None: ...
def from_env(self, name: str, default: Optional[Any] = None) -> None: ...
class Configuration(Object):
DEFAULT_NAME: str = 'config'
def __init__(self, name: str = DEFAULT_NAME, default: Optional[Any] = None) -> None: ...
def __getattr__(self, item: str) -> ConfigurationOption: ...
def __getitem__(self, item: str) -> ConfigurationOption: ...
def get_name(self) -> str: ...
def get(self, selector: str) -> Any: ...
def set(self, selector: str, value: Any) -> OverridingContext: ...
def reset_cache(self) -> None: ...
def update(self, value: Any) -> None: ...
def from_ini(self, filepath: str) -> None: ...
def from_yaml(self, filepath: str) -> None: ...
def from_dict(self, options: Dict[str, Any]) -> None: ...
def from_env(self, name: str, default: Optional[Any] = None) -> None: ...
class Factory(Provider, Generic[T]):
provided_type: Optional[Type]
def __init__(self, provides: _Callable[..., T], *args: Injection, **kwargs: Injection) -> None: ...
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
@property
def cls(self) -> 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]: ...
def clear_args(self) -> Factory[T]: ...
@property
def kwargs(self) -> Dict[str, Injection]: ...
def add_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
def set_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
def clear_kwargs(self) -> Factory[T]: ...
@property
def attributes(self) -> Dict[str, Injection]: ...
def add_attributes(self, **kwargs: Injection) -> Factory[T]: ...
def set_attributes(self, **kwargs: Injection) -> Factory[T]: ...
def clear_attributes(self) -> Factory[T]: ...
class DelegatedFactory(Factory): ...
class AbstractFactory(Factory):
def override(self, provider: Factory) -> OverridingContext: ...
class FactoryDelegate(Delegate):
def __init__(self, factory: Factory): ...
class FactoryAggregate(Provider):
def __init__(self, **factories: Factory): ...
def __call__(self, factory_name: str, *args: Injection, **kwargs: Injection) -> Any: ...
def __getattr__(self, factory_name: str) -> Factory: ...
@property
def factories(self) -> Dict[str, Factory]: ...
class BaseSingleton(Provider, Generic[T]):
provided_type = Optional[Type]
def __init__(self, provides: _Callable[..., T], *args: Injection, **kwargs: Injection) -> None: ...
def __call__(self, *args: Injection, **kwargs: Injection) -> 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]: ...
def clear_args(self) -> Factory[T]: ...
@property
def kwargs(self) -> Dict[str, Injection]: ...
def add_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
def set_kwargs(self, **kwargs: Injection) -> Factory[T]: ...
def clear_kwargs(self) -> Factory[T]: ...
@property
def attributes(self) -> Dict[str, Injection]: ...
def add_attributes(self, **kwargs: Injection) -> Factory[T]: ...
def set_attributes(self, **kwargs: Injection) -> Factory[T]: ...
def clear_attributes(self) -> Factory[T]: ...
def reset(self) -> None: ...
class Singleton(BaseSingleton): ...
class DelegatedSingleton(Singleton): ...
class ThreadSafeSingleton(Singleton): ...
class DelegatedThreadSafeSingleton(ThreadSafeSingleton): ...
class ThreadLocalSingleton(BaseSingleton): ...
class DelegatedThreadLocalSingleton(ThreadLocalSingleton): ...
class AbstractSingleton(BaseSingleton):
def override(self, provider: BaseSingleton) -> OverridingContext: ...
class SingletonDelegate(Delegate):
def __init__(self, factory: BaseSingleton): ...
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: ...
def clear_args(self) -> List: ...
class Container(Provider):
def __init__(self, container_cls: Type[T], container: Optional[T] = None, **overriding_providers: Provider) -> None: ...
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...
def __getattr__(self, name: str) -> Provider: ...
class Selector(Provider):
def __init__(self, selector: _Callable[..., Any], **providers: 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]: ...
class ProvidedInstanceFluentInterface:
def __getattr__(self, item: str) -> AttributeGetter: ...
def __getitem__(self, item: str) -> ItemGetter: ...
def call(self, *args: Injection, **kwargs: Injection) -> MethodCaller: ...
class ProvidedInstance(Provider, ProvidedInstanceFluentInterface):
def __init__(self, provider: Provider) -> None: ...
class AttributeGetter(Provider, ProvidedInstanceFluentInterface):
def __init__(self, provider: Provider, attribute: str) -> None: ...
class ItemGetter(Provider, ProvidedInstanceFluentInterface):
def __init__(self, provider: Provider, item: str) -> None: ...
class MethodCaller(Provider, ProvidedInstanceFluentInterface):
def __init__(self, provider: Provider, *args: Injection, **kwargs: Injection) -> None: ...
def is_provider(instance: Any) -> bool: ...
def ensure_is_provider(instance: Any) -> Provider: ...
def is_delegated(instance: Any) -> bool: ...
def represent_provider(provider: Provider, provides: Any) -> str: ...
def deepcopy(instance: Any, memo: Optional[Dict[str, Any]]): Any: ...
def merge_dicts(dict1: Dict[Any, Any], dict2: Dict[Any, Any]) -> Dict[Any, Any]: ...

View File

@ -3,6 +3,8 @@
Powered by Cython. Powered by Cython.
""" """
from __future__ import absolute_import
import copy import copy
import os import os
import re import re

View File

View File

@ -0,0 +1,9 @@
from typing import TypeVar, Generic, Any
Injection = Any
T = TypeVar('T')
class Provider(Generic[T]):
def __call__(self, *args: Injection, **kwargs: Injection) -> T: ...

52
tests/typing/callable.py Normal file
View File

@ -0,0 +1,52 @@
from typing import Tuple, Any, Dict
from dependency_injector import providers
class Animal:
...
class Cat(Animal):
@classmethod
def create(cls) -> Animal:
return cls()
# Test 1: to check the return type (class)
provider1 = providers.Callable(Cat)
animal1: Animal = provider1(1, 2, 3, b='1', c=2, e=0.0)
# Test 2: to check the return type (class factory method)
provider2 = providers.Callable(Cat.create)
animal2: Animal = provider2()
# Test 3: to check the .override() method
provider3 = providers.Callable(Animal)
with provider3.override(providers.Callable(Cat)):
provider3()
# Test 4: to check the .args & .kwargs attributes
provider4 = providers.Callable(Animal)
args4: Tuple[Any] = provider4.args
kwargs4: Dict[str, Any] = provider4.kwargs
# Test 5: to check the provided instance interface
provider5 = providers.Callable(Animal)
provided5: providers.ProvidedInstance = provider5.provided
attr_getter5: providers.AttributeGetter = provider5.provided.attr
item_getter5: providers.ItemGetter = provider5.provided['item']
method_caller: providers.MethodCaller = provider5.provided.method.call(123, arg=324)
# Test 6: to check the DelegatedCallable
provider6 = providers.DelegatedCallable(Cat)
animal6: Animal = provider6(1, 2, 3, b='1', c=2, e=0.0)
# Test 7: to check the AbstractCallable
provider7 = providers.AbstractCallable(Animal)
provider7.override(providers.Callable(Cat))
animal7: Animal = provider7(1, 2, 3, b='1', c=2, e=0.0)
# Test 8: to check the CallableDelegate __init__
provider8 = providers.CallableDelegate(providers.Callable(lambda: None))

View File

@ -0,0 +1,19 @@
from dependency_injector import providers
# Test 1: to check the getattr
config1 = providers.Configuration()
provider1 = providers.Factory(dict, a=config1.a)
# Test 2: to check the from_*() method
config2 = providers.Configuration()
config2.from_dict({})
config2.from_ini('config.ini')
config2.from_yaml('config.yml')
config2.from_env('ENV', 'default')
# Test 3: to check as_*() methods
config3 = providers.Configuration()
int3: providers.Callable[int] = config3.option.as_int()
float3: providers.Callable[float] = config3.option.as_float()
int3_custom: providers.Callable[int] = config3.option.as_(int)

14
tests/typing/container.py Normal file
View File

@ -0,0 +1,14 @@
from dependency_injector import providers
class Container:
...
# Test 1: to check the return type
provider1 = providers.Container(Container)
var1: Container = provider1()
# Test 2: to check the getattr
provider2 = providers.Container(Container)
attr: providers.Provider = provider2.attr

11
tests/typing/coroutine.py Normal file
View File

@ -0,0 +1,11 @@
from typing import Coroutine
from dependency_injector import providers
async def _coro() -> None:
...
# Test 1: to check the return type
provider1 = providers.Coroutine(_coro)
var1: Coroutine = provider1()

View File

@ -0,0 +1,12 @@
from dependency_injector import containers, providers
# Test 1: to check declarative container subclass
class Container1(containers.DeclarativeContainer):
provider = providers.Factory(int)
container1 = Container1()
container1_type: containers.Container = Container1()
provider1: providers.Provider = container1.provider
val1: int = container1.provider(3)

6
tests/typing/delegate.py Normal file
View File

@ -0,0 +1,6 @@
from dependency_injector import providers
# Test 1: to check the return type
provider1 = providers.Delegate(providers.Provider())
var1: providers.Provider = provider1()

View File

@ -0,0 +1,10 @@
from dependency_injector import providers
# Test 1: to check the getattr type
provider1 = providers.DependenciesContainer(
a=providers.Provider(),
b=providers.Provider(),
)
a1: providers.Provider = provider1.a
b1: providers.Provider = provider1.b

View File

@ -0,0 +1,22 @@
from typing import Type
from dependency_injector import providers
class Animal:
...
class Cat(Animal):
def __init__(self, *_, **__): ...
# Test 1: to check the return type
provider1 = providers.Dependency(instance_of=Animal)
provider1.override(providers.Factory(Cat))
var1: Animal = provider1()
# Test 2: to check the return type
provider2 = providers.Dependency(instance_of=Animal)
var2: Type[Animal] = provider2.instance_of

View File

@ -0,0 +1,18 @@
from dependency_injector import containers, providers
# Test 1: to check setattr
container1 = containers.DynamicContainer()
container1.abc = providers.Provider()
# Test 2: to check override()
container2 = containers.DynamicContainer()
container2.override(containers.DynamicContainer())
# Test 3: to check override_providers()
container3 = containers.DynamicContainer()
container3.override_providers(a=providers.Provider())
# Test 4: to check set_providers()
container4 = containers.DynamicContainer()
container4.set_providers(a=providers.Provider())

68
tests/typing/factory.py Normal file
View File

@ -0,0 +1,68 @@
from typing import Tuple, Any, Dict
from dependency_injector import providers, types
class Animal:
...
class Cat(Animal):
def __init__(self, *_, **__): ...
@classmethod
def create(cls) -> Animal:
return cls()
# Test 1: to check the return type (class)
provider1 = providers.Factory(Cat)
animal1: Animal = provider1(1, 2, 3, b='1', c=2, e=0.0)
# Test 2: to check the return type (class factory method)
provider2 = providers.Factory(Cat.create)
animal2: Animal = provider2()
# Test 3: to check the .override() method
provider3 = providers.Factory(Animal)
with provider3.override(providers.Factory(Cat)):
provider3()
# Test 4: to check the .args, .kwargs, .attributes attributes
provider4 = providers.Factory(Animal)
args4: Tuple[Any] = provider4.args
kwargs4: Dict[str, Any] = provider4.kwargs
attributes4: Dict[str, Any] = provider4.attributes
# Test 5: to check the provided instance interface
provider5 = providers.Factory(Animal)
provided5: providers.ProvidedInstance = provider5.provided
attr_getter5: providers.AttributeGetter = provider5.provided.attr
item_getter5: providers.ItemGetter = provider5.provided['item']
method_caller5: providers.MethodCaller = provider5.provided.method.call(123, arg=324)
# Test 6: to check the DelegatedFactory
provider6 = providers.DelegatedFactory(Cat)
animal6: Animal = provider6(1, 2, 3, b='1', c=2, e=0.0)
# Test 7: to check the AbstractFactory
provider7 = providers.AbstractFactory(Animal)
provider7.override(providers.Factory(Cat))
animal7: Animal = provider7(1, 2, 3, b='1', c=2, e=0.0)
# Test 8: to check the FactoryDelegate __init__
provider8 = providers.FactoryDelegate(providers.Factory(object))
# Test 9: to check FactoryAggregate provider
provider9 = providers.FactoryAggregate(
a=providers.Factory(object),
b=providers.Factory(object),
)
factory_a_9: providers.Factory = provider9.a
factory_b_9: providers.Factory = provider9.b
val9: Any = provider9('a')
# Test 10: to check the explicit typing
factory10: types.Provider[Animal] = providers.Factory(Cat)
animal10: Animal = factory10()

29
tests/typing/list.py Normal file
View File

@ -0,0 +1,29 @@
from typing import Tuple, Any, List
from dependency_injector import providers
# Test 1: to check the return type (class)
provider1 = providers.List(
providers.Factory(object),
providers.Factory(object),
)
var1: List[Any] = provider1()
# Test 2: to check the .args attributes
provider2 = providers.List(
providers.Factory(object),
providers.Factory(object),
)
args2: Tuple[Any] = provider2.args
# Test 5: to check the provided instance interface
provider3 = providers.List(
providers.Factory(object),
providers.Factory(object),
)
provided3: providers.ProvidedInstance = provider3.provided
attr_getter3: providers.AttributeGetter = provider3.provided.attr
item_getter3: providers.ItemGetter = provider3.provided['item']
method_caller3: providers.MethodCaller = provider3.provided.method.call(123, arg=324)

13
tests/typing/object.py Normal file
View File

@ -0,0 +1,13 @@
from dependency_injector import providers
# Test 1: to check the return type
provider1 = providers.Object(int(3))
var1: int = provider1()
# Test 2: to check the provided instance interface
provider2 = providers.Object(int)
provided2: providers.ProvidedInstance = provider2.provided
attr_getter2: providers.AttributeGetter = provider2.provided.attr
item_getter2: providers.ItemGetter = provider2.provided['item']
method_caller2: providers.MethodCaller = provider2.provided.method.call(123, arg=324)

29
tests/typing/selector.py Normal file
View File

@ -0,0 +1,29 @@
from dependency_injector import providers
# Test 1: to check the return type
provider1 = providers.Selector(
lambda: 'a',
a=providers.Factory(object),
b=providers.Factory(object),
)
var1: int = provider1()
# Test 2: to check the provided instance interface
provider2 = providers.Selector(
lambda: 'a',
a=providers.Factory(object),
b=providers.Factory(object),
)
provided2: providers.ProvidedInstance = provider2.provided
attr_getter2: providers.AttributeGetter = provider2.provided.attr
item_getter2: providers.ItemGetter = provider2.provided['item']
method_caller2: providers.MethodCaller = provider2.provided.method.call(123, arg=324)
# Test3 to check the getattr
provider3 = providers.Selector(
lambda: 'a',
a=providers.Factory(object),
b=providers.Factory(object),
)
attr3: providers.Provider = provider3.a

71
tests/typing/singleton.py Normal file
View File

@ -0,0 +1,71 @@
from typing import Tuple, Any, Dict
from dependency_injector import providers
class Animal:
...
class Cat(Animal):
def __init__(self, *_, **__): ...
@classmethod
def create(cls) -> Animal:
return cls()
# Test 1: to check the return type (class)
provider1 = providers.Singleton(Cat)
animal1: Animal = provider1(1, 2, 3, b='1', c=2, e=0.0)
# Test 2: to check the return type (class factory method)
provider2 = providers.Singleton(Cat.create)
animal2: Animal = provider2()
# Test 3: to check the .override() method
provider3 = providers.Singleton(Animal)
with provider3.override(providers.Singleton(Cat)):
provider3()
# Test 4: to check the .args, .kwargs, .attributes attributes
provider4 = providers.Singleton(Animal)
args4: Tuple[Any] = provider4.args
kwargs4: Dict[str, Any] = provider4.kwargs
attributes4: Dict[str, Any] = provider4.attributes
# Test 5: to check the provided instance interface
provider5 = providers.Singleton(Animal)
provided5: providers.ProvidedInstance = provider5.provided
attr_getter5: providers.AttributeGetter = provider5.provided.attr
item_getter5: providers.ItemGetter = provider5.provided['item']
method_caller5: providers.MethodCaller = provider5.provided.method.call(123, arg=324)
# Test 6: to check the DelegatedSingleton
provider6 = providers.DelegatedSingleton(Cat)
animal6: Animal = provider6(1, 2, 3, b='1', c=2, e=0.0)
# Test 7: to check the ThreadSafeSingleton
provider7: providers.BaseSingleton[Animal] = providers.ThreadSafeSingleton(Cat)
animal7: Animal = provider7()
# Test 8: to check the DelegatedThreadSafeSingleton
provider8 = providers.DelegatedThreadSafeSingleton(Cat)
animal8: Animal = provider8(1, 2, 3, b='1', c=2, e=0.0)
# Test 9: to check the ThreadLocalSingleton
provider9 = providers.ThreadLocalSingleton(Cat)
animal9: Animal = provider9(1, 2, 3, b='1', c=2, e=0.0)
# Test 10: to check the DelegatedThreadLocalSingleton
provider10 = providers.DelegatedThreadLocalSingleton(Cat)
animal10: Animal = provider10(1, 2, 3, b='1', c=2, e=0.0)
# Test 11: to check the AbstractSingleton
provider11 = providers.AbstractSingleton(Animal)
provider11.override(providers.Singleton(Cat))
animal11: Animal = provider11(1, 2, 3, b='1', c=2, e=0.0)
# Test 12: to check the SingletonDelegate __init__
provider12 = providers.SingletonDelegate(providers.Singleton(object))

View File

@ -0,0 +1,15 @@
import unittest
from dependency_injector import providers, types
class SomeClass:
...
class TypesTest(unittest.TestCase):
def test_provider(self):
provider: types.Provider[SomeClass] = providers.Factory(SomeClass)
some_object = provider()
self.assertIsInstance(some_object, SomeClass)

17
tox.ini
View File

@ -35,10 +35,17 @@ commands=
unit2 discover -s tests/unit -p test_*_py2_py3.py unit2 discover -s tests/unit -p test_*_py2_py3.py
[testenv:py34] [testenv:py34]
commands=
unit2 discover -s tests/unit -p test_*_py3.py
extras= extras=
flask flask
commands=
unit2 discover -s tests/unit -p test_*_py3.py
[testenv:py35]
extras=
yaml
flask
commands=
unit2 discover -s tests/unit -p test_*_py3.py
[testenv:pypy] [testenv:pypy]
extras= extras=
@ -66,3 +73,9 @@ deps=
commands= commands=
pydocstyle src/dependency_injector/ pydocstyle src/dependency_injector/
pydocstyle examples/ pydocstyle examples/
[testenv:mypy]
deps=
mypy
commands=
mypy tests/typing