diff --git a/injector.py b/injector.py index 5179fdc..3a44a2f 100644 --- a/injector.py +++ b/injector.py @@ -114,6 +114,10 @@ class UnknownProvider(Error): """Tried to bind to a type whose provider couldn't be determined.""" +class UnknownArgument(Error): + """Tried to mark an unknown argument as noninjectable.""" + + class Provider: """Provides class instances.""" @@ -1071,6 +1075,12 @@ def noninjectable(*args): doesn't matter. """ def decorator(function): + bindings = _infer_injected_bindings(function) + for arg in args: + if arg not in bindings: + raise UnknownArgument('Unable to mark unknown argument %s ' + 'as non-injectable.' % arg) + existing = getattr(function, '__noninjectables__', set()) merged = existing | set(args) function.__noninjectables__ = merged diff --git a/injector_test.py b/injector_test.py index a1cc752..f89ce6e 100644 --- a/injector_test.py +++ b/injector_test.py @@ -25,7 +25,7 @@ from injector import ( CircularDependency, Module, Key, SingletonScope, ScopeDecorator, with_injector, AssistedBuilder, BindingKey, SequenceKey, MappingKey, provider, ProviderOf, ClassAssistedBuilder, - Error, + Error, UnknownArgument, ) @@ -1109,6 +1109,16 @@ def test_assisted_building_is_supported(): assert processor.name == 'John' +def test_raises_when_noninjectable_arguments_defined_with_invalid_arguments(): + with pytest.raises(UnknownArgument): + + class A: + @inject + @noninjectable('c') + def __init__(self, b: str): + self.b = b + + def test_implicit_injection_fails_when_annotations_are_missing(): class A: def __init__(self, n):