Fix injecting special interfaces with no auto_bind

This concerns injecting ProviderOf and AssistedBuilder "interfaces".
This commit is contained in:
Jakub Stasiak 2015-11-04 23:09:30 +01:00
parent 607b4ce12b
commit 7e91d048db
3 changed files with 38 additions and 1 deletions

View File

@ -10,6 +10,9 @@ Injector Change Log
:class:`~injector.Module` constructors or :meth:`injector.Module.configure` methods)
- removed `extends` decorator
- few classes got useful __repr__ implementations
- fixed injecting ProviderOf and AssistedBuilders when :class:`injector.Injector`
auto_bind is set to False (previously would result in `UnsatisfiedRequirement`
error)
0.9.1
-----

View File

@ -452,12 +452,20 @@ class Binder(object):
try:
return self._get_binding(key)
except (KeyError, UnsatisfiedRequirement):
if self._auto_bind:
# The special interface is added here so that requesting a special
# interface with auto_bind disabled works
if self._auto_bind or self._is_special_interface(key.interface):
binding = self.create_binding(key.interface)
self._bindings[key] = binding
return binding
raise UnsatisfiedRequirement(cls, key)
def _is_special_interface(self, interface):
# "Special" interfaces are ones that you cannot bind yourself but
# you can request them (for example you cannot bind ProviderOf(SomeClass)
# to anything but you can inject ProviderOf(SomeClass) just fine
return isinstance(interface, (ProviderOf, AssistedBuilder))
class Scope(object):
"""A Scope looks up the Provider for a binding.

View File

@ -1159,3 +1159,29 @@ def test_providerof_is_safe_to_use_with_multiple_injectors():
assert provider1.get() == 1
assert provider2.get() == 2
def test_special_interfaces_work_with_auto_bind_disabled():
class InjectMe(object):
pass
def configure(binder):
binder.bind(InjectMe, to=InstanceProvider(InjectMe()))
injector = Injector(configure, auto_bind=False)
# This line used to fail with:
# Traceback (most recent call last):
# File "/projects/injector/injector_test.py", line 1171,
# in test_auto_bind_disabled_regressions
# injector.get(ProviderOf(InjectMe))
# File "/projects/injector/injector.py", line 687, in get
# binding = self.binder.get_binding(None, key)
# File "/projects/injector/injector.py", line 459, in get_binding
# raise UnsatisfiedRequirement(cls, key)
# UnsatisfiedRequirement: unsatisfied requirement on
# <injector.ProviderOf object at 0x10ff01550>
injector.get(ProviderOf(InjectMe))
# This used to fail with an error similar to the ProviderOf one
injector.get(AssistedBuilder(cls=InjectMe))