ENH: add support for setting astropy's cache and config directories via environment variables#17567
Conversation
|
Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.
|
|
👋 Thank you for your draft pull request! Do you know that you can use |
d31ce13 to
f1bac6b
Compare
There was a problem hiding this comment.
my testing strategy is not ideal in that it repeats fixture code but I couldn't find a smart way to avoid that. In particular, parametrized fixtures didn't seem applicable here given the subtle differences between each setup.
These tests are also very likely thread unsafe as they all modify a global state (os.environ). This isn't a problem right now but could be in the future when we start experimenting with free-threaded Python.
|
Thanks! Should I look at this now or should I wait for the CI to be green first? |
|
Feel free to have a look now but I'll be fixing those errors tomorrow. The takeaway message from now is: this can be implemented on top of #17554, but maybe that point doesn't get across as well with a red CI 😅 |
astropy/config/paths.py
Outdated
|
|
||
| """ | ||
| return _get_dir_path(rootname, set_temp_config, "config") | ||
| return set_temp_config.get_dir_path(rootname) |
There was a problem hiding this comment.
I am not sure about using set_temp_config here. It was meant for temporary stuff, not suitable for cases like you want to permanently change the path for a machine.
Currently your patch only deals with cache, but config also should be consistent:
HOME
|__ .astropy
|___ cache
|___ config
I think the ask was to change where HOME points to, which affects both cache and config.
What I had in mind, I think, was simpler, we add one more if in _get_dir_path to check for the new env var first before going to XDG env var (for both cache and config).
Additionally, the user doc would need to make clear of this new option and how it might catch users unawares if they accidentally have those new env var defined, etc.
Also have to make sure we don't break https://docs.astropy.org/en/latest/config/index.html#customizing-config-location-in-affiliated-packages in the process.
There was a problem hiding this comment.
This bit is from #17554. I'll move your comment and answer there !
to clarify, only the second commit on this PR is to be reviewed here.
There was a problem hiding this comment.
Actually never mind, I think I should answer here because the second half of your comment makes the most sense in this context;
I am not sure about using set_temp_config here.
Note that it is already being used. I'm just moving the function around to make it a class method instead of a floating function that takes a class as one of its arguments.
Currently your patch only deals with cache, but config also should be consistent
You're right, it seems I was half-remembering a conversation from #17507. I'll add ASTROPY_CONFIG_DIR too once I stabilized CI (listed both tasks as todos on the original post).
What I had in mind, I think, was simpler, we add one more if in _get_dir_path to check for the new env var first before going to XDG env var (for both cache and config).
that is actually exactly what I did in this branch. It's easier to see if you just look at the second commit.
f1bac6b to
3d12505
Compare
|
Reproducing the failures in CI is a bit costly but feasible: I need to run the whole test suite sequentially. |
|
Epilog: the teardow logic in my test functions was flawed and caused changes to |
407eccc to
0bbc9b6
Compare
|
Once I got tests to be stable (at least locally), adding |
9da2256 to
6445dcd
Compare
…ia environment variables
6445dcd to
a87f45c
Compare
|
With #17554 merged, this is now ready for review. |
eerovaher
left a comment
There was a problem hiding this comment.
Our testing infrastructure sets up temporary cache and configuration directories for the tests to ensure both that the normal cache and configuration do not interfere with the tests and also to ensure that the tests don't leave anything behind in the normal directories. This is set up in conftest.py, astropy/conftest.py, docs/conftest.py and in our test runner using the XDG environment variables. The new Astropy environment variables are supposed to have priority over the XDG variables, so using them will turn off that testing setup unless the setup is updated accordingly.
The config documentation needs to be updated, but pull request currently only adds a change log entry.
| if (usrpth_str := os.getenv(cls._astropy_env_dir)) is not None: | ||
| usrpth = Path(usrpth_str).expanduser() | ||
|
|
||
| if usrpth.is_file(): | ||
| raise FileExistsError( | ||
| f"Cannot create directory under {usrpth_str} as requested " | ||
| f"via the environment variable {cls._astropy_env_dir}: " | ||
| "a file with this name already exists." | ||
| ) | ||
|
|
||
| if not usrpth.parent.exists(): | ||
| raise FileNotFoundError( | ||
| f"Cannot create directory under {usrpth_str} as requested " | ||
| f"via the environment variable {cls._astropy_env_dir}: " | ||
| f"the parent directory {usrpth.parent} does not exist." | ||
| ) | ||
| usrpth.mkdir(exist_ok=True) | ||
| return usrpth.resolve() |
There was a problem hiding this comment.
It would be simplest both for us and for the users if the effect of the new Astropy-specific environment variables would be as similar as possible to the effect of the already available XDG environment variables. My (naive) expectation is that the code that handles that should look something like
for env_dir in (cls._astropy_env_dir, cls._xdg_env_dir):
...Why is there a separate code block for the new functionality?
There was a problem hiding this comment.
I can't remember what my reasoning was, maybe I was just trying to get the most simple behavior right from the get go; the existing logic for XDG variables is quite complex and I probably thought I couldn't test it all efficiently.
| usrpth.mkdir(exist_ok=True) | ||
| return usrpth.resolve() | ||
|
|
||
| if (xch := cls._temp_path) is not None: |
There was a problem hiding this comment.
cls._temp_path being handled after the Astropy environment variables means that set_temp_cache and set_temp_config will fail silently at runtime if the corresponding Astropy environment variable is used. The fact that this is not being caught be the tests means that we need to add tests that would check which directory customization mechanism has priority if multiple are used simultaneously.
| def _cleanup_environment(env_var_name: str, old_value: str | None) -> None: | ||
| if old_value is None: | ||
| os.environ.pop(env_var_name) | ||
| else: | ||
| os.environ[env_var_name] = old_value |
There was a problem hiding this comment.
Why are you implementing this functionality yourself instead of making use of pytest monkeypatching?
There was a problem hiding this comment.
I try to reserve mock/monkeypatching as last resorts because I think they are not well understood and tend to effectively make tests harder to read or refactor (see for instance #16659).
There was a problem hiding this comment.
You have added several new tests, but you have not modified any of the existing ones. I would have thought that the tests involving the XDG environment variables could be rewritten to be parametrized tests that check both the XDG and the new Astropy environment variables.
pllim
left a comment
There was a problem hiding this comment.
Thanks!
What is the intended design? That is, if both XDG and ASTROPY variables are defined, which would take precedence? All this should be documented in the user facing doc.
|
p.s. Ooops I didn't see #17567 (review) before posting my comment as I had an outdated tab open. |
|
Thank you both for reviewing this. In hindsight, I realize my approach is different enough from what I should have done that I prefer replacing this PR with a brand new one instead of mutating this one so much that it doesn't retain any of its history. I'll move it to draft for now. |
|
Closing this as the alternative PR #17640 appears to be converging. |
Description
This is a proof of concept solution to #17507, based atop #17554
Fixes #17507
TODO:
ASTROPY_CACHE_DIRASTROPY_CONFIG_DIR