]> granicus.if.org Git - python/commitdiff
logging: Allowed filters to be just callables.
authorVinay Sajip <vinay_sajip@yahoo.co.uk>
Tue, 19 Oct 2010 20:53:01 +0000 (20:53 +0000)
committerVinay Sajip <vinay_sajip@yahoo.co.uk>
Tue, 19 Oct 2010 20:53:01 +0000 (20:53 +0000)
Lib/logging/__init__.py
Lib/test/test_logging.py
Misc/NEWS

index 995d313c1184009a0aa4b6ce216693273a9aa65c..551d85e599e0c29b04eced97690e0864d8c69b03 100644 (file)
@@ -604,10 +604,23 @@ class Filterer(object):
         The default is to allow the record to be logged; any filter can veto
         this and the record is then dropped. Returns a zero value if a record
         is to be dropped, else non-zero.
+
+        .. versionchanged: 3.2
+
+           Allow filters to be just callables.
         """
         rv = 1
         for f in self.filters:
-            if not f.filter(record):
+            if hasattr(f, 'filter'):
+                result = f.filter(record)
+            elif hasattr(f, '__call__'):
+                try:
+                    result = f(record)
+                except Exception:
+                    result = True # filter failed, assume a pass
+            else:
+                result = False # we don't know what f is
+            if not result:
                 rv = 0
                 break
         return rv
index ea2ea2eb6750a509e8cd9b670f401c6621d931b4..a738d7a8758d181dd67f1f0b57ad7900c30a398d 100644 (file)
@@ -309,6 +309,35 @@ class BasicFilterTest(BaseTest):
         finally:
             handler.removeFilter(filter_)
 
+    def test_callable_filter(self):
+        # Only messages satisfying the specified criteria pass through the
+        #  filter.
+
+        def filterfunc(record):
+            parts = record.name.split('.')
+            prefix = '.'.join(parts[:2])
+            return prefix == 'spam.eggs'
+
+        handler = self.root_logger.handlers[0]
+        try:
+            handler.addFilter(filterfunc)
+            spam = logging.getLogger("spam")
+            spam_eggs = logging.getLogger("spam.eggs")
+            spam_eggs_fish = logging.getLogger("spam.eggs.fish")
+            spam_bakedbeans = logging.getLogger("spam.bakedbeans")
+
+            spam.info(self.next_message())
+            spam_eggs.info(self.next_message())  # Good.
+            spam_eggs_fish.info(self.next_message())  # Good.
+            spam_bakedbeans.info(self.next_message())
+
+            self.assert_log_lines([
+                ('spam.eggs', 'INFO', '2'),
+                ('spam.eggs.fish', 'INFO', '3'),
+            ])
+        finally:
+            handler.removeFilter(filterfunc)
+
 
 #
 #   First, we define our levels. There can be as many as you want - the only
index 1453453bd341e0089dce61ff72282060a98f2fad..ccab30adaa5a0b36f1dac299d84c435bd38f7089 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -34,6 +34,8 @@ Core and Builtins
 Library
 -------
 
+- logging: Allowed filters to be just callables.
+
 - logging: Added tests for _logRecordClass changes.
 
 - Issue #10092: Properly reset locale in calendar.Locale*Calendar classes.