fix: inspect union arguments for annotations (#195)

NoInject[T] = None has the runtime typehint NoInject[T] | None,
instead of the expected NoInject[T | None].
NoInject[str] = 'blarb' works as expected

Resolves #192
This commit is contained in:
Tobias Nilsson 2022-06-15 01:01:32 +02:00 committed by GitHub
parent 92212fe08b
commit ce957ab42a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 2 deletions

View File

@ -1190,6 +1190,19 @@ def _infer_injected_bindings(callable: Callable, only_explicit_bindings: bool) -
# mypy complains about this construct: # mypy complains about this construct:
# error: The type alias is invalid in runtime context # error: The type alias is invalid in runtime context
# See: https://github.com/python/mypy/issues/5354 # See: https://github.com/python/mypy/issues/5354
union_metadata = {
metadata
for member in new_members
for metadata in getattr(member, '__metadata__', tuple())
if _is_specialization(member, Annotated)
}
if (
only_explicit_bindings
and _inject_marker not in union_metadata
or _noinject_marker in union_metadata
):
del bindings[k]
else:
bindings[k] = new_union # type: ignore bindings[k] = new_union # type: ignore
return bindings return bindings

View File

@ -11,7 +11,7 @@
"""Functional tests for the "Injector" dependency injection framework.""" """Functional tests for the "Injector" dependency injection framework."""
from contextlib import contextmanager from contextlib import contextmanager
from typing import Any, NewType from typing import Any, NewType, Optional
import abc import abc
import sys import sys
import threading import threading
@ -1481,3 +1481,16 @@ def test_get_bindings():
pass pass
assert get_bindings(function8) == {} assert get_bindings(function8) == {}
# Default arguments to NoInject annotations should behave the same as noninjectable decorator w.r.t 'None'
@inject
@noninjectable('b')
def function9(self, a: int, b: Optional[str] = None):
pass
@inject
def function10(self, a: int, b: NoInject[Optional[str]] = None):
# b:s type is Union[NoInject[Union[str, None]], None]
pass
assert get_bindings(function9) == {'a': int} == get_bindings(function10)