Skip to content

Commit b80ca13

Browse files
committed
gh-157695: Parse also _Py_XXX variables in sysconfig
Add parse_config_h() tests in test_sysconfig.
1 parent ea0ee92 commit b80ca13

2 files changed

Lines changed: 67 additions & 5 deletions

File tree

‎Lib/sysconfig/__init__.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,10 @@ def parse_config_h(fp, vars=None):
437437
if vars is None:
438438
vars = {}
439439
import re
440-
define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
441-
undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
442-
quoted_re = re.compile('^"(.*)"$')
440+
name_rx = '(?:[A-Z]|_Py_)[A-Za-z0-9_]+'
441+
define_rx = re.compile(fr"#define ({name_rx}) (.*)\n")
442+
undef_rx = re.compile(fr"/[*] #undef ({name_rx}) [*]/\n")
443+
quoted_re = re.compile(r'"(.*)"')
443444

444445
while True:
445446
line = fp.readline()
@@ -448,7 +449,7 @@ def parse_config_h(fp, vars=None):
448449
m = define_rx.match(line)
449450
if m:
450451
n, v = m.group(1, 2)
451-
if mq := quoted_re.match(v):
452+
if mq := quoted_re.fullmatch(v):
452453
v = mq.group(1)
453454
try:
454455
if n in _ALWAYS_STR:

‎Lib/test/test_sysconfig.py‎

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
get_path, get_path_names, _INSTALL_SCHEMES,
3030
get_default_scheme, get_scheme_names, get_config_var,
3131
_expand_vars, _get_preferred_schemes,
32-
is_python_build, _PROJECT_BASE)
32+
is_python_build, _PROJECT_BASE, parse_config_h)
3333
from sysconfig.__main__ import _main, _parse_makefile, _get_pybuilddir, _get_json_data_name
3434
import _imp
3535
import _osx_support
@@ -767,6 +767,67 @@ def test_sysconfig_config_vars_no_prefix_cache(self):
767767
self.assertEqual(config_vars['exec_prefix'], sys.exec_prefix)
768768
self.assertEqual(config_vars['platbase'], sys.exec_prefix)
769769

770+
def test_parse_config_h(self):
771+
config = textwrap.dedent('''
772+
#ifndef Py_PYCONFIG_H
773+
#define Py_PYCONFIG_H
774+
775+
/* C comment */
776+
777+
#define ALIGNOF_LONG 8
778+
#define HAVE_ACCEPT 1
779+
#define _Py_HAVE_COSPI 1
780+
#define INVALID_NUMBER abc
781+
#define ALT_SOABI "cpython-316t-x86_64-linux-gnu"
782+
783+
// Undef macros must be written as "/* #undef NAME */":
784+
// name must be valid and there is not value.
785+
/* #undef ANDROID_API_LEVEL */
786+
#undef IGNORE_UNDEF
787+
/* #undef IGNORE_VALUE 1 */
788+
789+
# _ALWAYS_STR: don't convert values to an integer,
790+
# but quotes are removed
791+
#define IPHONEOS_DEPLOYMENT_TARGET "13.0"
792+
#define MACOSX_DEPLOYMENT_TARGET 10.9
793+
794+
// Ignore macro without value
795+
#define IGNORE_NO_VALUE
796+
797+
// Ignore macro with an invalid name
798+
#define _PRIVATE_IGNORED 1
799+
#define aLOWER_IGNORED 1
800+
#define 123IGNORED 1
801+
#define INVALID-NAME 1
802+
#define INVALID#NAME 1
803+
#define NONASCII_NAME_é 1
804+
805+
// Ignore single letter names
806+
#define A 1
807+
/* #undef A */
808+
809+
#endif /*Py_PYCONFIG_H*/
810+
''')
811+
812+
filename = TESTFN
813+
self.addCleanup(unlink, filename)
814+
with open(filename, "w", encoding="utf-8") as fp:
815+
fp.write(config)
816+
vars = {}
817+
with open(filename, encoding="utf-8") as fp:
818+
parse_config_h(fp, vars)
819+
expected = {
820+
'ALIGNOF_LONG': 8,
821+
'HAVE_ACCEPT': 1,
822+
'_Py_HAVE_COSPI': 1,
823+
'INVALID_NUMBER': 'abc',
824+
'ALT_SOABI': 'cpython-316t-x86_64-linux-gnu',
825+
'ANDROID_API_LEVEL': 0,
826+
'IPHONEOS_DEPLOYMENT_TARGET': '13.0',
827+
'MACOSX_DEPLOYMENT_TARGET': '10.9',
828+
}
829+
self.assertEqual(vars, expected)
830+
770831

771832
class MakefileTests(unittest.TestCase):
772833

0 commit comments

Comments
 (0)