gh-89258: Add a getChildren() method to logging.Logger. (GH-96444)

Co-authored-by: Éric <merwok@netwok.org>
This commit is contained in:
Vinay Sajip 2022-08-31 10:50:29 +01:00 committed by GitHub
parent f7e7bf161a
commit 29f1b0bb1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 0 deletions

View file

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

View file

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

View file

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

View file

@ -0,0 +1,2 @@
Added a :meth:`~logging.Logger.getChildren` method to
:class:`logging.Logger`, to get the immediate child loggers of a logger.