Lib/sysconfig.py (part 2)
Source:
cpython 3.14 @ ab2d84fe1023/Lib/sysconfig.py
This annotation covers configuration variable access and Makefile parsing. See lib_sysconfig_detail for get_python_version, get_platform, get_paths, and scheme definitions.
Map
| Lines | Symbol | Role |
|---|---|---|
| 1-80 | get_config_vars | Return build-time configuration variables from Makefile/_sysconfigdata |
| 81-200 | get_config_var | Return a single variable by name |
| 201-320 | get_path | Return a single installation path (e.g., purelib, platlib) |
| 321-480 | parse_config_h | Parse a CPython pyconfig.h to extract #define values |
| 481-600 | expand_makefile_vars | Expand $(VAR) references in Makefile strings |
| 601-700 | get_scheme_names / get_default_scheme | List available install schemes |
Reading
get_config_vars
# CPython: Lib/sysconfig.py:580 get_config_vars
def get_config_vars(*args):
"""Return a dict of build-time configuration variables.
Variables come from:
1. sys.implementation (Python version, platform)
2. _sysconfigdata_*.py (generated by Makefile at build time)
3. os.environ overrides
"""
global _CONFIG_VARS
if _CONFIG_VARS is None:
_CONFIG_VARS = {}
_init_config_vars()
if args:
vals = []
for name in args:
vals.append(_CONFIG_VARS.get(name))
return vals
return _CONFIG_VARS
get_config_vars() returns all variables. get_config_vars('CC', 'CFLAGS') returns a list of just those two values.
parse_config_h
# CPython: Lib/sysconfig.py:380 parse_config_h
def parse_config_h(fp, vars=None):
"""Parse a config.h-style file.
Returns a dictionary mapping names to integer or string values.
"""
if vars is None:
vars = {}
define_rx = re.compile(r"#define ([A-Z][A-Z0-9_]+) (.*)\n")
undef_rx = re.compile(r"/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n")
for line in fp:
m = define_rx.match(line)
if m:
n, v = m.group(1, 2)
try:
vars[n] = int(v)
except ValueError:
vars[n] = v
continue
m = undef_rx.match(line)
if m:
vars[m.group(1)] = 0
return vars
parse_config_h is used by distutils and setuptools to read CPython's pyconfig.h and determine which features were compiled in (HAVE_OPENSSL, WITH_THREAD, etc.).
expand_makefile_vars
# CPython: Lib/sysconfig.py:450 expand_makefile_vars
def expand_makefile_vars(s, vars):
"""Expand all $(VAR) references in string s using vars dict.
Resolves recursive references. Raises ValueError on circular deps.
"""
while True:
m = re.search(r'\$\(([^)]+)\)', s)
if not m:
break
var_name = m.group(1)
var_value = vars.get(var_name, '')
s = s[:m.start()] + var_value + s[m.end():]
return s
$(CC) in a Makefile variable like CFLAGS = $(CC) -O2 is expanded by substituting the value of CC. Circular references (e.g., A = $(B), B = $(A)) result in an infinite loop in this simple implementation; CPython limits recursion depth in practice.
get_scheme_names
# CPython: Lib/sysconfig.py:640 get_scheme_names
def get_scheme_names():
"""Return a tuple of the install scheme names."""
return tuple(sorted(_SCHEMES))
def get_default_scheme():
"""Return the default scheme name for this platform."""
if os.name == 'nt':
return 'nt'
if sys.platform == 'darwin' and sys._framework:
return 'osx_framework_library'
return 'posix_prefix'
Install schemes define where packages go: posix_prefix puts them in /usr/local/lib/pythonX.Y/, posix_home uses ~/, venv uses the virtual environment prefix.
gopy notes
sysconfig is pure Python. get_config_vars reads _sysconfigdata_*.py via importlib.import_module. parse_config_h uses re from module/re. get_path expands scheme templates with string.format_map.