Reputation: 32367
How can I make a module-within-a-package .adipiscing.lorem_ipsum
available, in a way which cleanly uses the import system and doesn't leave extraneous names unused?
Given a code base:
foo/
consecteur.py
adipiscing/
lorem_ipsum.py
The consecteur
module needs to access the adipiscing.lorem_ipsum
module.
This is what I want to do:
# consecteur.py
from . import adipiscing.lorem_ipsum
dolor = adipiscing.lorem_ipsum.dolor_sit_amet()
That doesn't work; from . import adipiscing.lorem_ipsum
is a SyntaxError.
# consecteur.py
import adipiscing.lorem_ipsum
dolor = adipiscing.lorem_ipsum.dolor_sit_amet()
This needlessly confuses whether adipiscing.lorem_ipsum
is an absolute or relative import. The code should instead be explicit when an import is relative.
# consecteur.py
from .adipiscing import lorem_ipsum
dolor = lorem_ipsum.dolor_sit_amet()
This loses the valuable information that is conveyed by reading adipiscing.lorem_ipsum
, especially if lorem_ipsum
is instead a generic word that needs to be contextualised by the adipiscing
package namespace.
# consecteur.py
from .adipiscing import lorem_ipsum as adipiscing_lorem_ipsum
dolor = adipiscing_lorem_ipsum.dolor_sit_amet()
This is visually confusing; someone expecting adipiscing.lorem_ipsum
can easily type that expecting it to work, but that name is not available. Making a confusingly-similar name is not a good solution; neither is making a distinct name, since the whole purpose is to make adipiscing.lorem_ipsum
available.
This is also ambiguous if one or both of the package or the module names actually have underscores already. If an underscore represents a dot, that becomes indistinguishable from a name that actually contains an underscore.
# consecteur.py
from . import adipiscing
dolor = adipiscing.lorem_ipsum.dolor_sit_amet()
This is an AttributeError because adipiscing.lorem_ipsum
is not available now; a module is not automatically available just by importing the containing package.
# consecteur.py
from . import adipiscing
from .adipiscing import lorem_ipsum
dolor = adipiscing.lorem_ipsum.dolor_sit_amet()
This hack succeeds, but the import statement from .adipiscing import lorem_ipsum
declares that we will be using the bare lorem_ipsum
name.
Since that's not true, static code checkers will (correctly) complain about an unused import. I agree with those code checkers, so I don't just want to silence the warning; I want to avoid the hack and still get the adipiscing.lorem_ipsum
name available.
So, how can I make the adipiscing.lorem_ipsum
name available to the code by that name, using an explicit relative import, without unused imports?
Upvotes: 2
Views: 457
Reputation: 48120
The syntax you want is not supported by the Python's interpreter. But you may use as
as an workaround with "Pull the module out of its namespace package". For example:
from .lorem import ipsum as lorem_ipsum
dolor = lorem_ipsum.dolor_sit_amet()
Doing this you will get the full context that it is lorem's ipsum
Upvotes: 1
Reputation: 32367
Currently there seems to be no way to do this using the Python import system.
Upvotes: 0