]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-89258: Add a getChildren() method to logging.Logger. (GH-96444)
authorVinay Sajip <vinay_sajip@yahoo.co.uk>
Wed, 31 Aug 2022 09:50:29 +0000 (10:50 +0100)
committerGitHub <noreply@github.com>
Wed, 31 Aug 2022 09:50:29 +0000 (10:50 +0100)
Co-authored-by: Éric <merwok@netwok.org>
Doc/library/logging.rst
Lib/logging/__init__.py
Lib/test/test_logging.py
Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst [new file with mode: 0644]

index 319340a39350e80b8dd9aa936331dd864cb1f859..c3806b6f5bf81cd09026fb83c2a60868832450d0 100644 (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
index c3208a21f499abedd75dd433fc3498c0ac4ab6ee..86e1efe6e653accaad08a06f04dd1119230b246a 100644 (file)
@@ -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)
index a67ed07f12c87cedba93271e79c1e6c7cb08b527..0c852fc1eda239cfdf9b1d1e694967710b6cbad6 100644 (file)
@@ -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 (file)
index 0000000..74300c1
--- /dev/null
@@ -0,0 +1,2 @@
+Added a :meth:`~logging.Logger.getChildren` method to
+:class:`logging.Logger`, to get the immediate child loggers of a logger.