From bd97bdb3ceea5d8e7d1712e1b9198daad9972d01 Mon Sep 17 00:00:00 2001 From: Zhaoqi Xu Date: Mon, 26 Oct 2026 02:44:13 -0400 Subject: [PATCH] fix(nodeenv): read config values without interpolation --- CHANGES | 4 ++++ nodeenv.py | 3 ++- tests/nodeenv_test.py | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index c42af9e..62ddae1 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Nodeenv changelog Version [unreleased] -------------------- +- A ``%`` in a ``[nodeenv]`` config value, such as a percent-encoded + mirror login, no longer crashes nodeenv; values are read as written, + so a ``%%`` that worked around the crash is now read as ``%%`` + `#440 `_ - `nodeenv -p` no longer puts the python venv's `bin` directory on `PATH` a second time: the venv's own `activate` and `activate.fish` put it there already. Envs without those scripts, such as conda envs, and the git-bash diff --git a/nodeenv.py b/nodeenv.py index c643526..fa0a89d 100644 --- a/nodeenv.py +++ b/nodeenv.py @@ -96,7 +96,8 @@ def _load(cls, configfiles, verbose=False): if not os.path.exists(configfile): continue - ini_file = ConfigParser() + # No interpolation: a percent-encoded mirror URL is valid, #440 + ini_file = ConfigParser(interpolation=None) ini_file.read(configfile) section = "nodeenv" if not ini_file.has_section(section): diff --git a/tests/nodeenv_test.py b/tests/nodeenv_test.py index 5ee988b..2348541 100644 --- a/tests/nodeenv_test.py +++ b/tests/nodeenv_test.py @@ -591,6 +591,19 @@ def test_config_strips_quotes(tmpdir): nodeenv.Config.mirror = nodeenv.Config._default['mirror'] +def test_config_keeps_percent_signs(tmpdir): + """A % in a value is read as is, not as interpolation, see #440""" + rc = tmpdir.join('nodeenvrc') + rc.write('[nodeenv]\n' + 'mirror = https://user:p%40ss@mirror.example/nodejs\n') + try: + nodeenv.Config._load([str(rc)]) + assert nodeenv.Config.mirror == \ + 'https://user:p%40ss@mirror.example/nodejs' + finally: + nodeenv.Config.mirror = nodeenv.Config._default['mirror'] + + @pytest.fixture def auth_mirror(monkeypatch): """