Logging messages with dictionary args in Python 2.4b1 leads to exception

Paul Clinch pclinch at internet-glue.co.uk
Wed Oct 20 06:46:16 EDT 2004


Stefan Behnel <behnel_ml at dvs1.informatik.tu-darmstadt.de> wrote in message news:<cl34oq$7fk$1 at lnx107.hrz.tu-darmstadt.de>...
> Hi!
> 
> I'm trying to do this in Py2.4b1:
> 
> -------------------------------
> import logging
> values = {'test':'bla'}
> logging.log(logging.FATAL, 'Test is %(test)s', values)
> -------------------------------
> 
> This leads to en exception:
> 
> -----------------------------
> Traceback (most recent call last):
>    File "/usr/lib/python2.4/logging/__init__.py", line 692, in emit
>      msg = self.format(record)
>    File "/usr/lib/python2.4/logging/__init__.py", line 578, in format
>      return fmt.format(record)
>    File "/usr/lib/python2.4/logging/__init__.py", line 368, in format
>      record.message = record.getMessage()
>    File "/usr/lib/python2.4/logging/__init__.py", line 239, in getMessage
>      msg = msg % self.args
> TypeError: format requires a mapping
> -----------------------------
> 
Not sure about 2.4 but but in 2.3:-
logging.fatal( 'Test is %(test)s', values)

with the same error, however :-
logging.fatal( 'Test is %(test)s' % values)

is fine. An why shouldn't you use it in this fashion?

> Now, values /is/ a mapping. I looked into logging/__init__.py, but I can 
> only see that the '*args' parameter (as which 'values' is fed in) should 
> have been unpacked like this in logging.log():
> 
> apply(root.log, (level, msg)+args, kwargs)
> 
> Which should lead to the second argument being '(level, msg, args)' in my 
> understanding and which should allow using dicts when doing this later on 
> in LogRecord:
> 
> msg = msg % self.args
> 

*args is not a mapping, its a tuple. Positional arguments in the
format string will be found.

> Now, I'm somewhat confused that this doesn't work and I'm also worried 
> that this is only done in the module methods and not inside the class that 
> actually handles the logging (the root object in this case). This should 
> encourage a diverting behaviour of the module methods and the Logger 
> object methods with the same name. This looks like a bug to me. Adding the 
> tuple should /only/ be done inside the class, not in the module functions.
> 
> Wouldn't it be better to handle dictionaries directly inside LogRecord? 
> Something like this would do the trick:
> 
> -----------------------
> if len(self.args) == 1:
>    msg = msg % self.args[0] # may be a single value or a dictionary
> else:
>    msg = msg % self.args    # looks like a value tuple
> -----------------------
> 
> Could anyone please comment on this?
> 
> Stefan

I haven't read the source so I punt on commenting.

Regards, Paul Clinch



More information about the Python-list mailing list