Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

colorlog.LevelFormatter does not allow to use dict for fmt parameter on python 3.8 #77

Closed
PanovEduard opened this issue Dec 10, 2019 · 5 comments

Comments

@PanovEduard
Copy link

Traceback (most recent call last):
File "D:/gitrep/DevOpsCI/DiasoftBuild/DiasoftBuild.py", line 36, in
from LogInit import file_formatter
File "D:\gitrep\DevOpsCI\DiasoftBuild\CommonLib\LogInit.py", line 98, in
formatter = LevelFormatter(
File "C:\Users\panov-ea\AppData\Roaming\Python\Python38\site-packages\colorlog\colorlog.py", line 160, in init
super(LevelFormatter, self).init(
File "C:\Users\panov-ea\AppData\Roaming\Python\Python38\site-packages\colorlog\colorlog.py", line 91, in init
super(ColoredFormatter, self).init(fmt, datefmt, style)
File "C:\Users\panov-ea\AppData\Local\Programs\Python\Python38-32\lib\logging_init_.py", line 576, in init
self.style.validate()
File "C:\Users\panov-ea\AppData\Local\Programs\Python\Python38-32\lib\logging_init
.py", line 456, in validate
for _, fieldname, spec, conversion in _str_formatter.parse(self._fmt):
File "C:\Users\panov-ea\AppData\Local\Programs\Python\Python38-32\lib\string.py", line 261, in parse
return _string.formatter_parser(format_string)
TypeError: expected str, got dict

@Northbadge
Copy link
Contributor

Seems like Python-logging was updated in 3.8 with validation checks.
python/cpython#9703

Adding a validate=false flag into the logging.formatter initializer for Python >= 3.8 should fix it

In my case, I just commented out the validate call in my logging lib.

@borntyping
Copy link
Owner

Could you provide a minimal code example you would expect to work? I'm very unclear on what usage would require passing a dictionary instead of a string as the fmt parameter.

@Northbadge
Copy link
Contributor

Northbadge commented Dec 23, 2019

Could you provide a minimal code example you would expect to work? I'm very unclear on what usage would require passing a dictionary instead of a string as the fmt parameter.

The LevelFormatter class seems to have specifically built in support for dicts as the fmt parameter

class LevelFormatter(ColoredFormatter):
"""An extension of ColoredFormatter that uses per-level format strings."""
def __init__(self, fmt=None, datefmt=None, style='%',
log_colors=None, reset=True,
secondary_log_colors=None):
"""
Set the per-loglevel format that will be used.
Supports fmt as a dict. All other args are passed on to the
``colorlog.ColoredFormatter`` constructor.
:Parameters:
- fmt (dict):
A mapping of log levels (represented as strings, e.g. 'WARNING') to
different formatters. (*New in version 2.7.0)
(All other parameters are the same as in colorlog.ColoredFormatter)
Example:
formatter = colorlog.LevelFormatter(fmt={
'DEBUG':'%(log_color)s%(msg)s (%(module)s:%(lineno)d)',
'INFO': '%(log_color)s%(msg)s',
'WARNING': '%(log_color)sWARN: %(msg)s (%(module)s:%(lineno)d)',
'ERROR': '%(log_color)sERROR: %(msg)s (%(module)s:%(lineno)d)',
'CRITICAL': '%(log_color)sCRIT: %(msg)s (%(module)s:%(lineno)d)',
})

There's an example there. Perhaps it could be reworked to not store the dict into fmt, but that would seem like it's just a complicated way of bypassing the validation check.

@borntyping
Copy link
Owner

My mistake, it's a long time since I've looked at the code for LevelFormatter and the original issue wasn't very clear.

@borntyping
Copy link
Owner

Fix released as version 4.1.0: https://pypi.org/project/colorlog/4.1.0/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants