2

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?

3
  • If you are worrying about code checker (i.e. flake8), just append # noqa: F401 to the lines and comment why you did it. Commented Nov 24, 2016 at 1:22
  • Alternatively just use the full import as that fully disambiguates what the thing is and is much more explicit. Commented Nov 24, 2016 at 1:24
  • Alternatively, try to see after from . import adipiscing, just do from adipiscing import lorem_ipsum, note the lack of leading . for adipiscing Commented Nov 24, 2016 at 1:27

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I have updated the question to show why this is insufficient.
0

Currently there seems to be no way to do this using the Python import system.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.