-
-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow string imports outside of packages #736
base: master
Are you sure you want to change the base?
Conversation
IMO this will not be a popular use case, using strings instead of objects is a rather exotic and rare practice.. |
@@ -5034,7 +5034,7 @@ def _resolve_calling_module(): | |||
|
|||
def _resolve_calling_package_name(): | |||
module = _resolve_calling_module() | |||
return module.__package__ | |||
return getattr(module, "__package__", None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like it would be a good idea to write tests or add test cases for clients using this _resolve_calling_package_name
function
allow string imports outside of packages
8debf09
to
7bed1ae
Compare
At that time, I was writing an image processing application, where the user could provide a list of filters, e.g. something like a Gaussian filter with given sigma and window size, within a config file. However, I got the feature request if I could also allow filters from other libraries, e.g. scipy, skimage and openCV... or a custom filter... Generally, I agree that this is an exotic and rare practice. Looking at it today reviewing my own PR, I would even argue that providing a string import to another library is unsafe, so it would require either a safe alternative like the IMHO, you may abandon the string imports from the factory provider and add an explicit string import provider or delegate the import to the users providing some examples in the documentation. This may shrink the interface to a single way of doing things. However, I can just imagine the difficulties of maintaining such a popular library and dealing with breaking changes. BTW, thanks for providing and maintaining this library! I could implement the string import provider that allows unsafe imports if you agree. What do you think? |
I'm just a user of this package, but I made my own analogue of the injector and understand how much it works inside. User experience is important, and I think that the provider should also be specified explicitly, and not as a string. And explicit is better than implicit! but if we refer to specific arguments, I have two arguments in favor of not working with strings:
class Container1(DeclarativeContainer): ...
class Container2(DeclarativeContainer): ...
@inject
def do_smth(dep = Provide["provider"]): ...
# string definitely won’t help here, because there is more than one container |
Even though they are related, I think we are talking about different string imports. While I am talking about the first argument of Please note that I am not generally against string imports, see my use-case above. An addition for the feature of this PR would be an |
I just realized, that the above error message is specific to working in an interactive mode, e.g. Jupyter notebooks. |
Problem description
Currently, string imports are not possible outside of packages.
Minimal reproducible example
The following code snippet executed from a script or Jupyter notebook cell raises an
AttributeError: 'NoneType' object has no attribute '__package__'
The trace back reveals that the exception is thrown in
src/dependency_injector/providers.pyx in dependency_injector.providers._resolve_calling_package_name()
.Proposal for solution
In case the module in
dependency_injector.providers._resolve_calling_package_name
isNone
, the package should also beNone
. The subsequent call toimportlib.import_module
will handle the situation properly.