Skip to content

Reduce cognitive complexity in 5 core functions via helper extraction - #99

Open
sonarqube-agent-dev7[bot] wants to merge 1 commit into
mainfrom
remediate-main-20261101-080732-7613e395
Open

sonarqube-agent-dev7[bot] wants to merge 1 commit into
mainfrom
remediate-main-20261101-080732-7613e395

Conversation

@sonarqube-agent-dev7

Copy link
Copy Markdown

This PR was automatically created by the Remediation Agent's Scheduled backlog remediation feature.

Why these issues? All five issues are CRITICAL severity S3776 violations spanning distinct core files that are well-scoped and highly automatable through method extraction. This coherent group targets code maintainability without functional changes and delivers maximum value in a single focused PR.

This PR fixes 5 CRITICAL SonarQube cognitive complexity violations across inference.py, main.py, post_process.py, search_backend.py, and search_manage.py by extracting nested control flow logic into dedicated helper functions. These refactorings improve code maintainability and readability while reducing complexity scores to meet the allowed threshold of 15.

View Project in SonarCloud


Fixed Issues

python:S3776 - Refactor this function to reduce its Cognitive Complexity from 34 to the 15 allowed. • CRITICAL • View issue

Location: app/inference.py:144

Why is this an issue?

Cognitive Complexity is a measure of how hard it is to understand the control flow of a unit of code. Code with high cognitive complexity is hard to read, understand, test, and modify.

What changed

Starts reducing the cognitive complexity of the overly complex select_patch function by replacing its header and setup with a new helper, _find_reviewer_approved_patch. The helper takes over the reviewer-approval loop (the for loop and the nested review/json checks), so that branching no longer counts toward select_patch's score. The setup code removed here is re-added further down, in the rewritten select_patch.

--- a/app/inference.py
+++ b/app/inference.py
@@ -144,11 +144,1 @@ def run_one_task(task: Task, output_dir: str, model_names: Iterable[str]) -> boo
-def select_patch(task: Task, output_dir: str | PathLike) -> tuple[str, dict]:
-
-    patches = natsorted(list(Path(output_dir).glob("**/extracted_patch_*.diff")))
-
-    # TODO: These candidate patches must have been dismissed by reviewer. Maybe an
-    # assertion should be added to confirm this.
-    candidate_patches = [p for p in patches if may_pass_regression_tests(task, p)]
-
-    agent_comment = None
-    thread = None
-
+def _find_reviewer_approved_patch(patches: list, candidate_patches: list):
python:S3776 - Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed. • CRITICAL • View issue

Location: app/main.py:559

Why is this an issue?

Cognitive Complexity is a measure of how hard it is to understand the control flow of a unit of code. Code with high cognitive complexity is hard to read, understand, test, and modify.

What changed

Adds a helper function _remove_task_output_files. It holds the cleanup logic that used to sit deep inside do_inference: the loop that deletes every file except the log file and the RawTask metadata files, and removes every subdirectory. The for/if/and/if structure now sits at shallow nesting inside its own function, so its nesting penalties no longer count toward do_inference's cognitive complexity. This supports the fix for the warning that do_inference is above the allowed complexity.

