summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-06-15 12:36:45 (GMT)
committerGitHub <noreply@github.com>2021-06-15 12:36:45 (GMT)
commit2f2ea96c4429b81f491aa1cdc4219ef2fd6d37fb (patch)
treeb81c7757606a7f2c2fe8e37b7656c064d1c9a573 /Lib
parent133cddf76e8265536c584872351c191e3afd66a2 (diff)
downloadcpython-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.py111
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