-
-
Couldn't load subscription status.
- Fork 339
Retrofit assert_type for Aggregate and Callable #935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| from typing import Any, Callable, Dict, Optional, Tuple, Type | ||
| from typing import Any, Callable, Dict, Optional, Tuple | ||
| from typing_extensions import assert_type | ||
| | ||
| from dependency_injector import providers | ||
| | ||
| | @@ -7,19 +8,20 @@ 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) | ||
| cat1 = provider1(1, 2, 3, b="1", c=2, e=0.0) | ||
| assert_type(cat1, Cat) | ||
| | ||
| # Test 2: to check the return type (class factory method) | ||
| provider2 = providers.Callable(Cat.create) | ||
| animal2: Animal = provider2() | ||
| animal2 = provider2() | ||
| assert_type(animal2, Animal) | ||
| | ||
| # Test 3: to check the .override() method | ||
| provider3 = providers.Callable(Animal) | ||
| | @@ -28,24 +30,34 @@ def create(cls) -> Animal: | |
| | ||
| # Test 4: to check the .args & .kwargs attributes | ||
| provider4 = providers.Callable(Animal) | ||
| args4: Tuple[Any] = provider4.args | ||
| kwargs4: Dict[str, Any] = provider4.kwargs | ||
| args4 = provider4.args | ||
| kwargs4 = provider4.kwargs | ||
| assert_type(args4, Tuple[Any]) | ||
| # TODO: Change Callable.kwargs to Dict[str, Any]? Then adjust test back to Dict[str, Any] | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The stub actually declares But I think we can safely change it to return | ||
| assert_type(kwargs4, Dict[Any, Any]) | ||
| | ||
| # Test 5: to check the provided instance interface | ||
| provider5 = providers.Callable(Animal) | ||
| provided5: Animal = 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) | ||
| provided_val5 = provider5.provided() | ||
| attr_getter5 = provider5.provided.attr | ||
| item_getter5 = provider5.provided["item"] | ||
| method_caller5 = provider5.provided.method.call(123, arg=324) | ||
| # TODO: Remove explicit typing of Provider.provided return type | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The stub is this @property def provided(self) -> ProvidedInstance[T]: ...But class ProvidedInstance(Provider, ProvidedInstanceFluentInterface): def __init__(self, provides: Optional[Provider] = None) -> None: ...I think we can make the quick fix to @property def provided(self) -> ProvidedInstance: ... | ||
| assert_type(provided_val5, Any) | ||
| assert_type(attr_getter5, providers.AttributeGetter) | ||
| assert_type(item_getter5, providers.ItemGetter) | ||
| assert_type(method_caller5, providers.MethodCaller) | ||
| | ||
| # Test 6: to check the DelegatedCallable | ||
| provider6 = providers.DelegatedCallable(Cat) | ||
| animal6: Animal = provider6(1, 2, 3, b="1", c=2, e=0.0) | ||
| cat6 = provider6(1, 2, 3, b="1", c=2, e=0.0) | ||
| assert_type(cat6, Cat) | ||
| | ||
| # 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) | ||
| animal7 = provider7(1, 2, 3, b="1", c=2, e=0.0) | ||
| assert_type(animal7, Animal) | ||
| | ||
| # Test 8: to check the CallableDelegate __init__ | ||
| provider8 = providers.CallableDelegate(providers.Callable(lambda: None)) | ||
| | @@ -55,20 +67,23 @@ def create(cls) -> Animal: | |
| | ||
| | ||
| async def _async9() -> None: | ||
| animal1: Animal = await provider9(1, 2, 3, b="1", c=2, e=0.0) # type: ignore | ||
| animal2: Animal = await provider9.async_(1, 2, 3, b="1", c=2, e=0.0) | ||
| await provider9(1, 2, 3, b="1", c=2, e=0.0) # type: ignore[misc] | ||
| cat9 = await provider9.async_(1, 2, 3, b="1", c=2, e=0.0) | ||
| assert_type(cat9, Cat) | ||
| | ||
| | ||
| # Test 10: to check the .provides | ||
| provider10 = providers.Callable(Cat) | ||
| provides10: Optional[Callable[..., Cat]] = provider10.provides | ||
| assert provides10 is Cat | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these assert statements are not doing anything | ||
| provides10 = provider10.provides | ||
| assert_type(provides10, Optional[Callable[..., Cat]]) | ||
| | ||
| # Test 11: to check the .provides for explicit typevar | ||
| provider11 = providers.Callable[Animal](Cat) | ||
| provides11: Optional[Callable[..., Animal]] = provider11.provides | ||
| assert provides11 is Cat | ||
| provides11 = provider11.provides | ||
| assert_type(provides11, Optional[Callable[..., Animal]]) | ||
| | ||
| | ||
| # Test 12: to check string imports | ||
| provider12: providers.Callable[Dict[Any, Any]] = providers.Callable("builtins.dict") | ||
| # TODO: Use T_Any as Callable typevar? Then remove type-ignore | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't infer typevar without explicit typing, mypy raises error here, but we can change it to typevar with default Any to fix it | ||
| provider12 = providers.Callable("builtins.dict") # type: ignore[var-annotated] | ||
| provider12.set_provides("builtins.dict") | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current stub:
I think we should accept
collections.abc.MappinghereBecause
Dictis invariant in both key and value, soproviders.Aggregatecannot infer its own typevar without explicit typing