mirror of https://github.com/python/cpython
Closes #16110: fileConfig now accepts a pre-initialised ConfigParser instance.
This commit is contained in:
parent
96df7da0ac
commit
cf9e2f2420
|
@ -76,11 +76,23 @@ in :mod:`logging` itself) and defining handlers which are declared either in
|
||||||
|
|
||||||
.. function:: fileConfig(fname, defaults=None, disable_existing_loggers=True)
|
.. function:: fileConfig(fname, defaults=None, disable_existing_loggers=True)
|
||||||
|
|
||||||
Reads the logging configuration from a :mod:`configparser`\-format file
|
Reads the logging configuration from a :mod:`configparser`\-format file.
|
||||||
named *fname*. This function can be called several times from an
|
This function can be called several times from an application, allowing an
|
||||||
application, allowing an end user to select from various pre-canned
|
end user to select from various pre-canned configurations (if the developer
|
||||||
configurations (if the developer provides a mechanism to present the choices
|
provides a mechanism to present the choices and load the chosen
|
||||||
and load the chosen configuration).
|
configuration).
|
||||||
|
|
||||||
|
: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
|
||||||
|
is. Otherwise, a :class:`~configparser.Configparser` is
|
||||||
|
instantiated, and the configuration read by it from the
|
||||||
|
object passed in ``fname``. If that has a :meth:`readline`
|
||||||
|
method, it is assumed to be a file-like object and read using
|
||||||
|
:meth:`~configparser.ConfigParser.read_file`; otherwise,
|
||||||
|
it is assumed to be a filename and passed to
|
||||||
|
:meth:`~configparser.ConfigParser.read`.
|
||||||
|
|
||||||
|
|
||||||
:param defaults: Defaults to be passed to the ConfigParser can be specified
|
:param defaults: Defaults to be passed to the ConfigParser can be specified
|
||||||
in this argument.
|
in this argument.
|
||||||
|
@ -94,6 +106,15 @@ in :mod:`logging` itself) and defining handlers which are declared either in
|
||||||
their ancestors are explicitly named in the
|
their ancestors are explicitly named in the
|
||||||
logging configuration.
|
logging configuration.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4
|
||||||
|
An instance of a subclass of :class:`~configparser.RawConfigParser` is
|
||||||
|
now accepted as a value for ``fname``. This facilitates:
|
||||||
|
|
||||||
|
* Use of a configuration file where logging configuration is just part
|
||||||
|
of the overall application configuration.
|
||||||
|
* Use of a configuration read from a file, and then modified by the using
|
||||||
|
application (e.g. based on command-line parameters or other aspects
|
||||||
|
of the runtime environment) before being passed to ``fileConfig``.
|
||||||
|
|
||||||
.. function:: listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None)
|
.. function:: listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None)
|
||||||
|
|
||||||
|
|
|
@ -61,11 +61,14 @@ def fileConfig(fname, defaults=None, disable_existing_loggers=True):
|
||||||
"""
|
"""
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
cp = configparser.ConfigParser(defaults)
|
if isinstance(fname, configparser.RawConfigParser):
|
||||||
if hasattr(fname, 'readline'):
|
cp = fname
|
||||||
cp.read_file(fname)
|
|
||||||
else:
|
else:
|
||||||
cp.read(fname)
|
cp = configparser.ConfigParser(defaults)
|
||||||
|
if hasattr(fname, 'readline'):
|
||||||
|
cp.read_file(fname)
|
||||||
|
else:
|
||||||
|
cp.read(fname)
|
||||||
|
|
||||||
formatters = _create_formatters(cp)
|
formatters = _create_formatters(cp)
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import logging.handlers
|
||||||
import logging.config
|
import logging.config
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
|
import configparser
|
||||||
import datetime
|
import datetime
|
||||||
import pickle
|
import pickle
|
||||||
import io
|
import io
|
||||||
|
@ -1279,6 +1280,24 @@ class ConfigFileTest(BaseTest):
|
||||||
# Original logger output is empty.
|
# Original logger output is empty.
|
||||||
self.assert_log_lines([])
|
self.assert_log_lines([])
|
||||||
|
|
||||||
|
def test_config0_using_cp_ok(self):
|
||||||
|
# A simple config file which overrides the default settings.
|
||||||
|
with captured_stdout() as output:
|
||||||
|
file = io.StringIO(textwrap.dedent(self.config0))
|
||||||
|
cp = configparser.ConfigParser()
|
||||||
|
cp.read_file(file)
|
||||||
|
logging.config.fileConfig(cp)
|
||||||
|
logger = logging.getLogger()
|
||||||
|
# Won't output anything
|
||||||
|
logger.info(self.next_message())
|
||||||
|
# Outputs a message
|
||||||
|
logger.error(self.next_message())
|
||||||
|
self.assert_log_lines([
|
||||||
|
('ERROR', '2'),
|
||||||
|
], stream=output)
|
||||||
|
# Original logger output is empty.
|
||||||
|
self.assert_log_lines([])
|
||||||
|
|
||||||
def test_config1_ok(self, config=config1):
|
def test_config1_ok(self, config=config1):
|
||||||
# A config file defining a sub-parser as well.
|
# A config file defining a sub-parser as well.
|
||||||
with captured_stdout() as output:
|
with captured_stdout() as output:
|
||||||
|
|
Loading…
Reference in New Issue