diff --git a/docs/README.md b/docs/README.md index 13a21a5..2e0284f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -51,6 +51,22 @@ Easily indicate that some functionality is being deprecated Raises a warning like `DeprecationWarning: __main__.foo is deprecated: Use bar(a, b) instead. It is not guaranteed to be in service in vers. 0.5.0 foo(1, 2)` +## Directory context + +A context manager that changes the current working directory to the given path upon entering the context and reverts to the original directory upon exiting. +If the specified path does not exist, it is created. + +```python +>>> import os +>>> from pyiron_snippets.directory_context import set_directory +>>> directory_before_context_is_applied = os.getcwd() +>>> with set_directory("tmp"): +... os.path.relpath(os.getcwd(), directory_before_context_is_applied) +'tmp' + +``` + + ## DotDict A dictionary that allows dot-access. Has `.items()` etc. diff --git a/pyiron_snippets/directory_context.py b/pyiron_snippets/directory_context.py new file mode 100644 index 0000000..bbf8eb6 --- /dev/null +++ b/pyiron_snippets/directory_context.py @@ -0,0 +1,35 @@ +import os +from contextlib import contextmanager +from pathlib import Path + + +@contextmanager +def set_directory(path: Path | str): + """ + A context manager that changes the current working directory to the given path + upon entering the context and reverts to the original directory upon exiting. + If the specified path does not exist, it is created. + + Parameters: + path: Path | str + The target directory path to set as the current working directory. + If it does not exist, it will be created. + + Examples: + Change the directory to the path "tmp" within the context: + + >>> import os + >>> from pyiron_snippets.directory_context import set_directory + >>> directory_before_context_is_applied = os.getcwd() + >>> with set_directory("tmp"): + ... os.path.relpath(os.getcwd(), directory_before_context_is_applied) + 'tmp' + + """ + origin = Path().absolute() + try: + os.makedirs(path, exist_ok=True) + os.chdir(path) + yield + finally: + os.chdir(origin) diff --git a/tests/unit/test_directory_context.py b/tests/unit/test_directory_context.py new file mode 100644 index 0000000..bccba68 --- /dev/null +++ b/tests/unit/test_directory_context.py @@ -0,0 +1,19 @@ +import os +import unittest + +from pyiron_snippets.directory_context import set_directory + + +class TestContextDirectory(unittest.TestCase): + def test_set_directory(self): + current_directory = os.getcwd() + test_directory = "context" + with set_directory(path=test_directory): + context_directory = os.getcwd() + self.assertEqual( + os.path.relpath(context_directory, current_directory), test_directory + ) + + +if __name__ == "__main__": + unittest.main()