From b399dcf908f137b4a5d593a971994f3e95717611 Mon Sep 17 00:00:00 2001 From: Jakub Stasiak Date: Tue, 10 Dec 2019 01:27:51 +0100 Subject: [PATCH] Fix a BoundKey UnknownProvider regression The example of an error this regression caused: 1302 A BoundKey provides a key to a type with pre-injected arguments. 1303 1304 >>> class A: 1305 ... def __init__(self, a, b): 1306 ... self.a = a 1307 ... self.b = b 1308 >>> InjectedA = BoundKey(A, a=InstanceProvider(1), b=InstanceProvider(2)) 1309 >>> injector = Injector() 1310 >>> a = injector.get(InjectedA) UNEXPECTED EXCEPTION: UnknownProvider("couldn't determine provider for InstanceProvider(1) to None") Traceback (most recent call last): File "/Users/user/projects/injector/injector/__init__.py", line 583, in get_binding return self._get_binding(interface, only_this_binder=is_scope) File "/Users/user/projects/injector/injector/__init__.py", line 578, in _get_binding raise KeyError KeyError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/doctest.py", line 1329, in __run compileflags, 1), test.globs) File "", line 1, in File "/Users/user/projects/injector/injector/__init__.py", line 864, in get result = scope_instance.get(interface, binding.provider).get(self) File "/Users/user/projects/injector/injector/__init__.py", line 289, in get return injector.call_with_injection(self._callable) File "/Users/user/projects/injector/injector/__init__.py", line 918, in call_with_injection owner_key=self_.__class__ if self_ is not None else callable.__module__, File "/Users/user/projects/injector/injector/__init__.py", line 80, in wrapper return function(*args, **kwargs) File "/Users/user/projects/injector/injector/__init__.py", line 959, in args_to_inject instance = self.get(interface) File "/Users/user/projects/injector/injector/__init__.py", line 853, in get binding, binder = self.binder.get_binding(interface) File "/Users/user/projects/injector/injector/__init__.py", line 592, in get_binding binding = self.create_binding(interface) File "/Users/user/projects/injector/injector/__init__.py", line 511, in create_binding provider = self.provider_for(interface, to) File "/Users/user/projects/injector/injector/__init__.py", line 569, in provider_for raise UnknownProvider('couldn\'t determine provider for %r to %r' % (interface, to)) injector.UnknownProvider: couldn't determine provider for InstanceProvider(1) to None It's been reported in GH-125. We haven't seen this because until recently doctests weren't running. Closes GH-125. --- injector/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/injector/__init__.py b/injector/__init__.py index dad96ab..189ac5d 100644 --- a/injector/__init__.py +++ b/injector/__init__.py @@ -542,10 +542,14 @@ class Binder: return ClassProvider(to) elif isinstance(interface, BoundKey): - def proxy(**kwargs): + def proxy(injector: Injector): + binder = injector.binder + kwarg_providers = { + name: binder.provider_for(None, provider) for (name, provider) in interface.kwargs.items() + } + kwargs = {name: provider.get(injector) for (name, provider) in kwarg_providers.items()} return interface.interface(**kwargs) - proxy.__annotations__ = interface.kwargs.copy() return CallableProvider(inject(proxy)) elif _is_specialization(interface, AssistedBuilder): (target,) = interface.__args__