Open adriangb opened 2 years ago
@adriangb some control of this would be nice, since I can imagine creating a class with no dependencies, using it within your project, and expecting it to get wired in for folks. I know I'd love this for builtin types, but maybe not so much my own.
I think a sensible default would be to check if its a leaf and if the type is part of builtins...
import inspect
import builtins
inspect.getmodule(str) == builtins # True
inspect.getmodule(list) == builtins # True
inspect.getmodule(dict) == builtins # True
Here's example BindHook that helps a little bit here:
def match_all_builtins_and_error(
param: Optional[inspect.Parameter], dependent: DependentBase[Any]
) -> Optional[DependentBase[Any]]:
if (
param is not None
and param.default is param.empty
and inspect.getmodule(param.annotation) is builtins
):
return Dependent(wire=False, call=lambda: _raise(param=param, dependent=dependent))
return None
def _raise(param: Optional[inspect.Parameter], dependent: DependentBase[Any]) -> Any:
raise RuntimeError(
f"The parameter {param} to {dependent.call} is a builtin which we don't want to autowire"
)
di
does auto wiring for dependencies which is super convenient to avoid boilerplate. But let's say you have something like:We (wrongly) assume that this can be constructed like
DBConnection(host=str())
. This is because we inspect the type annotation and autowirestr
itself!We need some way of cutting off how deep we auto-wire. I think a sensible rule would be "all of the leaf dependencies (dependencies with no further dependencies) must be manually wired with:
Marker(function_that_accepts_no_arguments)