8000 bpo-44351: Restore back parse_makefile in distutils.sysconfig (GH-266… · python/cpython@2f2ea96 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2f2ea96

Browse files
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 fc98266) Co-authored-by: Lumír 'Frenzy' Balhar <lbalhar@redhat.com>
1 parent 133cddf commit 2f2ea96

File tree

2 files changed

+109
-4
lines changed

2 files changed

+109
-4
lines changed

Lib/distutils/sysconfig.py

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
_PYTHON_BUILD as python_build,
2929
_init_posix as sysconfig_init_posix,
3030
parse_config_h as sysconfig_parse_config_h,
31-
_parse_makefile as sysconfig_parse_makefile,
3231

3332
_init_non_posix,
3433
_is_python_source_dir,
@@ -68,14 +67,118 @@ def parse_config_h(fp, g=None):
6867
return sysconfig_parse_config_h(fp, vars=g)
6968

7069

71-
def parse_makefile(fn, g=None):
72-
return sysconfig_parse_makefile(fn, vars=g, keep_unresolved=False)
73-
7470
_python_build = partial(is_python_build, check_home=True)
7571
_init_posix = partial(sysconfig_init_posix, _config_vars)
7672
_init_nt = partial(_init_non_posix, _config_vars)
7773

7874

75+
# Similar function is also implemented in sysconfig as _parse_makefile
76+
# but without the parsing capabilities of distutils.text_file.TextFile.
77+
def parse_makefile(fn, g=None):
78+
"""Parse a Makefile-style file.
79+
A dictionary containing name/value pairs is returned. If an
80+
optional dictionary is passed in as the second argument, it is
81+
used instead of a new dictionary.
82+
"""
83+
from distutils.text_file import TextFile
84+
fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape")
85+
86+
if g is None:
87+
g = {}
88+
done = {}
89+
notdone = {}
90+
91+
while True:
92+
line = fp.readline()
93+
if line is None: # eof
94+
break
95+
m = re.match(_variable_rx, line)
96+
if m:
97+
n, v = m.group(1, 2)
98+
v = v.strip()
99+
# `$$' is a literal `$' in make
100+
tmpv = v.replace('$$', '')
101+
102+
if "$" in tmpv:
103+
notdone[n] = v
104+
else:
105+
try:
106+
v = int(v)
107+
except ValueError:
108+
# insert literal `$'
109+
done[n] = v.replace('$$', '$')
110+
else:
111+
done[n] = v
112+
113+
# Variables with a 'PY_' prefix in the makefile. These need to
114+
# be made available without that prefix through sysconfig.
115+
# Special care is needed to ensure that variable expansion works, even
116+
# if the expansion uses the name without a prefix.
117+
renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
118+
119+
# do variable interpolation here
120+
while notdone:
121+
for name in list(notdone):
122+
value = notdone[name]
123+
m = re.search(_findvar1_rx, value) or re.search(_findvar2_rx, value)
124+
if m:
125+
n = m.group(1)
126+
found = True
127+
if n in done:
128+
item = str(done[n])
129+
elif n in notdone:
130+
# get it on a subsequent round
131+
found = False
132+
elif n in os.environ:
133+
# do it like make: fall back to environment
134+
item = os.environ[n]
135+
136+
elif n in renamed_variables:
137+
if name.startswith('PY_') and name[3:] in renamed_variables:
138+
item = ""
139+
140+
elif 'PY_' + n in notdone:
141+
found = False
142+
143+
else:
144+
item = str(done['PY_' + n])
145+
else:
146+
done[n] = item = ""
147+
if found:
148+
after = value[m.end():]
149+
value = value[:m.start()] + item + after
150+
if "$" in after:
151+
notdone[name] = value
152+
else:
153+
try: value = int(value)
154+
except ValueError:
155+
done[name] = value.strip()
156+
else:
157+
done[name] = value
158+
del notdone[name]
159+
160+
if name.startswith('PY_') \
161+
and name[3:] in renamed_variables:
162+
163+
name = name[3:]
164+
if name not in done:
165+
done[name] = value
166+
else:
167+
# bogus variable reference; just drop it since we can't deal
168+
del notdone[name]
169+
170+
fp.close()
171+
172+
# strip spurious spaces
173+
for k, v in done.items():
174+
if isinstance(v, str):
175+
done[k] = v.strip()
176+
177+
# save the results in the global dictionary
178+
g.update(done)
179+
return g
180+
181+
79182
# Following functions are deprecated together with this module and they
80183
# have no direct replacement
81184

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Restore back :func:`parse_makefile` in :mod:`distutils.sysconfig` because it
2+
behaves differently than the similar implementation in :mod:`sysconfig`.

0 commit comments

Comments
 (0)
0