yt
yt copied to clipboard
ENH: "local" config file upward lookup
Bug report
Bug summary
Since yt 4.0 we support two locations to store a configuration file yt.toml
, namely $XDG_CONFIG/yt/yt.toml
(this is the global configuration) and ./yt.toml
(local)
Now, assuming a data exploration project organised into subfolders, for instance
.
├── scripts
│ ├── exp1
│ │ ├── t1.py
│ │ ├── t2.py
│ │ └── t3.py
│ └── exp2
│ ├── t1.py
│ ├── t2.py
│ └── t3.py
└── yt.toml
The results of any script will differ depending on wether it's launched from the top level of the project (where yt.toml
lives) or from within their respective containing directories.
To solve this, we could implement an upward lookup routine to check for yt.toml
files in all parents directories until it is found (or we reach root /
).
There is a precedent to the proposed behaviour: many tools already implement this mechanism, for instance
- flake8 https://github.com/PyCQA/flake8/blob/ca573a7ccf2d4a1c7df0b577bb6d3455c941e828/src/flake8/options/config.py#L17
- black https://github.com/psf/black/blob/1af29fbfa507daa8166e7aac659e9b2ff2b47a3c/src/black/files.py#L84
I seem to remember we already had this discussion but I cannot find it anymore. Was it on the mailing list? Maybe here https://mail.python.org/archives/list/[email protected]/message/7E5A4WGVTRAUMVYXOEPHZO5TTE7JWYTQ/?
I think you're right but I don't know where it happened originally. Anyway I wanted to bring it up again now that #3626 was merged and the code involved is less intricate.
This patch does what I'm proposing, but I'll refrain from opening a PR for now
diff --git a/yt/utilities/configure.py b/yt/utilities/configure.py
index 4370303d3..961fe9d60 100644
--- a/yt/utilities/configure.py
+++ b/yt/utilities/configure.py
@@ -1,4 +1,5 @@
import os
+from pathlib import Path
from typing import Callable, List
# TODO: import tomllib from the standard library instead in Python >= 3.11
@@ -108,6 +109,15 @@ class YTConfig:
@staticmethod
def get_local_config_file():
+ path = Path.cwd()
+ while path.parent is not path:
+ candidate = path.joinpath("yt.toml")
+ if candidate.is_file():
+ print(f"found config at {str(candidate)}")
+ return os.path.abspath(candidate)
+ else:
+ path = path.parent
+
return os.path.join(os.path.abspath(os.curdir), "yt.toml")
def __setitem__(self, args, value):
I don't remember why I might have had objections to this, but it seems to me that this is a reasonable thing to do. It's also what git does, right?
Though not explicitly stated, I think it is, yes.
Finally, Git looks for configuration values in the configuration file in the Git directory (.git/config) of whatever repository you’re currently using https://www.git-scm.com/book/en/v2/Customizing-Git-Git-Configuration
I'll will open a PR