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.
Options that don't satisfy
Use implicit relative import
# 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.
Pull the module out of its namespace package
# 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.
Import with a mangled name
# 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.
Import the package, try using the module
# 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.
Import the package, then import the module but never use its name
# 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?
# noqa: F401to the lines and comment why you did it.from . import adipiscing, just dofrom adipiscing import lorem_ipsum, note the lack of leading.foradipiscing