From: Vinay Sajip Date: Wed, 31 Aug 2022 09:50:29 +0000 (+0100) Subject: gh-89258: Add a getChildren() method to logging.Logger. (GH-96444) X-Git-Tag: v3.12.0a1~507 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=29f1b0bb1ff73dcc28f0ca7e11794141b6de58c9;p=thirdparty%2FPython%2Fcpython.git gh-89258: Add a getChildren() method to logging.Logger. (GH-96444) Co-authored-by: Éric --- 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 @@ class Logger(Filterer): 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 @@ class ChildLoggerTest(BaseTest): 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.