--- a/app/main.py
+++ b/app/main.py
@@ -558,0 +559,18 @@ def evaluate_swe_issue_reproducer(
+def _remove_task_output_files(task_output_dir: str, log_file_name: str) -> None:
+    """
+    Remove everything in the task output dir other than the log file and
+    some meta data files dumped by RawTask.
+    """
+    files_to_keep = [
+        log_file_name,
+        "meta.json",
+        "problem_statement.txt",
+        "developer_patch.diff",
+    ]
+    for f in Path(task_output_dir).iterdir():
+        if f.is_file() and f.name not in files_to_keep:
+            f.unlink()
+        if f.is_dir():
+            shutil.rmtree(str(f))
+
+
python:S3776 - Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed. • CRITICAL • View issue

Location: app/post_process.py:219

Why is this an issue?

Cognitive Complexity is a measure of how hard it is to understand the control flow of a unit of code. Code with high cognitive complexity is hard to read, understand, test, and modify.

What changed

Introduces a new helper function _apply_edits that contains the loop for locating each edit's target file and applying the edit, collecting the indexes of edits that could not be matched or applied. On its own it changes nothing; it exists so the next hunk can move this logic out of convert_response_to_diff. That function was flagged for cognitive complexity of 17, above the allowed 15.

--- a/app/post_process.py
+++ b/app/post_process.py
@@ -217,0 +218,21 @@ def extract_diff_one_instance(
+def _apply_edits(edits, repo_path: str) -> list[int]:
+    """
+    Try to match and apply each edit. Returns indexes of edits that could not be applied.
+    """
+    unmatched_edit_indexes = []
+    for idx, edit in enumerate(edits):
+        # NOTE: do not clean here, since we want to accumulate changes from all edits
+        target_file = edit.filename
+        # find the target file. The model may only use the short name of the file,
+        # so we need to search for it here
+        found_file = apputils.find_file(repo_path, target_file)
+        if found_file is None:
+            unmatched_edit_indexes.append(idx)
+            continue
+        # try to apply this edit and update the actual file content
+        applied_file = apply_edit(edit, found_file)
+        if applied_file is None:
+            unmatched_edit_indexes.append(idx)
+    return unmatched_edit_indexes
+
+
python:S3776 - Refactor this function to reduce its Cognitive Complexity from 37 to the 15 allowed. • CRITICAL • View issue

Location: app/search/search_backend.py:759

Why is this an issue?

Cognitive Complexity is a measure of how hard it is to understand the control flow of a unit of code. Code with high cognitive complexity is hard to read, understand, test, and modify.

What changed

Replaces the nested if/else that splits 'Class.method' names inside get_bug_loc_snippets_new with a call to the new _split_class_method_name helper. This removes the compound condition and nested branch from the overly complex function, lowering its cognitive complexity.

--- a/app/search/search_backend.py
+++ b/app/search/search_backend.py
@@ -773,11 +773,3 @@ class SearchBackend:
-        if not tmp_class_name and tmp_method_name and "." in tmp_method_name:
-            fragments = tmp_method_name.split(".")
-            if len(fragments) == 2:
-                tmp_class_name, tmp_method_name = fragments
-                logger.warning(
-                    "Successfully split {} and {}", tmp_class_name, tmp_method_name
-                )
-            else:
-                logger.warning(
-                    "Too many fragments. Examine the method name: {}", tmp_method_name
-                )
+        tmp_class_name, tmp_method_name = self._split_class_method_name(
+            tmp_class_name, tmp_method_name
+        )
python:S3776 - Refactor this function to reduce its Cognitive Complexity from 34 to the 15 allowed. • CRITICAL • View issue

Location: app/search/search_manage.py:29

Why is this an issue?

Cognitive Complexity is a measure of how hard it is to understand the control flow of a unit of code. Code with high cognitive complexity is hard to read, understand, test, and modify.

What changed

Replaces the inline formatting/printing of agent-selected API calls and bug locations (nested ifs and for-loops) in search_iterative with a single call to the new _print_selected_apis helper, removing several nested control-flow increments from the overly complex function.

--- a/app/search/search_manage.py
+++ b/app/search/search_manage.py
@@ -98,13 +98,1 @@ class SearchManager:
-            formatted = []
-            if json_api_calls:
-                formatted.append("API calls:")
-                for call in json_api_calls:
-                    formatted.extend([f"\n- `{call}`"])
-
-            if buggy_locations:
-                formatted.append("\n\nBug locations")
-                for location in buggy_locations:
-                    s = ", ".join(f"{k}: `{v}`" for k, v in location.items())
-                    formatted.extend([f"\n- {s}"])
-
-            print_acr("\n".join(formatted), "Agent-selected API calls")
+            self._print_selected_apis(json_api_calls, buggy_locations)

Have a suggestion or found an issue? Share your feedback here.


SonarQube Cloud SonarQube Remediation Agent uses AI. Check for mistakes.

Fixed issues:
- AZ-oWkG81o4aY-kM01X9 for python:S3776 rule
- AZ-oWkGE1o4aY-kM01Xl for python:S3776 rule
- AZ-oWkGN1o4aY-kM01Xt for python:S3776 rule
- AZ-oWkFT1o4aY-kM01XC for python:S3776 rule
- AZ-oWkF81o4aY-kM01Xd for python:S3776 rule

Generated by SonarQube Agent (task: 6571a72c-f641-4f3b-9d64-452eeac847cd)
@sonarqube-agent-dev7

Copy link
Copy Markdown
Author

⚠️ This repository does not have a CODEOWNERS file. The PR has been created but has not been automatically assigned to any reviewer. To ensure PRs are reviewed promptly, consider adding a CODEOWNERS file to your repository.

@sonarqube-cloud-dev7

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant