Skip to content

Commit b619088

Browse files
committed
Review conf_sharedlib.py: fix docstring and MACOSX_DEPLOYMENT_TARGET parsing.
Fix docstring (perf trampoline lives in conf_buildopts.py, not here). Add pyconf.is_digit() / pyconf_is_digit() so the deployment target version components can be validated before int() conversion, matching autoconf's silent-failure behaviour when the variable is empty or non-numeric. Register is_digit in the transpiler lint whitelist. Assisted-by: Claude
1 parent 45b54b0 commit b619088

File tree

5 files changed

+37
-9
lines changed

5 files changed

+37
-9
lines changed

Tools/configure/conf_sharedlib.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
"""conf_sharedlib — Shared-lib linking, perf trampoline.
1+
"""conf_sharedlib — Shared-lib linking and dynamic loading.
22
33
Determines shared library extension (SHLIB_SUFFIX); computes LDSHARED,
44
LDCXXSHARED, BLDSHARED for each platform; sets CCSHARED (-fPIC etc.);
55
determines LINKFORSHARED for the main executable; exports shared-lib
6-
variables (CFLAGSFORSHARED, SHLIBS); and configures perf trampoline
7-
support.
6+
variables (CFLAGSFORSHARED, SHLIBS); selects DYNLOADFILE; and sets
7+
MACHDEP_OBJS.
88
"""
99

1010
from __future__ import annotations
@@ -87,8 +87,16 @@ def setup_ldshared(v):
8787
# This allows an extension to be used in any Python
8888
dt = v.MACOSX_DEPLOYMENT_TARGET or ""
8989
dt_parts = dt.split(".")
90-
dt_major = int(dt_parts[0]) if dt_parts else 0
91-
dt_minor = int(dt_parts[1]) if len(dt_parts) > 1 else 0
90+
dt_major = (
91+
int(dt_parts[0])
92+
if dt_parts and pyconf.is_digit(dt_parts[0])
93+
else 0
94+
)
95+
dt_minor = (
96+
int(dt_parts[1])
97+
if len(dt_parts) > 1 and pyconf.is_digit(dt_parts[1])
98+
else 0
99+
)
92100
if dt_major == 10 and dt_minor <= 2:
93101
pyconf.error(
94102
f"MACOSX_DEPLOYMENT_TARGET too old ({dt}), "

Tools/configure/configure.awk

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -799,14 +799,18 @@ function pyconf_check_func(fname, headers, define, source, inc, cv, rc, cache_ke
799799
return rc
800800
}
801801

802-
function pyconf_check_funcs(funcs, n, i, rc) {
802+
function pyconf_check_funcs(funcs, n, i, rc, any_found) {
803+
# Returns 1 if any function was found (mirrors AC_CHECK_FUNCS action-if-found).
803804
n = funcs[0] + 0
805+
any_found = 0
804806
for (i = 1; i <= n; i++)
805807
if (funcs[i] != "") {
806808
pyconf_checking("for " funcs[i])
807809
rc = pyconf_check_func(funcs[i])
808810
pyconf_result(rc ? "yes" : "no")
811+
if (rc) any_found = 1
809812
}
813+
return any_found
810814
}
811815

812816
function pyconf_replace_funcs(funcs, n, i, rc) {
@@ -1227,6 +1231,10 @@ function pyconf_find_mkdir_p( result, ver, dirs, n, i, p, prog, progs, cmd) {
12271231
# String / path utilities
12281232
# ---------------------------------------------------------------------------
12291233

1234+
function pyconf_is_digit(s) {
1235+
return s ~ /^[0-9]+$/
1236+
}
1237+
12301238
function pyconf_fnmatch(string, pattern) {
12311239
# Simple glob match using case
12321240
# For exact match patterns, use == comparison
@@ -7624,8 +7632,8 @@ function u_setup_ldshared( _tmp_split, dt, dt_major, dt_minor, dt_parts, has_
76247632
} else if (_str_startswith(sr, "Darwin/")) {
76257633
dt = ((V["MACOSX_DEPLOYMENT_TARGET"] != "") ? V["MACOSX_DEPLOYMENT_TARGET"] : "")
76267634
dt_parts = _str_replace(dt, ".", " ")
7627-
dt_major = (((dt_parts != "") && (dt_parts != "no")) ? _split_index(dt_parts, " ", 1) : 0)
7628-
dt_minor = ((length(dt_parts) > 1) ? _split_index(dt_parts, " ", 2) : 0)
7635+
dt_major = ((((dt_parts != "") && (dt_parts != "no")) && pyconf_is_digit(_split_index(dt_parts, " ", 1))) ? _split_index(dt_parts, " ", 1) : 0)
7636+
dt_minor = (((length(dt_parts) > 1) && pyconf_is_digit(_split_index(dt_parts, " ", 2))) ? _split_index(dt_parts, " ", 2) : 0)
76297637
if (((dt_major == 10) && (dt_minor <= 2))) {
76307638
pyconf_error("MACOSX_DEPLOYMENT_TARGET too old (" dt "), only 10.3 or later is supported")
76317639
}
@@ -7931,6 +7939,7 @@ function u_detect_dbm( _i_db, _n_db, _tmp_split, ac_cv_have_libdb, ac_cv_head
79317939
pyconf_define("HAVE_GDBM_DASH_NDBM_H", 1, 0, "Define to 1 if you have the <gdbm-ndbm.h> header file.")
79327940
}
79337941
if ((((ac_cv_header_gdbm_slash_ndbm_h != "") && (ac_cv_header_gdbm_slash_ndbm_h != "no")) || ((ac_cv_header_gdbm_dash_ndbm_h != "") && (ac_cv_header_gdbm_dash_ndbm_h != "no")))) {
7942+
r = ""
79347943
pyconf_save_env()
79357944
r = pyconf_search_libs("dbm_open", "gdbm_compat")
79367945
pyconf_restore_env()
@@ -8066,6 +8075,7 @@ function u_check_remaining_libs( AIX_BUILDDATE, ac_cv_aligned_required) {
80668075
}
80678076

80688077
function u_check_libatomic( libatomic_needed) {
8078+
libatomic_needed = "no"
80698079
pyconf_save_env()
80708080
V["CPPFLAGS"] = _str_strip(V["BASECPPFLAGS"] " -I. -I" pyconf_srcdir "/Include " V["CPPFLAGS"])
80718081
libatomic_needed = ((!pyconf_link_check("whether libatomic is needed by <pyatomic.h>", "\n// pyatomic.h needs uint64_t and Py_ssize_t types\n#include <stdint.h>\n#ifdef HAVE_SYS_TYPES_H\n# include <sys/types.h>\n#endif\n#if HAVE_SSIZE_T\ntypedef ssize_t Py_ssize_t;\n#elif SIZEOF_VOID_P == SIZEOF_SIZE_T\ntypedef intptr_t Py_ssize_t;\n#else\n# error \"unable to define Py_ssize_t\"\n#endif\n#include \"pyatomic.h\"\nint main() {\n uint64_t value;\n _Py_atomic_store_uint64(&value, 2);\n if (_Py_atomic_or_uint64(&value, 8) != 2) return 1;\n if (_Py_atomic_load_uint64(&value) != 10) return 1;\n uint8_t byte = 0xb8;\n if (_Py_atomic_or_uint8(&byte, 0x2d) != 0xb8) return 1;\n if (_Py_atomic_load_uint8(&byte) != 0xbd) return 1;\n return 0;\n}\n")) ? "yes" : "no")

Tools/configure/pyconf.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3548,6 +3548,11 @@ def macro(name: str, args: list | None = None) -> None:
35483548
# The transpiler maps each to a corresponding shell function or built-in.
35493549

35503550

3551+
def is_digit(s: str) -> bool:
3552+
"""Return True if *s* is non-empty and all characters are ASCII digits."""
3553+
return s.isdigit()
3554+
3555+
35513556
def fnmatch(string: str, pattern: str) -> bool:
35523557
"""Glob-style pattern match (shell: case "$string" in pattern) ...)."""
35533558
return _fnmatch.fnmatch(string, pattern)

Tools/configure/transpiler/lint_transpilable.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,10 @@
135135
"cmd_status",
136136
"run_program_output",
137137
"shell",
138-
# Pattern matching (pyconf wrapper)
138+
# Pattern matching and string predicates (pyconf wrappers)
139139
"fnmatch",
140140
"fnmatch_any",
141+
"is_digit",
141142
"sed",
142143
# Environment save/restore
143144
"save_env",

Tools/configure/transpiler/pyconf.awk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,10 @@ function pyconf_find_mkdir_p( result, ver, dirs, n, i, p, prog, progs, cmd) {
11941194
# String / path utilities
11951195
# ---------------------------------------------------------------------------
11961196

1197+
function pyconf_is_digit(s) {
1198+
return s ~ /^[0-9]+$/
1199+
}
1200+
11971201
function pyconf_fnmatch(string, pattern) {
11981202
# Simple glob match using case
11991203
# For exact match patterns, use == comparison

0 commit comments

Comments
 (0)