Skip to main content

Lib/sysconfig.py

cpython 3.14 @ ab2d84fe1023/Lib/sysconfig.py

sysconfig exposes the build-time Makefile variables and the installation directory layout that CPython was compiled and installed with. Tools such as pip, distutils, and setuptools rely on it to locate include/, lib/, and platlib/ trees without hard-coding platform-specific paths. The module replaced the older distutils.sysconfig in Python 3.2 and is now the canonical source of this information.

At the core of the module is the concept of an installation scheme. A scheme is a named set of path templates, each template containing {base}, {platbase}, {userbase}, and similar variables that are expanded at runtime. The built-in schemes cover posix_prefix (the standard Unix layout under /usr or a prefix), posix_home (a single-directory home install), nt (Windows), and venv (PEP 405 virtual environments). Additional schemes can be registered by platform vendors.

Configuration variables come from two sources: the Makefile produced during the CPython build (parsed lazily on first access) and a _sysconfigdata_*.py file generated by the build system and installed alongside the standard library. On Windows, variables are read from the registry and _sysconfigdata is absent.

Map

LinesSymbolRolegopy
1-60module header, _INSTALL_SCHEMESBuilt-in scheme definitions
61-200_parse_makefile, _read_makefileLazy Makefile variable parser
201-380_init_config_vars, _get_sysconfigdata_nameConfig variable initialiser
381-520get_config_vars, get_config_varPublic config variable accessors
521-650get_path, get_paths, get_path_namesPath expansion and scheme lookup
651-780get_python_version, get_platform, is_python_buildPlatform and version helpers
781-900_main, CLI entry pointCommand-line introspection driver

Reading

Installation schemes (lines 1 to 60)

cpython 3.14 @ ab2d84fe1023/Lib/sysconfig.py#L1-60

The module opens by defining _INSTALL_SCHEMES, a dict mapping scheme names to dicts of path templates. Each inner dict has keys like stdlib, platstdlib, purelib, platlib, include, scripts, and data. Template variables use Python's str.format_map style. The _SCHEME_KEYS tuple records the canonical key ordering that get_paths respects.

_INSTALL_SCHEMES = {
'posix_prefix': {
'stdlib': '{installed_base}/lib/python{py_version_short}',
'platstdlib': '{platbase}/lib/python{py_version_short}',
'purelib': '{base}/lib/python{py_version_short}/site-packages',
...
},
'nt': {
'stdlib': '{installed_base}/Lib',
...
},
}

Makefile parser (lines 61 to 200)

cpython 3.14 @ ab2d84fe1023/Lib/sysconfig.py#L61-200

_parse_makefile opens the Makefile file found via get_makefile_filename and performs two passes. The first pass collects raw variable assignments, distinguishing numeric literals from string values. The second pass expands $(VAR) references repeatedly until no substitutions remain. The result is a flat dict of variable names to Python scalars. This dict is merged into the global config vars dict on first access so repeated calls pay no extra I/O cost.

def _parse_makefile(filename, vars=None, keep_unresolved=True):
...
_variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
done = {}
notdone = {}
with open(filename, errors='surrogateescape') as f:
for line in f:
m = _variable_rx.match(line)
if m:
n, v = m.group(1, 2)
...

Config variable accessors (lines 381 to 520)

cpython 3.14 @ ab2d84fe1023/Lib/sysconfig.py#L381-520

get_config_vars(*names) is the primary public API for build variables. Called with no arguments it returns the full dict. Called with one or more names it returns a list of values, substituting None for missing keys. get_config_var(name) is the single-key convenience wrapper. Both functions trigger lazy initialisation via _init_config_vars on first call, which loads the Makefile and the _sysconfigdata module.

def get_config_var(name):
if name == 'SO':
...
return get_config_var('EXT_SUFFIX')
return get_config_vars().get(name)

def get_config_vars(*args):
global _CONFIG_VARS
if _CONFIG_VARS is None:
_init_config_vars()
if args:
return [_CONFIG_VARS.get(name) for name in args]
return _CONFIG_VARS

Path helpers (lines 521 to 650)

cpython 3.14 @ ab2d84fe1023/Lib/sysconfig.py#L521-650

get_path(name, scheme, vars, expand) looks up a single path template from the named scheme (defaulting to the platform default) and expands it with the merged set of config variables plus any caller-supplied overrides. get_paths(scheme, vars) returns all paths for a scheme as a dict. get_path_names() returns the tuple of canonical key names. Together these functions give installers a single call to locate any installation directory without knowing platform details.

def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True):
if expand:
return _expand_vars(scheme, vars)[name]
else:
return _INSTALL_SCHEMES[scheme][name]

Platform and version utilities (lines 651 to 780)

cpython 3.14 @ ab2d84fe1023/Lib/sysconfig.py#L651-780

get_python_version() returns the MAJOR.MINOR string. get_platform() constructs the platform tag used in wheel filenames and distinfo directories, handling the macOS MACOSX_DEPLOYMENT_TARGET and multi-arch fat binary cases. is_python_build(check_home) tests whether the running interpreter is being executed directly from its build directory, which affects path resolution for in-tree test runs.

def get_platform():
if os.name == 'nt':
...
if sys.platform == 'darwin':
...
return '%s-%s' % (os.name, plat)

gopy mirror

Not yet ported.