Skip to content

Commit 6b2b415

Browse files
committed
Fix init_args to convert VAR=VALUE command-line args like CONFIG_SITE does.
Command-line VAR=VALUE arguments (e.g. ./configure ac_cv_file__dev_ptmx=yes) were stored only in os.environ, but vars.is_set() only checked vars.__dict__. This caused two bugs when cross-compiling: 1. is_set("ac_cv_file__dev_ptmx") returned False even when the user had explicitly set it, triggering a spurious CONFIG_SITE error. 2. A "no" value stayed as a string in os.environ; Python truthiness (if v.ac_cv_file__dev_ptmx:) would evaluate it as True, incorrectly defining HAVE_DEV_PTMX. Fix: in init_args(), after storing in os.environ, also convert the value via _cache_deserialize() (yes→True, no→False) and setattr on vars, matching exactly what _load_config_site() does. For ac_cv_* vars, also populate cache[]. This makes command-line VAR=VALUE args behave consistently with CONFIG_SITE values, matching AWK where VAR=val populates V[]. Also clear vars.__dict__ user attributes in _reset() so test isolation is complete. Add TestInitArgsVarValue tests to cover is_set() detection and bool truthiness for command-line ac_cv_* args. Found during review of conf_filesystem.py (check_device_files cross-compile path uses is_set()). Assisted-by: Claude
1 parent 15db13f commit 6b2b415

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

Tools/configure/pyconf.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,14 @@ def init_args() -> None:
291291
):
292292
name, value = arg.split("=", 1)
293293
os.environ[name] = value
294+
# Also set on vars so is_set() detects it and bool truthiness
295+
# works correctly, mirroring what _load_config_site() does.
296+
# Convert yes/no → True/False so ac_cv_* checks behave the same
297+
# whether the value came from CONFIG_SITE or the command line.
298+
converted = _cache_deserialize(value)
299+
setattr(vars, name, converted)
300+
if name.startswith("ac_cv_"):
301+
cache[name] = converted
294302
continue
295303

296304
# Early-exit flags

Tools/configure/test_pyconf.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def _reset():
3232
pyconf.substs.clear()
3333
pyconf.env.clear()
3434
pyconf.cache.clear()
35+
# Clear user-set attributes on the Vars instance (but keep _exports).
36+
for _k in list(pyconf.vars.__dict__):
37+
if not _k.startswith("_"):
38+
delattr(pyconf.vars, _k)
3539

3640

3741
@pytest.fixture(autouse=True)
@@ -1485,6 +1489,55 @@ def test_loading_cache_message(self, capsys, monkeypatch, tmp_path):
14851489
assert f"loading cache {cache_path}" in captured.out
14861490

14871491

1492+
# ---------------------------------------------------------------------------
1493+
# init_args VAR=VALUE → vars.is_set() and truthiness
1494+
# ---------------------------------------------------------------------------
1495+
1496+
1497+
class TestInitArgsVarValue:
1498+
"""Command-line VAR=VALUE must be detectable via is_set() and must have
1499+
correct bool truthiness, matching AWK where VAR=val populates V[]."""
1500+
1501+
def test_ac_cv_var_sets_is_set(self, monkeypatch):
1502+
monkeypatch.setattr(sys, "argv", ["configure", "ac_cv_foo=yes"])
1503+
monkeypatch.delenv("ac_cv_foo", raising=False)
1504+
pyconf.init_args()
1505+
assert pyconf.vars.is_set("ac_cv_foo")
1506+
1507+
def test_ac_cv_yes_converts_to_true(self, monkeypatch):
1508+
monkeypatch.setattr(sys, "argv", ["configure", "ac_cv_foo=yes"])
1509+
monkeypatch.delenv("ac_cv_foo", raising=False)
1510+
pyconf.init_args()
1511+
assert pyconf.vars.ac_cv_foo is True
1512+
1513+
def test_ac_cv_no_converts_to_false(self, monkeypatch):
1514+
# Bug: before the fix, "no" stayed as a string in os.environ and
1515+
# `if v.ac_cv_foo:` would be True ("no" is a truthy non-empty string).
1516+
monkeypatch.setattr(sys, "argv", ["configure", "ac_cv_foo=no"])
1517+
monkeypatch.delenv("ac_cv_foo", raising=False)
1518+
pyconf.init_args()
1519+
assert pyconf.vars.ac_cv_foo is False
1520+
assert not pyconf.vars.ac_cv_foo
1521+
1522+
def test_ac_cv_populates_cache(self, monkeypatch):
1523+
monkeypatch.setattr(sys, "argv", ["configure", "ac_cv_foo=yes"])
1524+
monkeypatch.delenv("ac_cv_foo", raising=False)
1525+
pyconf.init_args()
1526+
assert pyconf.cache.get("ac_cv_foo") is True
1527+
1528+
def test_non_ac_cv_sets_is_set(self, monkeypatch):
1529+
monkeypatch.setattr(sys, "argv", ["configure", "MYVAR=hello"])
1530+
monkeypatch.delenv("MYVAR", raising=False)
1531+
pyconf.init_args()
1532+
assert pyconf.vars.is_set("MYVAR")
1533+
1534+
def test_non_ac_cv_not_in_cache(self, monkeypatch):
1535+
monkeypatch.setattr(sys, "argv", ["configure", "MYVAR=hello"])
1536+
monkeypatch.delenv("MYVAR", raising=False)
1537+
pyconf.init_args()
1538+
assert "MYVAR" not in pyconf.cache
1539+
1540+
14881541
# ---------------------------------------------------------------------------
14891542
# replace_funcs / LIBOBJS
14901543
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)