Skip to content

stdlib: don't clear LogRecord.args before ProcessorFormatter processors run#810

Closed
SarthakB11 wants to merge 1 commit into
hynek:mainfrom
SarthakB11:fix/issue-771
Closed

stdlib: don't clear LogRecord.args before ProcessorFormatter processors run#810
SarthakB11 wants to merge 1 commit into
hynek:mainfrom
SarthakB11:fix/issue-771

Conversation

@SarthakB11
Copy link
Copy Markdown

Summary

In the foreign branch of ProcessorFormatter.format(), record.args = () was being assigned before foreign_pre_chain and the main processors chain ran.
Processors that look at event_dict["_record"].args therefore always saw an empty tuple, even when stdlib was called with positional args like logger.info("a=%s b=%s", "a", "b").

The clear is necessary: once record.msg is replaced with the rendered structlog string, leaving non-empty record.args makes logging.Formatter.format() raise TypeError: not all arguments converted during string formatting.
But it only needs to happen after the processor chain.
The fix moves record.args = () to right before record.msg = ed / super().format(record) and leaves a comment so a future refactor doesn't drop it again.

test_clears_args (the regression guard for the original TypeError) and test_pass_foreign_args_true_sets_positional_args_key still pass.
New test_record_args_accessible_in_processor reproduces #771 at the public API surface and asserts the foreign-pre-chain processor sees record.args == ("a", "b").

Closes #771.

Pull Request Check List

  • I acknowledge this project's AI policy.
  • This pull requests is not from my main branch.
  • There's tests for all new and changed code.
  • New APIs are added to our typing tests in api.py.
    • No new APIs.
  • Updated documentation for changed code.
    • New functions/classes have to be added to docs/api.rst by hand.
      • No new public symbols.
    • Changed/added classes/methods/functions have appropriate versionadded, versionchanged, or deprecated directives.
      • Behavior fix; public contract unchanged.
  • Documentation in .rst and .md files is written using semantic newlines.
  • Changes (and possible deprecations) are documented in the changelog.

@hynek
Copy link
Copy Markdown
Owner

hynek commented May 10, 2026

did you run into the problem yourself too, or did you just try to fix #771? I'm not sure why it should be a problem since we pass args inside of event_dict. Futzing around with stdlib integration is a rather risky endeavor.

@hynek
Copy link
Copy Markdown
Owner

hynek commented May 10, 2026

to wit: if I'm not mistaken this patch changes the behavior of getMessage() (now has interpolation).

@SarthakB11
Copy link
Copy Markdown
Author

You're right. With this patch, processors calling record.getMessage() during the chain would see the interpolated message instead of the format string, which is a behavior change. The reporter's case is already covered by pass_foreign_args=True (sets event_dict["positional_args"]). Closing.

@SarthakB11 SarthakB11 closed this May 10, 2026
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

Successfully merging this pull request may close these issues.

LogRecord.args not accessible

2 participants