diff --git a/CHANGES.md b/CHANGES.md index 5e02027841b..8adaf56049a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -60,6 +60,7 @@ and the first release covered by our new stability policy. - Enable Python 3.10+ by default, without any extra need to specify `--target-version=py310`. (#2758) - Make passing `SRC` or `--code` mandatory and mutually exclusive (#2804) +- Avoid crashing when the user has no homedir (#2814) ### Output diff --git a/src/black/files.py b/src/black/files.py index 18c84237bf0..8348e0d8c28 100644 --- a/src/black/files.py +++ b/src/black/files.py @@ -87,7 +87,7 @@ def find_pyproject_toml(path_search_start: Tuple[str, ...]) -> Optional[str]: if path_user_pyproject_toml.is_file() else None ) - except PermissionError as e: + except (PermissionError, RuntimeError) as e: # We do not have access to the user-level config directory, so ignore it. err(f"Ignoring user configuration directory due to {e!r}") return None @@ -111,6 +111,10 @@ def find_user_pyproject_toml() -> Path: This looks for ~\.black on Windows and ~/.config/black on Linux and other Unix systems. + + May raise: + - RuntimeError: if the current user has no homedir + - PermissionError: if the current process cannot access the user's homedir """ if sys.platform == "win32": # Windows diff --git a/tests/test_black.py b/tests/test_black.py index 2dd284f2cd6..b5dd61585b8 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -10,7 +10,7 @@ import types import unittest from concurrent.futures import ThreadPoolExecutor -from contextlib import contextmanager +from contextlib import contextmanager, redirect_stderr from dataclasses import replace from io import BytesIO from pathlib import Path @@ -1339,6 +1339,21 @@ def test_find_project_root(self) -> None: (src_dir.resolve(), "pyproject.toml"), ) + @patch( + "black.files.find_user_pyproject_toml", + ) + def test_find_pyproject_toml(self, find_user_pyproject_toml: MagicMock) -> None: + find_user_pyproject_toml.side_effect = RuntimeError() + + with redirect_stderr(io.StringIO()) as stderr: + result = black.files.find_pyproject_toml( + path_search_start=(str(Path.cwd().root),) + ) + + assert result is None + err = stderr.getvalue() + assert "Ignoring user configuration" in err + @patch( "black.files.find_user_pyproject_toml", black.files.find_user_pyproject_toml.__wrapped__,