From dc1843ea0594251b60a85b08a2616ac3944d7a49 Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Mon, 27 Jul 2026 12:28:48 -0400 Subject: [PATCH 1/3] fix: copy caller-supplied paths instead of aliasing --- donfig/config_obj.py | 10 +++++++--- donfig/tests/test_config.py | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/donfig/config_obj.py b/donfig/config_obj.py index 7ae34c4..fcae169 100644 --- a/donfig/config_obj.py +++ b/donfig/config_obj.py @@ -399,7 +399,7 @@ def __init__( self, name: str, defaults: Sequence[Mapping[str, Any]] | None = None, - paths: list[str] | None = None, + paths: Sequence[str] | None = None, env: Mapping[str, str] | None = None, env_var: str | None = None, root_env_var: str | None = None, @@ -415,7 +415,11 @@ def __init__( *[os.path.join(prefix, "etc", name) for prefix in site.PREFIXES], os.path.join(os.path.expanduser("~"), ".config", name), ] - + else: + # copy so the env-var append below never mutates the caller's sequence + if isinstance(paths, str): + raise TypeError("paths must be a sequence of strings, not a single string") + paths = list(paths) if env_prefix is None: env_prefix = f"{name.upper()}_" if env is None: @@ -458,7 +462,7 @@ def __getitem__(self, item): def pprint(self, **kwargs): return pprint.pprint(self.config, **kwargs) - def collect(self, paths: list[str] | None = None, env: Mapping[str, str] | None = None) -> dict: + def collect(self, paths: Sequence[str] | None = None, env: Mapping[str, str] | None = None) -> dict: """Collect configuration from paths and environment variables Parameters diff --git a/donfig/tests/test_config.py b/donfig/tests/test_config.py index c5148bd..2e5254e 100644 --- a/donfig/tests/test_config.py +++ b/donfig/tests/test_config.py @@ -606,6 +606,21 @@ def test__get_paths(monkeypatch): assert len(paths) == len(set(paths)) +def test_paths_not_mutated(monkeypatch): + monkeypatch.setenv("MYPKG_CONFIG", "foo-bar") + paths = ["/etc/mypkg"] + config = Config("mypkg", paths=paths) + assert config.paths == ["/etc/mypkg", "foo-bar"] + # the caller's list is copied on init, not aliased + assert paths == ["/etc/mypkg"] + + +def test_paths_accepts_any_sequence(monkeypatch): + monkeypatch.setenv("MYPKG_CONFIG", "foo-bar") + config = Config("mypkg", paths=("/etc/mypkg",)) + assert config.paths == ["/etc/mypkg", "foo-bar"] + + def test_serialization(): config = Config(CONFIG_NAME) config.set(one_key="one_value") From 2dff88c48e426dc08168db40d8609a8c69b12dbf Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Mon, 27 Jul 2026 17:19:49 -0400 Subject: [PATCH 2/3] refactor: revert type changes --- donfig/config_obj.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/donfig/config_obj.py b/donfig/config_obj.py index fcae169..cd19c53 100644 --- a/donfig/config_obj.py +++ b/donfig/config_obj.py @@ -399,7 +399,7 @@ def __init__( self, name: str, defaults: Sequence[Mapping[str, Any]] | None = None, - paths: Sequence[str] | None = None, + paths: list[str] | None = None, env: Mapping[str, str] | None = None, env_var: str | None = None, root_env_var: str | None = None, @@ -417,8 +417,6 @@ def __init__( ] else: # copy so the env-var append below never mutates the caller's sequence - if isinstance(paths, str): - raise TypeError("paths must be a sequence of strings, not a single string") paths = list(paths) if env_prefix is None: env_prefix = f"{name.upper()}_" @@ -462,7 +460,7 @@ def __getitem__(self, item): def pprint(self, **kwargs): return pprint.pprint(self.config, **kwargs) - def collect(self, paths: Sequence[str] | None = None, env: Mapping[str, str] | None = None) -> dict: + def collect(self, paths: list[str] | None = None, env: Mapping[str, str] | None = None) -> dict: """Collect configuration from paths and environment variables Parameters From ccf0e9e5fe3934b10de6fd0980aa53a4ca916ace Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Mon, 27 Jul 2026 17:21:15 -0400 Subject: [PATCH 3/3] Update paths --- donfig/config_obj.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/donfig/config_obj.py b/donfig/config_obj.py index cd19c53..738ac7f 100644 --- a/donfig/config_obj.py +++ b/donfig/config_obj.py @@ -416,7 +416,7 @@ def __init__( os.path.join(os.path.expanduser("~"), ".config", name), ] else: - # copy so the env-var append below never mutates the caller's sequence + # copy so the env-var append below never mutates the caller's list paths = list(paths) if env_prefix is None: env_prefix = f"{name.upper()}_"