diff options
-rw-r--r-- | Doc/library/logging.rst | 12 | ||||
-rw-r--r-- | Lib/logging/__init__.py | 19 | ||||
-rw-r--r-- | Lib/test/test_logging.py | 14 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-08-29-07-04-03.gh-issue-89258.ri7ncj.rst | 2 |
4 files changed, 47 insertions, 0 deletions
diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 319340a..c3806b6 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 c3208a2..86e1efe 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 a67ed07..0c852fc1 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 0000000..74300c1 --- /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. |