Reputation: 2923
I have a package that contains a module with compatible imports. However, I cannot import from the exposed modules directly; I have to use slightly more inconvenient workarounds.
Inside common/compat.py, I have this:
import bcrypt
In main.py, this does not work:
from common.compat.bcrypt import hashpw
with the error:
Traceback (most recent call last):
File "main.py", line 2, in <module>
from common.compat.bcrypt import hashpw
ImportError: No module named bcrypt
However, this works fine:
from common.compat import bcrypt
# now bcrypt.hashpw works fine
Is there any way to make the first one work properly without having to do the second solution? I would prefer from imports for quite a few classes and methods.
Upvotes: 2
Views: 926
Reputation: 26160
The problem is that bcrypt
is not actually a submodule of common.compat
; the module object is actually a member attribute of the common.compat
module object with the name bcrypt
within common.compat
's namespace. As a consequence, if you want to be able to import bcrypt
as if it is a submodule of common.compat
as opposed to a value from its namespace, you need to monkey around a bit. You could create a dummy bcrypt
module within your package structure then from bcrypt import *
inside it to alias it, but probably the better way would be to directly modify sys.modules
in compat.py
.
import sys
import bcrypt
sys.modules['common.compat.bcrypt'] = bcrypt
As commenters have noted though, modifying sys.modules
is dangerous. I'm inferring from the fact that you call your package common.compat
that you are creating some sort of compatibility module that implements fallback logic in case some dependency is not available. Instead of hacking sys.modules
, you'll likely be better served creating a common.compat.crypto
module that looks something like
try:
from bcrypt import hashpw
except ImportError:
# Alternative import, hand-written alternative,
# or function that raises NotImplementedError here
Then in your main.py
, just from common.compat.crypto import hashpw
.
Upvotes: 1
Reputation: 1512
Would the following be what you are looking for ?
from common.compat import bcrypt.hashpw
However, it seems a bad idea to build depedencies in such way, because you don't seem to need that compat.py even exist to get your bcrypt module. Thus I would rather do one of the following :
Upvotes: 0