Why can’t you reference modules that appear to be automatically loaded by the interpreter without an additional `import` statement?

When you start your Python interpreter it appears that some modules/packages are automatically imported during the startup process:

python
Python 2.7.6 (default, Jan 13 2014, 14:59:37)
...
>>> import sys
>>> for key in sys.modules.iterkeys():
...     print(key)
...
os
sys
abc
others ...

However, these modules seem to have been loaded into a different scope/namespace because you can’t access them without an additional import:

>>> abc
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'abc' is not defined

Here are my questions:

  1. What precisely is loading these modules and for what purpose?
  2. What scope/namespace were they loaded into?

Best answer

On a fresh interpreter startup, sys.modules will contain those modules that were loaded automatically by Python because they perform roles necessary for the Python interpreter to run. For example, Py_InitializeEx in Python/pythonrun.c includes lines like

bimod = _PyBuiltin_Init();

which initializes the __builtin__ module, where builtins like int and open live, and

sysmod = _PySys_Init();

which initializes the sys module.

As for what namespace these modules are loaded into, modules aren’t really loaded into namespaces. The import statement loads a module and assigns the module or items from the module into a variable or variables in the current namespace, but the module loading and the assignment are independent steps. Calls like _PySys_Init don’t assign the module into any particular namespace. However, the import machinery will record in sys.modules any module loaded by any code in the current Python execution, so further imports don’t re-execute the module and create a new copy.