Repository: PyCQA/flake8

Issue:
Exception if HOME is not an existing path
### how did you install flake8?

```console
$ pip install flake8
```


### unmodified output of `flake8 --bug-report`

```json
{
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.9.13",
    "system": "Linux"
  },
  "plugins": [
    {
      "plugin": "mccabe",
      "version": "0.7.0"
    },
    {
      "plugin": "pycodestyle",
      "version": "2.9.0"
    },
    {
      "plugin": "pyflakes",
      "version": "2.5.0"
    }
  ],
  "version": "5.0.1"
}
```


### describe the problem

#### what I expected to happen

flake8 should not raise an exception if $HOME points to an invalid directory

For example, when running as the `nobody` user in a Debian-based Docker image, and $HOME points to `/nonexistent`.

#### commands ran

```console
# sudo -u nobody flake8
Traceback (most recent call last):
  File "/usr/local/bin/flake8", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.9/site-packages/flake8/main/cli.py", line 22, in main
    app.run(argv)
  File "/usr/local/lib/python3.9/site-packages/flake8/main/application.py", line 336, in run
    self._run(argv)
  File "/usr/local/lib/python3.9/site-packages/flake8/main/application.py", line 324, in _run
    self.initialize(argv)
  File "/usr/local/lib/python3.9/site-packages/flake8/main/application.py", line 296, in initialize
    cfg, cfg_dir = config.load_config(
  File "/usr/local/lib/python3.9/site-packages/flake8/options/config.py", line 73, in load_config
    config = _find_config_file(pwd)
  File "/usr/local/lib/python3.9/site-packages/flake8/options/config.py", line 26, in _find_config_file
    home_stat = _stat_key(home) if home != "~" else None
  File "/usr/local/lib/python3.9/site-packages/flake8/options/config.py", line 19, in _stat_key
    st = os.stat(s)
FileNotFoundError: [Errno 2] No such file or directory: '/nonexistent'
```


Discussion:

Patch:
diff --git a/src/flake8/options/config.py b/src/flake8/options/config.py
index f5c93ce..36fe976 100644
--- a/src/flake8/options/config.py
+++ b/src/flake8/options/config.py
@@ -23,7 +23,10 @@ def _stat_key(s: str) -> Tuple[int, int]:
 def _find_config_file(path: str) -> Optional[str]:
     # on windows if the homedir isn't detected this returns back `~`
     home = os.path.expanduser("~")
-    home_stat = _stat_key(home) if home != "~" else None
+    try:
+        home_stat = _stat_key(home) if home != "~" else None
+    except OSError:  # FileNotFoundError / PermissionError / etc.
+        home_stat = None
 
     dir_stat = _stat_key(path)
     cfg = configparser.RawConfigParser()


Test patch:
diff --git a/tests/unit/test_options_config.py b/tests/unit/test_options_config.py
index 7a7c4f7..bdc2208 100644
--- a/tests/unit/test_options_config.py
+++ b/tests/unit/test_options_config.py
@@ -78,6 +78,13 @@ def test_find_config_ignores_homedir(tmp_path):
         assert config._find_config_file(str(subdir)) is None
 
 
+def test_find_config_ignores_unknown_homedir(tmp_path):
+    subdir = tmp_path.joinpath("d")
+
+    with mock.patch.object(os.path, "expanduser", return_value=str(subdir)):
+        assert config._find_config_file(str(tmp_path)) is None
+
+
 def test_load_config_config_specified_skips_discovery(tmpdir):
     tmpdir.join("setup.cfg").write("[flake8]\nindent-size=2\n")
     custom_cfg = tmpdir.join("custom.cfg")