◐ Shell
clean mode source ↗

[3.10] bpo-44351: Restore back parse_makefile in distutils.sysconfig (GH-26637) by miss-islington · Pull Request #26673 · python/cpython

Expand Up @@ -28,7 +28,6 @@ _PYTHON_BUILD as python_build, _init_posix as sysconfig_init_posix, parse_config_h as sysconfig_parse_config_h, _parse_makefile as sysconfig_parse_makefile,
_init_non_posix, _is_python_source_dir, Expand Down Expand Up @@ -68,14 +67,118 @@ def parse_config_h(fp, g=None): return sysconfig_parse_config_h(fp, vars=g)

def parse_makefile(fn, g=None): return sysconfig_parse_makefile(fn, vars=g, keep_unresolved=False)
_python_build = partial(is_python_build, check_home=True) _init_posix = partial(sysconfig_init_posix, _config_vars) _init_nt = partial(_init_non_posix, _config_vars)

# Similar function is also implemented in sysconfig as _parse_makefile # but without the parsing capabilities of distutils.text_file.TextFile. def parse_makefile(fn, g=None): """Parse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ from distutils.text_file import TextFile fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape")
if g is None: g = {} done = {} notdone = {}
while True: line = fp.readline() if line is None: # eof break m = re.match(_variable_rx, line) if m: n, v = m.group(1, 2) v = v.strip() # `$$' is a literal `$' in make tmpv = v.replace('$$', '')
if "$" in tmpv: notdone[n] = v else: try: v = int(v) except ValueError: # insert literal `$' done[n] = v.replace('$$', '$') else: done[n] = v
# Variables with a 'PY_' prefix in the makefile. These need to # be made available without that prefix through sysconfig. # Special care is needed to ensure that variable expansion works, even # if the expansion uses the name without a prefix. renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
# do variable interpolation here while notdone: for name in list(notdone): value = notdone[name] m = re.search(_findvar1_rx, value) or re.search(_findvar2_rx, value) if m: n = m.group(1) found = True if n in done: item = str(done[n]) elif n in notdone: # get it on a subsequent round found = False elif n in os.environ: # do it like make: fall back to environment item = os.environ[n]
elif n in renamed_variables: if name.startswith('PY_') and name[3:] in renamed_variables: item = ""
elif 'PY_' + n in notdone: found = False
else: item = str(done['PY_' + n]) else: done[n] = item = "" if found: after = value[m.end():] value = value[:m.start()] + item + after if "$" in after: notdone[name] = value else: try: value = int(value) except ValueError: done[name] = value.strip() else: done[name] = value del notdone[name]
if name.startswith('PY_') \ and name[3:] in renamed_variables:
name = name[3:] if name not in done: done[name] = value else: # bogus variable reference; just drop it since we can't deal del notdone[name]
fp.close()
# strip spurious spaces for k, v in done.items(): if isinstance(v, str): done[k] = v.strip()
# save the results in the global dictionary g.update(done) return g

# Following functions are deprecated together with this module and they # have no direct replacement
Expand Down