Repository navigation
bpo-34844: logging.Formatter enhancement - Ensure styles and fmt matches in logging.Formatter #9703
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
Changes from 1 commit
66bbddf
0eaaf25
f4f6a60
d51e186
cc2cfbd
7c24e46
abd868d
c1359bb
921ba33
8484f29
4c35216
6eee298
aab0c46
59879e9
43c0b34
908c3ec
d73ab3a
ff05742
2664f85
74ca6a2
de1243f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -419,6 +419,10 @@ def makeLogRecord(dict): | |
| #--------------------------------------------------------------------------- | ||
| # Formatter classes and functions | ||
| #--------------------------------------------------------------------------- | ||
| _str_formatter = StrFormatter() | ||
| del StrFormatter | ||
|
|
||
|
|
||
| class PercentStyle(object): | ||
|
|
||
| default_format = '%(message)s' | ||
|
|
@@ -438,7 +442,7 @@ def validate(self): | |
| self._invalid_raise() | ||
|
|
||
| def _invalid_raise(self, additional_message=None): | ||
| msg = 'Invalid format %s for %s style' % (self._fmt, self.default_format[0]) | ||
| msg = "Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0]) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can just use |
||
| if additional_message: | ||
| msg = "%s, %s" % (msg, additional_message) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to use single quotes where possible. |
||
| raise ValueError(msg) | ||
|
|
@@ -458,29 +462,38 @@ class StrFormatStyle(PercentStyle): | |
| asctime_format = '{asctime}' | ||
| asctime_search = '{asctime' | ||
| # This is only for validating the format_spec | ||
| validation_pattern = re.compile(r"^((.)?[<>=]?[+ -]?[#0]?[\d]*,?[\.\d]*)?[bcdefgnosx%]?$", re.I) | ||
| validation_pattern = re.compile(r"^(.?[<>=^]?[+ -]?#?0?[\d]*,?(\.[\d]*)?)?[bcdefgnosx%]?$", re.I) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had a bit of a think about this whole area - I think both brace and dollar validation need a bit more work. I put my thoughts into this Gist - see what you think and if you can adapt some of it. The test cases in there might be useful, too - and you could try adding to them using combinations I haven't tried. I also think maybe we should add a It means that the |
||
| spec_fmt_pattern = re.compile(r"(?<=(?<!\{)\{)[^{}]*(?=\}(?!\}))") | ||
|
|
||
| def _format(self, record): | ||
| return self._fmt.format(**record.__dict__) | ||
|
|
||
| def validate(self): | ||
| """Validate the input format, ensure it is the correct string formatting style""" | ||
| def _validate(self, fmt): | ||
| try: | ||
| fields = [] | ||
| for _, field_name, spec, conversion in StrFormatter().parse(self._fmt): | ||
| for _, field_name, spec, conversion in _str_formatter.parse(fmt): | ||
|
|
||
| if field_name and "-" not in field_name: | ||
| if field_name: | ||
| if "-" in field_name: | ||
| raise ValueError("Invalid field name '%s', cannot have '-' in field name") | ||
| if conversion and conversion not in "rsa": | ||
| raise ValueError("invalid conversion %s for field %s" % (conversion, field_name)) | ||
| if spec and not self.validation_pattern.search(spec): | ||
| raise ValueError("invalid spec %s for %s" % (spec[-1], field_name)) | ||
| raise ValueError("invalid conversion '%s' for '%s' field" % (conversion, field_name)) | ||
| if spec: | ||
| if self.spec_fmt_pattern.search(spec): | ||
| return self._validate(spec) | ||
| elif not self.validation_pattern.search(spec): | ||
| raise ValueError("invalid spec %s for '%s' field" % (spec[-1], field_name)) | ||
|
|
||
| fields.append(field_name) | ||
| if not fields: | ||
| raise ValueError("No fields found for format %s" % self._fmt) | ||
| raise ValueError("no fields found") | ||
| except ValueError as e: | ||
| self._invalid_raise(e) | ||
|
|
||
| def validate(self): | ||
| """Validate the input format, ensure it is the correct string formatting style""" | ||
| self._validate(self._fmt) | ||
|
|
||
|
|
||
| class StringTemplateStyle(PercentStyle): | ||
| default_format = '${message}' | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would prefer the name
_raise_invalidas the verb should come first, generally.