Open-Source Wikis

/

CPython

/

Modules

/

C extension modules

python/cpython

C extension modules

Modules/ is the home of every C extension module that ships with CPython, plus a few pieces of build-time infrastructure. There are about 100 top-level .c files in this directory, plus several subdirectories for multi-file modules.

Categories

Built into the interpreter

These end up as part of python itself rather than as .so files:

Module File
posix / nt Modules/posixmodule.c (~19k lines, the largest file in the tree)
_thread Modules/_threadmodule.c
_io Modules/_io/
_signal Modules/signalmodule.c
errno Modules/errnomodule.c
gc Modules/gcmodule.c
_codecs Modules/_codecsmodule.c
time Modules/timemodule.c
unicodedata Modules/unicodedata.c + UCD tables under Modules/unicodename_db.h/unicodedata_db.h
faulthandler Modules/faulthandler.c
atexit Modules/atexitmodule.c
pyexpat Modules/pyexpat.c (uses vendored expat under Modules/expat/)

The list is enumerated in _PyImport_Inittab in Python/import.c and in Modules/Setup.bootstrap.in.

Built as .so accelerators

Most C-implemented stdlib modules are built as shared libraries during the build and installed alongside the Python files:

Module File
_asyncio Modules/_asynciomodule.c (~123k lines)
_collections Modules/_collectionsmodule.c
_ctypes Modules/_ctypes/
_datetime Modules/_datetimemodule.c (~250k lines)
_decimal Modules/_decimal/ (vendored libmpdec)
_elementtree Modules/_elementtree.c
_functools Modules/_functoolsmodule.c
_hashlib Modules/_hashopenssl.c — OpenSSL-backed digests
HACL* digests Modules/_hacl/ — verified C, fallback when OpenSSL is missing
_heapq Modules/_heapqmodule.c
_io (parts) Modules/_io/
_json Modules/_json.c
_lzma Modules/_lzmamodule.c
_bz2 Modules/_bz2module.c
_zstd Modules/_zstd/
_pickle Modules/_pickle.c
_random Modules/_randommodule.c
_sqlite3 Modules/_sqlite/
_sre Modules/_sre/ (re regex engine)
_ssl Modules/_ssl.c + Modules/_ssl/
_struct Modules/_struct.c
array Modules/arraymodule.c
binascii Modules/binascii.c
cmath Modules/cmathmodule.c
itertools Modules/itertoolsmodule.c
math Modules/mathmodule.c
mmap Modules/mmapmodule.c
select Modules/selectmodule.c
socket Modules/socketmodule.c (~272k lines)
zlib Modules/zlibmodule.c
zoneinfo (_zoneinfo) Modules/_zoneinfo.c
Subinterpreter plumbing Modules/_interpretersmodule.c, Modules/_interpchannelsmodule.c, Modules/_interpqueuesmodule.c
cjkcodecs Modules/cjkcodecs/
Tk / GUI Modules/_tkinter.c, Modules/_curses_panel.c, Modules/_cursesmodule.c
Multiprocessing helpers Modules/_multiprocessing/, Modules/_posixsubprocess.c
Profiling Modules/_lsprof.c (cProfile), Modules/_remote_debugging/

Vendored third-party libraries

Library Location
expat (XML parser) Modules/expat/
libmpdec (decimal arithmetic) Modules/_decimal/libmpdec/
HACL* (verified crypto) Modules/_hacl/
mimalloc (small-obj alloc) Objects/mimalloc/ — used in free-threaded builds

These are imported with vendor-specific update procedures; see the per-directory README.

Test-only modules

These exist purely to exercise the C API, the build system, or the import protocol from CPython's own test suite. They are not part of the public stdlib:

Build infrastructure

These C files are not Python modules but are part of the build:

Argument Clinic glue

Most modern modules have a clinic/ subdirectory next to them with the generated argument-parsing code, e.g. Modules/clinic/posixmodule.c.h. See Tooling.

Conventions for new C modules

The pattern that current PRs follow:

  1. Multi-phase init (PEP 489). PyInit_<name> returns a PyModuleDef with slots, not a fully-initialized module object.
  2. Heap types only. Use PyType_FromModuleAndSpec to register types so they pick up the per-module state and per-interpreter state correctly. Static types are subinterpreter-unsafe.
  3. No global mutable C state. Per-interpreter state goes in the module's m_state. The Tools/c-analyzer/ static checker enforces this.
  4. Argument parsing via Clinic. Keep [clinic input] blocks in the source and regenerate clinic/*.c.h with make clinic.
  5. Free-threaded safety. Mutating per-object state requires Py_BEGIN_CRITICAL_SECTION.

A clean recent example to copy from is Modules/_queuemodule.c or the Modules/_zstd/ module.

How a stdlib C module is wired in

graph LR
    SETUP[Modules/Setup.stdlib.in] --> MAKE[Makefile]
    MAKE --> SO[(.so file)]
    INITTAB[Python/import.c _PyImport_Inittab] --> BUILTIN[Built-in modules]
    SO --> IMPORTLIB[importlib finds .so on sys.path]
    IMPORTLIB --> IMPORTDL[Python/importdl.c]
    IMPORTDL --> DLOPEN[dlopen / LoadLibrary]
    DLOPEN --> PYINIT[PyInit_<name>]

Built-in modules are listed in _PyImport_Inittab and in Modules/Setup.bootstrap.in. Shared modules are listed in Modules/Setup.stdlib.in. Adding a new module means: write the C source, add the Setup line, add the build rule (autodetected on most platforms), add an entry to Modules/config.c.in if it's built-in, and add the Python-level wrapper if any.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

C extension modules – CPython wiki | Factory