Eason09053360 opened a new pull request, #73112:
URL: https://github.com/apache/airflow/pull/73112
## Why
`StructlogCapture.__contains__` backs the `cap_structlog` fixture, which
`caplog` is replaced by on Airflow 3.1+, so it is what every structured log
assertion in the repo goes through.
Its dict branch built the lookup with `operator.itemgetter(*target.keys())`,
whose return type depends on how many keys it is given: a tuple for two or
more, but a **bare value** for one. The expected side is always a tuple, so for
a single-key target `zip(got, want)` iterated that bare value instead of
pairing it up — for a string, comparing its first character against the whole
expected string:
```python
got = "some event" # str, not a tuple
want = ("some event",)
zip(got, want) # -> [("s", "some event")] -> False
```
A single-field assertion therefore never matched, whatever was logged:
```python
assert {"event": "some event", "field1": False} in caplog # True
assert {"event": "some event"} in caplog # False, even
though it was logged
```
This is a false negative, which is the worst failure mode for a test helper
— the natural reading of the red test is that the assertion is wrong, and the
way out is `caplog.text` or a mocked logger, the two patterns
`contributing-docs` asks us to stop using. The `cap_structlog` docstring itself
demonstrates `assert {"field2": [1, 2]} in cap_structlog`, so the documented
example was one of the broken cases. Grepping the repo, there is not a single
one-key dict assertion today.
## What
`devel-common/src/tests_common/test_utils/logs.py` builds the actual values
with `tuple(e[key] for key in target)` instead, which keys off the same dict as
`want` and so keeps the two aligned at any number of keys. A missing key still
raises `KeyError` inside the existing `try` and counts as a non-match.
An empty dict is now rejected with `ValueError`. `itemgetter()` used to
raise `TypeError` on zero keys, and losing that would have turned `assert
expected in caplog` into a vacuous pass whenever a dynamically built `expected`
came out empty.
`StructlogCapture` had no tests;
`devel-common/tests/unit/tests_common/test_utils/test_logs.py` covers the dict
branch — the single-key cases (including the docstring's and a `re.Pattern`
value) fail without this change, and the negative cases pin down that partial
and missing-key targets still do not match.
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes — Claude Code (Opus 5)
Generated-by: Claude Code (Opus 5) following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]