diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2021-06-15 12:36:45 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-15 12:36:45 (GMT) |
commit | 2f2ea96c4429b81f491aa1cdc4219ef2fd6d37fb (patch) | |
tree | b81c7757606a7f2c2fe8e37b7656c064d1c9a573 /Lib | |
parent | 133cddf76e8265536c584872351c191e3afd66a2 (diff) | |
download | cpython-2f2ea96c4429b81f491aa1cdc4219ef2fd6d37fb.zip cpython-2f2ea96c4429b81f491aa1cdc4219ef2fd6d37fb.tar.gz cpython-2f2ea96c4429b81f491aa1cdc4219ef2fd6d37fb.tar.bz2 |
bpo-44351: Restore back parse_makefile in distutils.sysconfig (GH-26637) (GH-26673)
The function uses distutils.text_file.TextFile and therefore
behaves differently than _parse_makefile in sysconfig.
(cherry picked from commit fc98266ff627ba0f56f8ae241245b66bc983baa3)
Co-authored-by: LumÃr 'Frenzy' Balhar <lbalhar@redhat.com>
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/distutils/sysconfig.py | 111 |
1 files changed, 107 insertions, 4 deletions
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index aa63093..3414a76 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -28,7 +28,6 @@ from sysconfig import ( _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, @@ -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 |