Why do some of CPython's lib modules have implementations in C and Python?

Viewed 79

I'm trying to adapt some code from the standard library and as I was looking through functools I noticed lines like this after each "functool":

try:
    from _functools import _lru_cache_wrapper
except ImportError:
    pass

From functools.py

In the comment header I noticed this disclaimer:

# Python module wrapper for _functools C module
# to allow utilities written in Python to be added
# to the functools module.

I then noticed that in the functools c module there are implementations for the same modules, lru_cache even talks about differences between them:

/* lru_cache object **********************************************************/

/* There are four principal algorithmic differences from the pure python version:
   1). The C version relies on the GIL instead of having its own reentrant lock.
   2). The prev/next link fields use borrowed references.
   3). For a full cache, the pure python version rotates the location of the
       root entry so that it never has to move individual links and it can
       limit updates to just the key and result fields.  However, in the C
       version, links are temporarily removed while the cache dict updates are
       occurring. Afterwards, they are appended or prepended back into the
       doubly-linked lists.
   4)  In the Python version, the _HashSeq class is used to prevent __hash__
       from being called more than once.  In the C version, the "known hash"
       variants of dictionary calls as used to the same effect.
*/

Presumably the import above just means we just import the C version. Why is there a Python implementation at all if it's just going to be overwritten? I would assume this is in case an environment can't import the C version, but what kind of CPython interpreter can't import a C module?

0 Answers
Related