[Python-checkins] gh-89258: Add a getChildren() method to logging.Logger. (GH-96444)
vsajip
webhook-mailer at python.org
Wed Aug 31 05:50:59 EDT 2022
https://github.com/python/cpython/commit/29f1b0bb1ff73dcc28f0ca7e11794141b6de58c9
commit: 29f1b0bb1ff73dcc28f0ca7e11794141b6de58c9
branch: main
author: Vinay Sajip <vinay_sajip at yahoo.co.uk>
committer: vsajip <vinay_sajip at yahoo.co.uk>
date: 2022-08-31T10:50:29+01:00
summary:
gh-89258: Add a getChildren() method to logging.Logger. (GH-96444)
Co-authored-by: Éric <merwok at netwok.org>
files:
A Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst
M Doc/library/logging.rst
M Lib/logging/__init__.py
M Lib/test/test_logging.py
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst
index 319340a39350..c3806b6f5bf8 100644
--- a/Doc/library/logging.rst
+++ b/Doc/library/logging.rst
@@ -170,6 +170,18 @@ is the module's name in the Python package namespace.
.. versionadded:: 3.2
+ .. method:: Logger.getChildren()
+
+ Returns a set of loggers which are immediate children of this logger. So for
+ example ``logging.getLogger().getChildren()`` might return a set containing
+ loggers named ``foo`` and ``bar``, but a logger named ``foo.bar`` wouldn't be
+ included in the set. Likewise, ``logging.getLogger('foo').getChildren()`` might
+ return a set including a logger named ``foo.bar``, but it wouldn't include one
+ named ``foo.bar.baz``.
+
+ .. versionadded:: 3.12
+
+
.. method:: Logger.debug(msg, *args, **kwargs)
Logs a message with level :const:`DEBUG` on this logger. The *msg* is the
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index c3208a21f499..86e1efe6e653 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -1828,6 +1828,25 @@ def getChild(self, suffix):
suffix = '.'.join((self.name, suffix))
return self.manager.getLogger(suffix)
+ def getChildren(self):
+
+ def _hierlevel(logger):
+ if logger is logger.manager.root:
+ return 0
+ return 1 + logger.name.count('.')
+
+ d = self.manager.loggerDict
+ _acquireLock()
+ try:
+ # exclude PlaceHolders - the last check is to ensure that lower-level
+ # descendants aren't returned - if there are placeholders, a logger's
+ # parent field might point to a grandparent or ancestor thereof.
+ return set(item for item in d.values()
+ if isinstance(item, Logger) and item.parent is self and
+ _hierlevel(item) == 1 + _hierlevel(item.parent))
+ finally:
+ _releaseLock()
+
def __repr__(self):
level = getLevelName(self.getEffectiveLevel())
return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index a67ed07f12c8..0c852fc1eda2 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -3717,6 +3717,20 @@ def test_child_loggers(self):
self.assertIs(c2, logging.getLogger('abc.def.ghi'))
self.assertIs(c2, c3)
+ def test_get_children(self):
+ r = logging.getLogger()
+ l1 = logging.getLogger('foo')
+ l2 = logging.getLogger('foo.bar')
+ l3 = logging.getLogger('foo.bar.baz.bozz')
+ l4 = logging.getLogger('bar')
+ kids = r.getChildren()
+ expected = {l1, l4}
+ self.assertEqual(expected, kids & expected) # might be other kids for root
+ self.assertNotIn(l2, expected)
+ kids = l1.getChildren()
+ self.assertEqual({l2}, kids)
+ kids = l2.getChildren()
+ self.assertEqual(set(), kids)
class DerivedLogRecord(logging.LogRecord):
pass
diff --git a/Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst b/Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst
new file mode 100644
index 000000000000..74300c108c89
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst
@@ -0,0 +1,2 @@
+Added a :meth:`~logging.Logger.getChildren` method to
+:class:`logging.Logger`, to get the immediate child loggers of a logger.
More information about the Python-checkins
mailing list