summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrince Roshan <princekrroshan01@gmail.com>2023-05-21 19:17:18 (GMT)
committerGitHub <noreply@github.com>2023-05-21 19:17:18 (GMT)
commit2ade563abc95281be595b6dc58a519e84b74d6e0 (patch)
tree3d10fa5b2904cb0bd4897b9f533ebdd191aa9650
parente033edab12986a9848d883a147c2a929760c7e9b (diff)
downloadcpython-2ade563abc95281be595b6dc58a519e84b74d6e0.zip
cpython-2ade563abc95281be595b6dc58a519e84b74d6e0.tar.gz
cpython-2ade563abc95281be595b6dc58a519e84b74d6e0.tar.bz2
[3.11] gh-103606: Improve error message from logging.config.FileConfig (GH-103628) (#104687)
* gh-103606: Improve error message from logging.config.FileConfig (GH-103628) (cherry picked from commit 152227b569c3a9b87fe0483706f704762ced6d75) plus backport the followup exception change fix to that in #104701
-rw-r--r--Doc/library/logging.config.rst8
-rw-r--r--Lib/logging/config.py23
-rw-r--r--Lib/test/test_logging.py36
3 files changed, 61 insertions, 6 deletions
diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst
index 45dc975..619e040 100644
--- a/Doc/library/logging.config.rst
+++ b/Doc/library/logging.config.rst
@@ -87,6 +87,10 @@ in :mod:`logging` itself) and defining handlers which are declared either in
provides a mechanism to present the choices and load the chosen
configuration).
+ It will raise :exc:`FileNotFoundError` if the file
+ doesn't exist and :exc:`RuntimeError` if the file is invalid or
+ empty.
+
:param fname: A filename, or a file-like object, or an instance derived
from :class:`~configparser.RawConfigParser`. If a
``RawConfigParser``-derived instance is passed, it is used as
@@ -126,6 +130,10 @@ in :mod:`logging` itself) and defining handlers which are declared either in
.. versionadded:: 3.10
The *encoding* parameter is added.
+ .. versionchanged:: 3.11.4
+ An exception will be thrown if the provided file
+ doesn't exist or is invalid or empty.
+
.. function:: listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None)
Starts up a socket server on the specified port, and listens for new
diff --git a/Lib/logging/config.py b/Lib/logging/config.py
index f9ef7b5..7e78a64 100644
--- a/Lib/logging/config.py
+++ b/Lib/logging/config.py
@@ -28,6 +28,8 @@ import errno
import io
import logging
import logging.handlers
+import os
+import queue
import re
import struct
import threading
@@ -58,15 +60,24 @@ def fileConfig(fname, defaults=None, disable_existing_loggers=True, encoding=Non
"""
import configparser
+ if isinstance(fname, str):
+ if not os.path.exists(fname):
+ raise FileNotFoundError(f"{fname} doesn't exist")
+ elif not os.path.getsize(fname):
+ raise RuntimeError(f'{fname} is an empty file')
+
if isinstance(fname, configparser.RawConfigParser):
cp = fname
else:
- cp = configparser.ConfigParser(defaults)
- if hasattr(fname, 'readline'):
- cp.read_file(fname)
- else:
- encoding = io.text_encoding(encoding)
- cp.read(fname, encoding=encoding)
+ try:
+ cp = configparser.ConfigParser(defaults)
+ if hasattr(fname, 'readline'):
+ cp.read_file(fname)
+ else:
+ encoding = io.text_encoding(encoding)
+ cp.read(fname, encoding=encoding)
+ except configparser.ParsingError as e:
+ raise RuntimeError(f'{fname} is invalid: {e}')
formatters = _create_formatters(cp)
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 350f4a5..76bd872 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -1645,6 +1645,42 @@ class ConfigFileTest(BaseTest):
self.apply_config(test_config)
self.assertEqual(logging.getLogger().handlers[0].name, 'hand1')
+ def test_exception_if_confg_file_is_invalid(self):
+ test_config = """
+ [loggers]
+ keys=root
+
+ [handlers]
+ keys=hand1
+
+ [formatters]
+ keys=form1
+
+ [logger_root]
+ handlers=hand1
+
+ [handler_hand1]
+ class=StreamHandler
+ formatter=form1
+
+ [formatter_form1]
+ format=%(levelname)s ++ %(message)s
+
+ prince
+ """
+
+ file = io.StringIO(textwrap.dedent(test_config))
+ self.assertRaises(RuntimeError, logging.config.fileConfig, file)
+
+ def test_exception_if_confg_file_is_empty(self):
+ fd, fn = tempfile.mkstemp(prefix='test_empty_', suffix='.ini')
+ os.close(fd)
+ self.assertRaises(RuntimeError, logging.config.fileConfig, fn)
+ os.remove(fn)
+
+ def test_exception_if_config_file_does_not_exist(self):
+ self.assertRaises(FileNotFoundError, logging.config.fileConfig, 'filenotfound')
+
def test_defaults_do_no_interpolation(self):
"""bpo-33802 defaults should not get interpolated"""
ini = textwrap.dedent("""