Repository: yt-project/yt

Issue:
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

```bash
.
├── 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


Discussion:
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/yt-users@python.org/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
```patch
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


Resolving patch:
diff --git a/yt/utilities/configure.py b/yt/utilities/configure.py
--- a/yt/utilities/configure.py
+++ b/yt/utilities/configure.py
@@ -127,6 +127,14 @@ def get_global_config_file():
 
     @staticmethod
     def get_local_config_file():
+        path = Path.cwd()
+        while path.parent is not path:
+            candidate = path.joinpath("yt.toml")
+            if candidate.is_file():
+                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):


Test patch: