Closes #16110: fileConfig now accepts a pre-initialised ConfigParser instance.

This commit is contained in:
Vinay Sajip 2012-10-09 09:06:03 +01:00
parent 96df7da0ac
commit cf9e2f2420
3 changed files with 52 additions and 9 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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: