Skip to content

feat(workflow_engine): Add in hook for producing occurrences from the stateful detector - #1

Open
linxia0415 wants to merge 2 commits into
masterfrom
pr-80168
Open

feat(workflow_engine): Add in hook for producing occurrences from the stateful detector#1
linxia0415 wants to merge 2 commits into
masterfrom
pr-80168

Conversation

@linxia0415

@linxia0415 linxia0415 commented Jun 4, 2026

Copy link
Copy Markdown

This adds a hook that can be implemented to produce an occurrence specific to the detector that is subclassing the StatefulDetector.

Also change the signature of evaluate to return a dict keyed by groupkey instead of a list. This helps avoid the chance of duplicate results for the same group key.

Summary by CodeRabbit

  • Refactor

    • Refactored detector evaluation system to improve handling of group-based detection results and state management.
    • Updated detector handler architecture for enhanced result processing and occurrence tracking.
  • Tests

    • Updated test suite to align with detector evaluation framework changes.

… stateful detector

This adds a hook that can be implemented to produce an occurrence specific to the detector that is subclassing the StatefulDetector.

Also change the signature of evaluate to return a dict keyed by groupkey instead of a list. This helps avoid the chance of duplicate results for the same group key.
@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This pull request refactors the detector evaluation system to return dictionary-keyed results instead of lists, introduces an occurrence-building abstraction for stateful handlers, adds a detector group-type lookup property, and updates all associated tests to validate the new contracts and data flows.

Changes

Detector evaluation refactoring

Layer / File(s) Summary
Handler interface contract changes
src/sentry/workflow_engine/processors/detector.py
DetectorHandler.evaluate() and StatefulDetectorHandler.evaluate() return dict[DetectorGroupKey, DetectorEvaluationResult] instead of lists. New abstract method build_occurrence_and_event_data(...) on StatefulDetectorHandler constructs IssueOccurrence and event payloads for non-OK priority transitions.
Detector model group-type lookup
src/sentry/workflow_engine/models/detector.py
Added Detector.group_type property for registered GroupType lookup. Updated Detector.detector_handler to use self.group_type instead of inline registry calls.
Stateful handler evaluation and accumulation
src/sentry/workflow_engine/processors/detector.py
StatefulDetectorHandler.evaluate accumulates results into a dictionary keyed by group_key. evaluate_group_key_value uses build_occurrence_and_event_data(...) in non-OK branches and types result as `StatusChangeMessage
Process detectors orchestration
src/sentry/workflow_engine/processors/detector.py
process_detectors expects dict-based evaluation results, iterates over detector_results.values(), and emits Kafka messages for non-None entries.
MetricAlertDetectorHandler migration
src/sentry/incidents/grouptype.py
MetricAlertDetectorHandler migrated from DetectorHandler to StatefulDetectorHandler[QuerySubscriptionUpdate]; non-stateful evaluate(...) method removed.
Test infrastructure and mocks
tests/sentry/workflow_engine/processors/test_detector.py
Test imports updated; MockDetectorStateHandler now implements build_occurrence_and_event_data. BaseDetectorHandlerTest manages StatusChangeMessage equality patching and provides helper methods for detector/handler construction.
Process detectors test suite
tests/sentry/workflow_engine/processors/test_detector.py
TestProcessDetectors refactored to expect dict-based results. Assertions validate PayloadType.OCCURRENCE Kafka calls with exact occurrence and event_data. New build_mock_occurrence_and_event helper constructs deterministic test occurrences.
State and evaluation test suite
tests/sentry/workflow_engine/processors/test_detector.py
TestGetStateData, TestCommitStateUpdateData, TestEvaluate, TestEvaluateGroupKeyValue converted to BaseDetectorHandlerTest inheritance. Tests updated to validate dict results, no-condition-group handling, dedupe metrics, and status transitions with occurrence/event-data payloads.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

🐰 From list to dict, the detectors dance,
Occurrence builders take their stance,
Group keys now index every call,
Stateful handlers flourish tall,
Tests aligned to new contracts' thrall!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically describes the main objective: adding a hook for producing occurrences from stateful detectors. The changes confirm this is the primary focus, with a secondary refactoring of evaluate return types from list to dict.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr-80168

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/sentry/incidents/grouptype.py`:
- Around line 10-12: MetricAlertDetectorHandler currently subclasses
StatefulDetectorHandler but omits the required abstract methods causing a
TypeError at instantiation (see
Detector.detector_handler/group_type.detector_handler); either implement the
required methods—counter_names, get_dedupe_value, get_group_key_values, and
build_occurrence_and_event_data—on MetricAlertDetectorHandler with appropriate
stubs that return valid types for the stateful flow, or change the base class
back to DetectorHandler until a full stateful implementation is ready; update
MetricAlertDetectorHandler to include these method definitions (matching
signatures expected by StatefulDetectorHandler) so instantiation no longer
fails.

