Vinay Sajip avatar Vinay Sajip committed 1ff6104

Improved handling of old-style classes and added test cases.

Comments (0)

Files changed (2)

src/dictconfig.py

 import logging.handlers
 import re
+import types
 
 IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
 
     
     def configure_custom(self, config):
         """Configure an object with a user-supplied factory."""
-        c = self.resolve(config.pop('()'))
+        c = config.pop('()')
+        if not hasattr(c, '__call__') and hasattr(types, 'ClassType') and type(c) != types.ClassType:
+            c = self.resolve(c)
         props = config.pop('.', None)
         # Check for valid identifiers
         kwargs = dict([(k, config[k]) for k in config if valid_ident(k)])

src/test_dictconfig.py

     def formatException(self, ei):
         return "Got a [%s]" % ei[0].__name__
 
+def formatFunc(format, datefmt=None):
+    return logging.Formatter(format, datefmt)
+
 class CustomHandler(logging.StreamHandler):
     pass
 
         },
     } 
 
+    # As config4 but using an actual callable rather than a string
+    config4a = {
+        'formatters': {
+            'form1' : {
+                '()' : ExceptionFormatter,
+                'format' : '%(levelname)s:%(name)s:%(message)s',
+            },
+            'form2' : {
+                '()' : __name__ + '.formatFunc',
+                'format' : '%(levelname)s:%(name)s:%(message)s',
+            },
+            'form3' : {
+                '()' : formatFunc,
+                'format' : '%(levelname)s:%(name)s:%(message)s',
+            },
+        },
+        'handlers' : {
+            'hand1' : {
+                'class' : 'logging.StreamHandler',
+                'formatter' : 'form1',
+                'level' : 'NOTSET',
+                'stream'  : 'ext://sys.stdout',
+            },
+        },
+        'root' : {
+            'level' : 'NOTSET',
+                'handlers' : ['hand1'],
+        },
+    } 
+
     # config5 specifies a custom handler class to be loaded
     config5 = {
         'formatters': {
             # Original logger output is empty
             self.assert_log_lines([])
 
+    def test_config4a_ok(self):
+        # A config specifying a custom formatter class.
+        with captured_stdout() as output:
+            self.apply_config(self.config4a)
+            #logger = logging.getLogger()
+            try:
+                raise RuntimeError()
+            except RuntimeError:
+                logging.exception("just testing")
+            sys.stdout.seek(0)
+            self.assertEquals(output.getvalue(),
+                "ERROR:root:just testing\nGot a [RuntimeError]\n")
+            # Original logger output is empty
+            self.assert_log_lines([])
+
     def test_config5_ok(self):
         self.test_config1_ok(config=self.config5)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.