Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ def __getitem__(self, key):
# https://github.com/python/cpython/blob/d3c888b4ec15dbd7d6b6ef4f15b558af77c228af/Lib/logging/__init__.py#L1652C34-L1652C48
if key == "lineno":
return self.event.get("lineno") or 0
# process and thread are numeric callsite params formatted with %d, so fall back to a
# number (like lineno above) rather than the "(unknown)" string used for text params;
# otherwise "%(process)d"/"%(thread)d" raises TypeError when the callsite info is absent
# (e.g. warnings routed through the logging bridge).
if key == "process" or key == "thread":
return self.event.get(key) or 0
if key == "filename":
return self.event.get("filename", "(unknown file)")
if key == "funcName":
Expand Down
18 changes: 18 additions & 0 deletions shared/logging/tests/logging/test_percent_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

from unittest import mock

import pytest

from airflow_shared.logging.percent_formatter import PercentFormatRender


Expand All @@ -40,3 +42,19 @@ def test_lineno_is_none(self):
)

assert formatted == "test.py:0 our msg"

@pytest.mark.parametrize(
"event",
[
pytest.param({"event": "our msg"}, id="missing"),
pytest.param({"event": "our msg", "process": None, "thread": None}, id="none"),
],
)
def test_numeric_callsite_without_process_or_thread(self, event):
# Regression for a scheduler crash: a %d specifier for process/thread with no callsite
# info (e.g. a warning routed through the logging bridge) must not raise TypeError.
fmter = PercentFormatRender("%(process)d:%(thread)d %(message)s")

formatted = fmter(mock.Mock(name="Logger"), "info", event)

assert formatted == "0:0 our msg"