Fix injecting special interfaces with no auto_bind
This concerns injecting ProviderOf and AssistedBuilder "interfaces".
This commit is contained in:
parent
607b4ce12b
commit
7e91d048db
3
CHANGES
3
CHANGES
|
@ -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
|
||||
-----
|
||||
|
|
10
injector.py
10
injector.py
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue