10

I was reading how to check if a python module has been imported and the instructions seems clear, check for the module in the sys.modules. This works as I expected in Python 2, but not with Python 3 (3.5 and 3.6 tested). For example:

Python 3.6

>>> import sys
>>> 'itertools' in sys.modules
True

Python 2.7

>>> import sys
>>> 'itertools' in sys.modules
False

I note that, itertools is described as a 'built-in' in the Python 3 sys.modules dict (<module 'itertools' (built-in)>), and not in Python 2 so maybe that's why it's in sys.modules prior to being imported, but it's not listed as a built-in. Anyway, since itertools still needs importing in Python 3, I'd be grateful for an explanation.

Community
  • 1
  • 1
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
  • 4
    If any modules that you've *already imported* need to import modules of their own, those modules will show as loaded. Perhaps a dependency was introduced in Python 3 that didn't exist in Python 2. P.S. even if a module is loaded, you need to `import` it to make it available in the current scope. – Mark Ransom Feb 17 '17 at 19:18
  • 1
    I think you've answered the question yourself: if `itertools` has become a builtin, it will be loaded right at the interpreter's startup. – ForceBru Feb 17 '17 at 19:20
  • is the question why `itertools` needs importing or why is it there and not listed as such in the docs? – Dimitris Fasarakis Hilliard Feb 17 '17 at 19:20
  • 2
    @ForceBru: No, built-in modules aren't all loaded at startup. You can check this by comparing `sys.builtin_module_names` against `sys.modules` in a fresh interpreter. – user2357112 Feb 17 '17 at 19:21
  • @JimFasarakis-Hilliard The question is why is `itertools` (and some other modules I tested) in `sys.modules` prior to being imported in Python 3 and not in Python 2 – Chris_Rands Feb 17 '17 at 19:24

2 Answers2

7

They have been imported, just not by you. Exactly what parts of interpreter startup caused the module to be loaded are unimportant implementation details, but you can trace possible paths if you want. For example, itertools is imported by reprlib

from itertools import islice

which is imported by functools:

from reprlib import recursive_repr

which is imported by types:

import functools as _functools

which is imported by importlib:

import types

which is bootstrapped at interpreter startup because it's where most of the implementation of importing is.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • Great, thank you for the authoritative answer. So the interpreter imports `itertools` (and other modules like `os`) but doesn't add them to `globals()` so they're not accessible? – Chris_Rands Feb 17 '17 at 20:47
  • @Chris_Rands: It follows the normal rules for importing. If module `foo` does `import bar`, that import only makes the `bar` module available for the `foo` module. Everyone that wants to use a module needs to import it themselves. – user2357112 Feb 17 '17 at 20:53
  • 1
    and that's why you can't find it in `Py 2` I'm guessing, when the import mechanism was still implemented in `C` and (apparently) didn't indirectly import `itertools`. – Dimitris Fasarakis Hilliard Feb 17 '17 at 22:45
-1

It appears that in Python 3, the itertools extension is actually compiled into the main Python binary unlike Python 2. If you do a

import sys

and then a

'itertools' in sys.builtin_module_names
>> True

it is clear. Doing the exact same steps in a Python 2.x console results in a False.

As per the docs, builtin_module_names comprises of 'modules that are compiled into this Python interpreter'.

Anomitra
  • 1,111
  • 15
  • 31
  • the question is *why* this is, not that it just is. – Dimitris Fasarakis Hilliard Feb 17 '17 at 19:51
  • @JimFasarakis-Hilliard The answer to "_why is itertools in sys.modules prior to being imported in Python 3 and not in Python 2_" is "_because it's a builtin which is proved by it's presence in_ `builtin_module_names`". – Anomitra Feb 17 '17 at 20:01
  • 2
    While the module does happen to be compiled into Python, such modules still need to be initialized and loaded by an import somewhere before they show up in `sys.modules`. – user2357112 Feb 17 '17 at 20:07
  • 2
    I downvoted because this answer implies that the reason `itertools` is loaded at startup is because it's built in. Not all built-in modules are loaded at interpreter startup. – user2357112 Feb 17 '17 at 20:25