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 "<doctest injector.BoundKey[3]>", line 1, in <module>
      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.
This commit is contained in:
Jakub Stasiak 2019-12-10 01:27:51 +01:00
parent 79e787887c
commit b399dcf908
1 changed files with 6 additions and 2 deletions

View File

@ -542,10 +542,14 @@ class Binder:
return ClassProvider(to) return ClassProvider(to)
elif isinstance(interface, BoundKey): 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) return interface.interface(**kwargs)
proxy.__annotations__ = interface.kwargs.copy()
return CallableProvider(inject(proxy)) return CallableProvider(inject(proxy))
elif _is_specialization(interface, AssistedBuilder): elif _is_specialization(interface, AssistedBuilder):
(target,) = interface.__args__ (target,) = interface.__args__