[New-bugs-announce] [issue46360] Inconsistent import behavior for (unusual) submodules

Eric Snow report at bugs.python.org
Wed Jan 12 17:04:50 EST 2022

New submission from Eric Snow <ericsnowcurrently at gmail.com>:

Let's look at a hypothetical module "spam" and its submodule "spam.eggs":

# spam.py
import sys
sys.modules['spam.eggs'] = None


>>> import spam.eggs
>>> import sys
>>> sys.modules['spam.eggs'] is None
>>> spam.eggs
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'spam' has no attribute 'eggs'

The key inconsistent behaviors:

* `import spam.eggs` succeeded even though the sys.modules entry is None
* `import spam.eggs` succeeded even though "spam" isn't a package (e.g. no `__path__`, `spec.submodule_search_locations`, etc.)
* the "eggs" attr wasn't bound on "spam"

The relevant code is _find_and_load_unlocked() and _find_and_load() in Lib/importlib/_bootstrap.py.

In _find_and_load_unlocked() we first import the parent module.  Then we have a special case, where we see if "spam.eggs" was added to sys.modules as a side effect.  If it was then we short-circuit the rest of import and return the submodule as-is.  This leads to some of the inconsistent behavior described above, since the subsequent code (e.g. checks, binding to the parent) get skipped.

In _find_and_load() we have code which raises ModuleNotFoundError if the resulting module is None, which acts as a marker that importing the module is disabled.  This check is always skipped when importing the module for the first time, leading to the other inconsistent behavior from above.

The is definitely a corner case, but os.path demonstrates it's a real scenario.  In fact, os.path is what drew my attention to this code.

Is it worth fixing?  The change shouldn't be invasive so I'm leaning toward yes.  It isn't a high priority though.

assignee: eric.snow
components: Interpreter Core
messages: 410433
nosy: barry, brett.cannon, eric.snow, ncoghlan
priority: normal
severity: normal
stage: needs patch
status: open
title: Inconsistent import behavior for (unusual) submodules
type: behavior
versions: Python 3.10, Python 3.11, Python 3.9

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list