Enable ruff B015 to catch silent no-op comparisons in tests#66977
Merged
shahar1 merged 5 commits intoMay 16, 2026
Conversation
Bare `actual == expected` expressions (missing `assert`) silently pass regardless of correctness. Enable ruff rule B015 (useless-comparison) to make this a lint error, and add `assert` to all 26 existing instances found across airflow-core, task-sdk, and providers (amazon, cncf, google).
ff2e36f to
7dfec04
Compare
`.calls` is not a real MagicMock attribute; accessing it auto-creates a child MagicMock. The expression `mock.calls[0] == []` was a silent no-op that B015 correctly caught. Adding `assert` exposed that the comparison always evaluates to False. Replace with `assert_not_called()`, which correctly verifies that `revoke_task` routes through `kube_scheduler.patch_pod_revoked()` rather than calling `patch_namespaced_pod` directly.
- test_bedrock: set ensure_unique_job_name on the operator before execute so the not-ensure-unique parametrize cases actually test the right path, and use pytest.raises for the cases where a conflict error is expected - test_emr_serverless (create): remove dead get_application mock setup and wrong call-count assertion; the operator uses waiters, not direct polling - test_emr_serverless (start job): correct expected call_count from 2 to 1; the operator calls get_application once (state CREATED is in SUCCESS_STATES so no retry loop)
Lee-W
reviewed
May 15, 2026
jscheffl
approved these changes
May 15, 2026
Contributor
jscheffl
left a comment
There was a problem hiding this comment.
Cool! I assume you can work on making CI green in parallel :-D
- Add missing `assert` to three bare comparisons caught by the new B015 rule: test_pod_template_file.py, test_otel_logger.py (×2) - Fix the MappedOperator task_type assertion in test_dag_serialization: `type(task).__name__` gives the wrapper class (`DecoratedMappedOperator`) but `operator_class["task_type"]` stores the underlying operator's name (`task.operator_class.__name__`, e.g. `_PythonDecoratedOperator`)
The operator uses json.dump() which writes strings incrementally to the file handle; the previous assertion expected bytes in a single write call. Also adds the missing mock_file.write.reset_mock() between the CSV and JSON sub-tests so write calls don't accumulate across sections.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bare
actual == expectedexpressions in tests silently evaluate and discard their result — the test passes regardless of correctness. This is exactly what happened in #66894 (fourtest_serializemethods in the Vertex AI triggers had been vacuously passing for years).Changes
pyproject.toml: addB015(useless-comparison) toextend-select. This rule fires on any bare comparison expression used as a statement.assertto all 26 existing violations found by the rule acrossairflow-core,task-sdk, and providersamazon,cncf/kubernetes,google).With this in place, any future bare comparison in a test is a lint error caught before CI runs.
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Sonnet 4.6) following the guidelines