In `@tests/sentry/workflow_engine/processors/test_detector.py`:
- Around line 190-192: The test uses
build_mock_occurrence_and_event(detector.detector_handler, "group_2", 6,
PriorityLevel.HIGH) but group_vals defines "group_2" as 10, so update the
expected occurrence fixture to use the actual group_2 value (10) instead of 6;
locate the call to build_mock_occurrence_and_event (variables occurrence_2 and
event_data_2) and change the numeric argument to match group_vals["group_2"] so
the test asserts the propagated value correctly.
- Around line 86-92: The test function create_detector_and_conditions shadows
the builtin name "type"; rename the parameter (for example to detector_type or
type_) and update its use inside the function (the call to create_detector
passing type=...) and any callers in this test file to use the new parameter
name to satisfy Ruff A001/A002; also optionally align the mismatched test data
for group_2 (change the helper call value from 6 to 10 or vice versa) if you
intend the value to be meaningful.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ec31ae3a-f504-4e96-964f-0fe799cdded4

📥 Commits

Reviewing files that changed from the base of the PR and between 533a491 and 8422030.

📒 Files selected for processing (4)
  • src/sentry/incidents/grouptype.py
  • src/sentry/workflow_engine/models/detector.py
  • src/sentry/workflow_engine/processors/detector.py
  • tests/sentry/workflow_engine/processors/test_detector.py

Comment on lines 10 to +12
# TODO: This will be a stateful detector when we build that abstraction
class MetricAlertDetectorHandler(DetectorHandler[QuerySubscriptionUpdate]):
def evaluate(
self, data_packet: DataPacket[QuerySubscriptionUpdate]
) -> list[DetectorEvaluationResult]:
# TODO: Implement
return []
class MetricAlertDetectorHandler(StatefulDetectorHandler[QuerySubscriptionUpdate]):
pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

Missing implementations of required abstract methods will cause runtime TypeError.

MetricAlertDetectorHandler extends StatefulDetectorHandler but doesn't implement the required abstract methods: counter_names, get_dedupe_value, get_group_key_values, and build_occurrence_and_event_data. When Detector.detector_handler attempts to instantiate this class (via group_type.detector_handler(self) in detector.py:86), Python will raise a TypeError.

Either implement the required abstract methods or keep this handler as a non-stateful DetectorHandler until the stateful implementation is complete.

