Fix Config.from_file silent error handling to include ENOTDIR

Config.from_file() was missing errno.ENOTDIR in its silent error
handling, while Config.from_pyfile() correctly includes it.

When a component of the config file path is a regular file rather
than a directory (e.g., trying to load 'file/config.json' where
'file' is a regular file), from_file(silent=True) would raise an
OSError instead of silently returning False.

This adds ENOTDIR to match from_pyfile's behavior and adds a test
to verify the fix.

Fixes #5912
This commit is contained in:
r266-tech 2026-03-23 02:17:36 +08:00
parent 4cae5d8e41
commit 6422bf669e
2 changed files with 14 additions and 1 deletions

View file

@ -293,7 +293,7 @@ class Config(dict): # type: ignore[type-arg]
with open(filename, "r" if text else "rb") as f:
obj = load(f)
except OSError as e:
if silent and e.errno in (errno.ENOENT, errno.EISDIR):
if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR):
return False
e.strerror = f"Unable to load configuration file ({e.strerror})"

View file

@ -195,6 +195,19 @@ def test_config_missing_file():
assert not app.config.from_file("missing.json", load=json.load, silent=True)
def test_config_from_file_not_a_directory(tmp_path):
"""from_file with silent=True returns False when a path component is not a
directory, matching the behavior of from_pyfile."""
file_in_tmp = tmp_path / "not_a_dir"
file_in_tmp.write_text("{}")
app = flask.Flask(__name__)
app.config.root_path = str(tmp_path)
# not_a_dir/config.json: not_a_dir is a file, not a directory
assert not app.config.from_file(
"not_a_dir/config.json", load=json.load, silent=True
)
def test_custom_config_class():
class Config(flask.Config):
pass