nhairs / nhairs/python-json-logger

parse() reads escaped %% and {{ }} as fields, and {-style format specs as part of the field name

Open
#74 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
270
Forks
21
PR merge metrics
No merged PRs in 30d

Description

parse() treats escaped literals as fields for the % and { styles, and reads a { style conversion/format spec as part of the field name.

#69 fixed this for $ ($$ is now skipped). The other two styles have the same class of problem.

The quickstart says the standard-library styles exist so you can use these formatters "with your existing config", so a format that works with logging.Formatter should select the same fields here.

Oracle used: the substitution engine itself — fmt % tracking_dict for %, string.Formatter().parse() for {, string.Template(fmt).get_identifiers() for $. Over 37 formats: $ 7/7 agree, % and { diverge 13 times.

style fmt parse() actually substituted
% "%(a)s%%(b)s%(c)s" a, b, c a, c
% "%%(x)s%%(y)s" x, y none
{ "{a}{{b}}{c}" a, {b, c a, c
{ "{levelname:>8}" levelname:>8 levelname
{ "{message!r}" message!r message

The { cases look the most likely to bite: "{levelname:>8} {message}" is an ordinary stdlib format (StrFormatStyle.validate() accepts it), and with a JSON formatter it emits a "levelname:>8": null key while dropping levelname entirely.

Happy to put up a PR — the shape I have working is % skipping %% the same way $ skips $$, and { using string.Formatter, which is what logging.StrFormatStyle.validate already parses the same string with (it also handles nested specs like {levelname:>{width}}, which a regex does not).

Investigated with AI assistance; the differential above was run locally and I have reviewed and tested the result.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating parse() and its existing tests, then compare its % and { style handling with the substitution behavior described in the issue and the standard-library parsers named there. Add coverage for escaped literals, conversion and format specifications, including nested specs; done means parse() selects exactly the fields that are actually substituted without changing the already-correct $ behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.