Minimal stub implementation to prevent runtime error
-class MetricAlertDetectorHandler(StatefulDetectorHandler[QuerySubscriptionUpdate]):
-    pass
+from typing import Any
+from sentry.issues.issue_occurrence import IssueOccurrence
+from sentry.workflow_engine.models import DataPacket
+from sentry.workflow_engine.types import DetectorGroupKey
+
+class MetricAlertDetectorHandler(StatefulDetectorHandler[QuerySubscriptionUpdate]):
+    `@property`
+    def counter_names(self) -> list[str]:
+        return []
+
+    def get_dedupe_value(self, data_packet: DataPacket[QuerySubscriptionUpdate]) -> int:
+        raise NotImplementedError("MetricAlertDetectorHandler is not yet fully implemented")
+
+    def get_group_key_values(self, data_packet: DataPacket[QuerySubscriptionUpdate]) -> dict[str, int]:
+        raise NotImplementedError("MetricAlertDetectorHandler is not yet fully implemented")
+
+    def build_occurrence_and_event_data(
+        self, group_key: DetectorGroupKey, value: int, new_status: PriorityLevel
+    ) -> tuple[IssueOccurrence, dict[str, Any]]:
+        raise NotImplementedError("MetricAlertDetectorHandler is not yet fully implemented")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/sentry/incidents/grouptype.py` around lines 10 - 12,
MetricAlertDetectorHandler currently subclasses StatefulDetectorHandler but
omits the required abstract methods causing a TypeError at instantiation (see
Detector.detector_handler/group_type.detector_handler); either implement the
required methods—counter_names, get_dedupe_value, get_group_key_values, and
build_occurrence_and_event_data—on MetricAlertDetectorHandler with appropriate
stubs that return valid types for the stateful flow, or change the base class
back to DetectorHandler until a full stateful implementation is ready; update
MetricAlertDetectorHandler to include these method definitions (matching
signatures expected by StatefulDetectorHandler) so instantiation no longer
fails.

Comment on lines +86 to +92
def create_detector_and_conditions(self, type: str | None = None):
if type is None:
type = "handler_with_state"
detector = self.create_detector(
workflow_condition_group=self.create_data_condition_group(),
type=type,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n 'def create_detector_and_conditions\(self, type:' tests/sentry/workflow_engine/processors/test_detector.py
rg -n '^\s*type\s*=' tests/sentry/workflow_engine/processors/test_detector.py

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 293


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/sentry/workflow_engine/processors/test_detector.py"

echo "== Context around create_detector_and_conditions =="
nl -ba "$FILE" | sed -n '70,110p'

echo
echo "== Any other 'type' variable assignments nearby =="
rg -n '^\s*type\s*=' "$FILE" -n

echo
echo "== Ruff config: check whether A001/A002 are selected/treated as errors =="
ls -la | rg -n 'pyproject\.toml|ruff\.toml|setup\.cfg|tox\.ini' || true
rg -n --hidden "A002|A001" pyproject.toml setup.cfg tox.ini ruff.toml 2>/dev/null || true
rg -n --hidden "tool\.ruff|\\[tool\\.ruff\\]" pyproject.toml setup.cfg tox.ini ruff.toml 2>/dev/null || true

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 217


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/sentry/workflow_engine/processors/test_detector.py"

echo "== List repo root for Ruff config =="
ls -la | head -n 200

echo
echo "== Show context around create_detector_and_conditions =="
cat -n "$FILE" | sed -n '75,105p'

echo
echo "== Any other 'type' variable assignments nearby =="
rg -n '^\s*type\s*=' "$FILE" || true

echo
echo "== Ruff config: locate likely files =="
ls -la | rg -n 'pyproject\.toml|ruff\.toml|setup\.cfg|tox\.ini' || true

echo
echo "== Ruff config: search for tool.ruff and rule selection (A001/A002) =="
for f in pyproject.toml ruff.toml setup.cfg tox.ini; do
  if [ -f "$f" ]; then
    echo "-- $f --"
    rg -n "tool\.ruff|\\[tool\.ruff\\]|select|ignore|A001|A002" "$f" || true
  fi
done

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 7462


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="ruff.toml"
echo "== ruff.toml (first 120 lines) =="
sed -n '1,120p' "$FILE"

echo
echo "== ruff.toml: any A001/A002 mentions =="
rg -n "A001|A002" ruff.toml pyproject.toml setup.cfg || true

echo
echo "== pyproject.toml: tool.ruff sections (snippets around tool.ruff) =="
rg -n "\\[tool\\.ruff\\]" -n pyproject.toml || true
rg -n "enable_error_code|select|ignore|lint\\.select|lint\\.ignore|per-file-ignores|tool\\.ruff" pyproject.toml | head -n 80 || true

echo
echo "== setup.cfg: per-file-ignores entries near A001/A002 (snippets) =="
rg -n "per-file-ignores|A001|A002" setup.cfg || true

echo
echo "== Does ruff ignore these rules in tests/...? (grep for tests.sentry pattern) =="
rg -n "tests/|tests\\." pyproject.toml ruff.toml setup.cfg | head -n 120 || true

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 5898


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="tests/sentry/workflow_engine/processors/test_detector.py"

echo "== Locate test_state_results_multi_group =="
rg -n "test_state_results_multi_group" "$FILE"

echo
echo "== Show surrounding code (function body area) =="
# try to capture a reasonable window around the match
line=$(rg -n "test_state_results_multi_group" "$FILE" | head -n1 | cut -d: -f1)
start=$(( line>40 ? line-40 : 1 ))
end=$(( line+160 ))
sed -n "${start},${end}p" "$FILE" | cat -n

echo
echo "== All occurrences of group_2 in this file =="
rg -n "\"group_2\"" "$FILE"

echo
echo "== Any expected/fixture dicts mentioning group_2 and values =="
rg -n "group_2.*(6|10)" "$FILE" || true

echo
echo "== Create_detector_and_conditions definition (full for quick context) =="
sed -n '70,110p' "$FILE"

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 11671


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Inspect build_mock_occurrence_and_event: does it use `value`? =="
FILE="tests/sentry/workflow_engine/processors/test_detector.py"
rg -n "def build_mock_occurrence_and_event" "$FILE"
# print the whole helper (small)
sed -n '110,160p' "$FILE" | cat -n

echo
echo "== Search for Ruff check command used in CI/pre-commit =="
rg -n "ruff (check|lint)|pre-commit.*ruff|ruff\.toml|A001|A002" .pre-commit-config.yaml Makefile .github -S || true

echo
echo "== Search for ruff execution scripts =="
rg -n "ruff check" -S .github scripts tools bin Makefile || true

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 2669


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/sentry/workflow_engine/processors/test_detector.py"

echo "== Confirm build_mock_occurrence_and_event implementation uses `value` =="
# Print the full helper (it’s small); stop at next top-level def/class to avoid huge output
python3 - <<'PY'
import re
path="tests/sentry/workflow_engine/processors/test_detector.py"
with open(path,'r',encoding='utf-8') as f:
    s=f.read().splitlines()
start=None
for i,line in enumerate(s):
    if line.startswith("def build_mock_occurrence_and_event("):
        start=i
        break
if start is None:
    raise SystemExit("helper not found")
# find end: next top-level "def " or "class " at column 0 after start
end=len(s)
for j in range(start+1,len(s)):
    if re.match(r'^(def|class) ', s[j]) and not s[j].startswith("def build_mock_occurrence_and_event("):
        end=j
        break
for k in range(start, min(end, start+120)):
    print(f"{k+1:4d}:{s[k]}")
PY

echo
echo "== Show Ruff configuration (ruff.toml select includes A) =="
sed -n '1,80p' ruff.toml

echo
echo "== Find Ruff usage in pre-commit / CI =="
rg -n "ruff (check|lint)|pre-commit.*ruff|\\bA001\\b|\\bA002\\b" .pre-commit-config.yaml .github scripts tools bin Makefile || true

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 2756


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Ruff invocation in pre-commit config =="
rg -n "ruff (check|lint)|pre-commit.*ruff" .pre-commit-config.yaml .github/workflows .github -S || true

echo
echo "== Ruff invocation in Makefile / scripts =="
rg -n "ruff (check|lint)" Makefile scripts tools bin -S || true

echo
echo "== Does repo enable A (builtins shadowing) as error? (select includes A) =="
rg -n "\\bselect\\b|\\\"A\\\"" ruff.toml || true

echo
echo "== Per-file ignores in ruff.toml =="
cat ruff.toml | sed -n '1,120p'

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 1533


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find where ruff is run in this repo =="
rg -n "ruff (check|lint)|\\bruff\\b" .github .pre-commit-config.yaml Makefile scripts tools bin -S || true

echo
echo "== Inspect detector occurrence construction code =="
FILE="src/sentry/workflow_engine/processors/detector.py"
ls -ლა src/sentry/workflow_engine/processors 2>/dev/null | head || true
rg -n "create_issue_occurrence_from_result|occurrence|event_data|group_vals|group_val" "$FILE" -S || true

echo
echo "== Show relevant sections of detector.py around create_issue_occurrence_from_result (if present) =="
line=$(rg -n "create_issue_occurrence_from_result" "$FILE" -S | head -n1 | cut -d: -f1 || true)
if [ -n "${line:-}" ]; then
  start=$(( line>60 ? line-60 : 1 ))
  end=$(( line+220 ))
  sed -n "${start},${end}p" "$FILE" | cat -n
else
  echo "No create_issue_occurrence_from_result symbol found in $FILE"
fi

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 14570


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/sentry/workflow_engine/processors/test_detector.py"

echo "== Locate MockDetectorStateHandler.build_occurrence_and_event_data =="
rg -n "class MockDetectorStateHandler|build_occurrence_and_event_data" "$FILE"

echo
echo "== Show MockDetectorStateHandler class (bounded window) =="
# Print a window around the class definition and its build_occurrence_and_event_data
class_line=$(rg -n "^class MockDetectorStateHandler" "$FILE" | head -n1 | cut -d: -f1)
if [ -n "${class_line:-}" ]; then
  start=$(( class_line>50 ? class_line-40 : 1 ))
  end=$(( class_line+260 ))
  sed -n "${start},${end}p" "$FILE" | cat -n
fi

echo
echo "== Search CI/pre-commit for ruff commands =="
rg -n "ruff (check|lint)|ruff\\.toml|pre-commit.*ruff|python -m ruff|ruff\\.ini" .github .pre-commit-config.yaml Makefile scripts tools bin -S || true

echo
echo "== Search for A001/A002 mentions in config or ignore =="
rg -n "A001|A002" .github .pre-commit-config.yaml pyproject.toml ruff.toml setup.cfg -S || true

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 13233


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/sentry/workflow_engine/processors/test_detector.py"

echo "== Try running ruff on the file (A001/A002) =="
if command -v ruff >/dev/null 2>&1; then
  ruff --version
  ruff check --select A001,A002 "$FILE" || true
else
  echo "ruff not found in PATH"
fi

echo
echo "== Find ruff usage in pre-commit / CI =="
rg -n "ruff\\s+(check|lint)|python -m ruff|\\bruff\\b" .pre-commit-config.yaml .github -S || true

echo
echo "== Also scan for ruff in Makefile/scripts/tools (limited) =="
rg -n "ruff\\s+(check|lint)|python -m ruff|\\bruff\\b" Makefile scripts tools bin -S || true

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 1426


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Call site: build_occurrence_and_event_data in detector.py =="
FILE="src/sentry/workflow_engine/processors/detector.py"
rg -n "build_occurrence_and_event_data\\(" "$FILE" -S
line=$(rg -n "build_occurrence_and_event_data\\(" "$FILE" -S | head -n1 | cut -d: -f1 || true)
if [ -n "${line:-}" ]; then
  start=$(( line>80 ? line-80 : 1 ))
  end=$(( line+120 ))
  sed -n "${start},${end}p" "$FILE" | cat -n
fi

echo
echo "== Where Ruff is invoked (CI/pre-commit/etc) =="
rg -n "\\bruff\\b" .pre-commit-config.yaml Makefile .github scripts tools bin -S || true
rg -n "ruff\\s+check|ruff\\s+lint|python\\s+-m\\s+ruff" .github Makefile scripts tools bin -S || true
rg -n "A001|A002" .pre-commit-config.yaml .github -S || true

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 9923


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== detector.py: inspect around call at ~299 =="
FILE="src/sentry/workflow_engine/processors/detector.py"
sed -n '260,340p' "$FILE" | cat -n

echo
echo "== Find ruff invocations across repo (broad) =="
rg -n "ruff\s+(check|lint)" . -S || true
rg -n "python\s+-m\s+ruff" . -S || true
rg -n "pre-commit.*ruff|ruff.*pre-commit" . -S || true

echo
echo "== Find A001/A002 handling (ignore/select) =="
rg -n "A001|A002" . -S || true

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 5576


🏁 Script executed:

#!/bin/bash
rg -n 'def create_detector_and_conditions\(self, type:' tests/sentry/workflow_engine/processors/test_detector.py
rg -n '^\s*type\s*=' tests/sentry/workflow_engine/processors/test_detector.py

Repository: test-code-tool/sentry__sentry__coderabbit__PR80168__20260407

Length of output: 293


Fix Ruff builtin shadowing in create_detector_and_conditions (A001/A002)

ruff check --select A001,A002 fails due to the type argument/local shadowing the Python builtin in tests/sentry/workflow_engine/processors/test_detector.py (~86-88).

Suggested fix
-    def create_detector_and_conditions(self, type: str | None = None):
-        if type is None:
-            type = "handler_with_state"
+    def create_detector_and_conditions(self, detector_type: str | None = None):
+        if detector_type is None:
+            detector_type = "handler_with_state"
         detector = self.create_detector(
             workflow_condition_group=self.create_data_condition_group(),
-            type=type,
+            type=detector_type,
         )
  • The group_2 test data mismatch (packet has 10, helper is called with 6) doesn’t currently affect asserted occurrence/event payloads because build_mock_occurrence_and_event(...) ignores its value parameter; align the values for clarity if this is intended to be value-sensitive.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def create_detector_and_conditions(self, type: str | None = None):
if type is None:
type = "handler_with_state"
detector = self.create_detector(
workflow_condition_group=self.create_data_condition_group(),
type=type,
)
def create_detector_and_conditions(self, detector_type: str | None = None):
if detector_type is None:
detector_type = "handler_with_state"
detector = self.create_detector(
workflow_condition_group=self.create_data_condition_group(),
type=detector_type,
)
🧰 Tools
🪛 Ruff (0.15.15)

[error] 86-86: Function argument type is shadowing a Python builtin

(A002)


[error] 88-88: Variable type is shadowing a Python builtin

(A001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/sentry/workflow_engine/processors/test_detector.py` around lines 86 -
92, The test function create_detector_and_conditions shadows the builtin name
"type"; rename the parameter (for example to detector_type or type_) and update
its use inside the function (the call to create_detector passing type=...) and
any callers in this test file to use the new parameter name to satisfy Ruff
A001/A002; also optionally align the mismatched test data for group_2 (change
the helper call value from 6 to 10 or vice versa) if you intend the value to be
meaningful.

