ivankorobkov / python-inject

Python dependency injection
Apache License 2.0
694 stars 79 forks source link

Error in case if class overrides __bool__ #55

Closed dbalabka closed 4 years ago

dbalabka commented 4 years ago

It might be that class might override __bool__ and restrict casting into boolean. Pandas DataFrame does it. In this case, it is impossible to use an instance of DataFrame as a dependency because of the following error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<timed exec> in <module>

/opt/conda/lib/python3.7/site-packages/inject/__init__.py in instance(cls)
    321 def instance(cls: Binding) -> Injectable:
    322     """Inject an instance of a class."""
--> 323     return get_injector_or_die().get_instance(cls)
    324 
    325 @overload

/opt/conda/lib/python3.7/site-packages/inject/__init__.py in get_instance(self, cls)
    169         binding = self._bindings.get(cls)
    170         if binding:
--> 171             return binding()
    172 
    173         # Try to create a runtime binding.

/opt/conda/lib/python3.7/site-packages/inject/__init__.py in __call__(self)
    212             if self._created and self._instance:
    213                 return self._instance
--> 214             self._instance = self._constructor()
    215             self._created = True
    216         return self._instance

/opt/conda/lib/python3.7/site-packages/inject/__init__.py in injection_wrapper(*args, **kwargs)
    262             for param, cls in params_to_provide.items():
    263                 if param not in provided_params:
--> 264                     kwargs[param] = instance(cls)
    265             return func(*args, **kwargs)
    266         return injection_wrapper

/opt/conda/lib/python3.7/site-packages/inject/__init__.py in instance(cls)
    321 def instance(cls: Binding) -> Injectable:
    322     """Inject an instance of a class."""
--> 323     return get_injector_or_die().get_instance(cls)
    324 
    325 @overload

/opt/conda/lib/python3.7/site-packages/inject/__init__.py in get_instance(self, cls)
    169         binding = self._bindings.get(cls)
    170         if binding:
--> 171             return binding()
    172 
    173         # Try to create a runtime binding.

/opt/conda/lib/python3.7/site-packages/inject/__init__.py in __call__(self)
    206 
    207     def __call__(self) -> T:
--> 208         if self._created and self._instance:
    209             return self._instance
    210 

/opt/conda/lib/python3.7/site-packages/pandas/core/generic.py in __nonzero__(self)
   1477     def __nonzero__(self):
   1478         raise ValueError(
-> 1479             f"The truth value of a {type(self).__name__} is ambiguous. "
   1480             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
   1481         )

ValueError: The truth value of a GuestFeatures is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

to fix this issue it would be better to avoid boolean casting for self._instance in:

/opt/conda/lib/python3.7/site-packages/inject/__init__.py in __call__(self)
    206 
    207     def __call__(self) -> T:
--> 208         if self._created and self._instance:
    209             return self._instance
    210 
ivankorobkov commented 4 years ago

Please, close the issue if everything is OK.

dbalabka commented 4 years ago

@ivankorobkov it works now.

dbalabka commented 4 years ago

@ivankorobkov is it possible to prepare the release?

ivankorobkov commented 4 years ago

The current master has changes which break python3.6 compatibility. I'll try to fix them today/tomorrow and then make a new release.

ivankorobkov commented 4 years ago

Please, check the master version. If everything is OK, I will make a release.

dbalabka commented 4 years ago

@ivankorobkov I have checked the master version. Everything works. Also, I have covered this issue with regression test. Please see #58

ivankorobkov commented 4 years ago

I've released 4.2.0 https://pypi.org/project/Inject/