Comment on lines +190 to 192
occurrence_2, event_data_2 = build_mock_occurrence_and_event(
detector.detector_handler, "group_2", 6, PriorityLevel.HIGH
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the actual group_2 value in expected occurrence fixture.

group_vals sets "group_2": 10, but the expected helper call passes 6. That weakens the test and can hide value-propagation regressions.

Suggested fix
         occurrence_2, event_data_2 = build_mock_occurrence_and_event(
-            detector.detector_handler, "group_2", 6, PriorityLevel.HIGH
+            detector.detector_handler, "group_2", 10, PriorityLevel.HIGH
         )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
occurrence_2, event_data_2 = build_mock_occurrence_and_event(
detector.detector_handler, "group_2", 6, PriorityLevel.HIGH
)
occurrence_2, event_data_2 = build_mock_occurrence_and_event(
detector.detector_handler, "group_2", 10, PriorityLevel.HIGH
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/sentry/workflow_engine/processors/test_detector.py` around lines 190 -
192, The test uses build_mock_occurrence_and_event(detector.detector_handler,
"group_2", 6, PriorityLevel.HIGH) but group_vals defines "group_2" as 10, so
update the expected occurrence fixture to use the actual group_2 value (10)
instead of 6; locate the call to build_mock_occurrence_and_event (variables
occurrence_2 and event_data_2) and change the numeric argument to match
group_vals["group_2"] so the test asserts the propagated value correctly.

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.

2 participants