Skip to content

Fix mutable default argument in merge_logs_to_list#1497

Open
juandiego-bmu wants to merge 4 commits intoOWASP:masterfrom
juandiego-bmu:fix-mutable-default-arg
Open

Fix mutable default argument in merge_logs_to_list#1497
juandiego-bmu wants to merge 4 commits intoOWASP:masterfrom
juandiego-bmu:fix-mutable-default-arg

Conversation

@juandiego-bmu
Copy link
Copy Markdown

Proposed change

Replace log_list=[] with log_list=None and initialize inside the function body in merge_logs_to_list() (nettacker/core/utils/common.py).

The mutable default list was shared across all calls. Since it's mutated via .append() on line 41, log entries from previous invocations leak into subsequent results and the list grows without bound.

Linked issue: #1464

Type of change

  • Bugfix (non-breaking change which fixes an issue)

Checklist

  • I've followed the contributing guidelines
  • I have digitally signed all my commits in this PR
  • I've run make pre-commit and confirm it didn't generate any warnings/changes
  • I've run make test, I confirm all tests passed locally
  • I've added/updated any relevant documentation in the docs/ folder
  • I've linked this PR with an open issue
  • I've tested and verified that my code works as intended and resolves the issue as described
  • I have attached screenshots demonstrating my code works as intended
  • I've checked all other open PRs to avoid submitting duplicate work
  • I confirm that the code and comments in this PR are not direct unreviewed outputs of AI
  • I confirm that I am the Sole Responsible Author for every line of code, comment, and design decision

Recreated from #1470 with signed commits and proper template as requested by @securestep9.

Replace log_list=[] with log_list=None and initialize inside the
function body. The mutable default was shared across all calls,
causing log entries from previous invocations to leak into subsequent
results and growing without bound.

Fixes OWASP#1464
Copilot AI review requested due to automatic review settings April 3, 2026 14:52
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 3, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c0427204-1c86-499c-8a11-f453951ad113

📥 Commits

Reviewing files that changed from the base of the PR and between fa6d2ca and 6957125.

📒 Files selected for processing (2)
  • nettacker/core/utils/common.py
  • tests/core/utils/test_common.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • nettacker/core/utils/common.py

Summary by CodeRabbit

  • Chores
    • Internal code quality fix to prevent unexpected state persistence across repeated calls.
    • Added unit tests covering log extraction, nesting, deduplication, and isolation between calls.

Walkthrough

Refactored merge_logs_to_list() to remove a mutable default argument by changing log_list=[] to log_list=None and initializing a new list when None. Added unit tests covering flat, nested, duplicate, absent, and call-isolation behaviors for the function.

Changes

Cohort / File(s) Summary
Core utility update
nettacker/core/utils/common.py
Replaced mutable default parameter log_list=[] with log_list=None and added conditional initialization inside merge_logs_to_list(); original recursive extraction and deduplication logic preserved.
Unit tests added
tests/core/utils/test_common.py
New tests for merge_logs_to_list() covering simple log extraction, nested logs, no-log inputs, duplicate removal, and ensuring no cross-call state leakage.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix mutable default argument in merge_logs_to_list' directly and clearly describes the main change—fixing a mutable default argument bug in a specific function.
Description check ✅ Passed The description is well-detailed and directly related to the changeset, explaining the bug (mutable default list being shared across calls), the fix (replacing [] with None), and the impact.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a Python mutable-default-argument bug in merge_logs_to_list() that caused log entries to leak across invocations and grow unbounded over time (issue #1464).

Changes:

  • Replace log_list=[] default with log_list=None.
  • Initialize log_list to a new list inside the function when None is provided.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +34 to +36
def merge_logs_to_list(result, log_list=None):
if log_list is None:
log_list = []
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

Add a unit test for merge_logs_to_list covering the original bug: calling it multiple times without providing log_list should return independent results (no cross-call contamination). This helps prevent regressions of the mutable-default-argument issue.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
nettacker/core/utils/common.py (1)

34-34: Consider adding type hints to clarify the recursive accumulator contract.

This utility is easier to reason about with an explicit signature.

♻️ Optional refactor
+from typing import Any
+
-def merge_logs_to_list(result, log_list=None):
+def merge_logs_to_list(result: Any, log_list: list[str] | None = None) -> list[str]:
     if log_list is None:
         log_list = []

As per coding guidelines, "Keep functions small, use type hints where practical, and add docstrings for public APIs".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nettacker/core/utils/common.py` at line 34, Add explicit type hints and a
short docstring to clarify the recursive accumulator contract for
merge_logs_to_list: change the signature to use typing (e.g., def
merge_logs_to_list(result: Any, log_list: Optional[list] = None) -> list) or a
more specific element type if known, import Optional/Any/List as needed,
document that log_list is an accumulator initialized to None and the function
returns a list of merged log entries, and ensure recursive calls and return
statements preserve the annotated types.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@nettacker/core/utils/common.py`:
- Line 34: Add explicit type hints and a short docstring to clarify the
recursive accumulator contract for merge_logs_to_list: change the signature to
use typing (e.g., def merge_logs_to_list(result: Any, log_list: Optional[list] =
None) -> list) or a more specific element type if known, import
Optional/Any/List as needed, document that log_list is an accumulator
initialized to None and the function returns a list of merged log entries, and
ensure recursive calls and return statements preserve the annotated types.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a765295d-4ba2-4b66-ae42-6849b066632d

📥 Commits

Reviewing files that changed from the base of the PR and between 74c2217 and fa6d2ca.

📒 Files selected for processing (1)
  • nettacker/core/utils/common.py

Copy link
Copy Markdown
Collaborator

@arkid15r arkid15r left a comment

Choose a reason for hiding this comment

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

This is a good catch. Could you address ai bot comments and add tests related to this change?

Thank you!

Address review feedback: add docstring to meet coverage threshold
and add tests verifying correct behavior including no shared state
between consecutive calls (the core bug this PR fixes).
@juandiego-bmu
Copy link
Copy Markdown
Author

Done! I pushed a new commit that:

  • Adds a docstring to merge_logs_to_list() to address the coverage warning
  • Adds 5 tests covering: simple extraction, nested dicts, missing log keys, deduplication, and most importantly — verifying that consecutive calls without an explicit log_list don't leak state between each other (which is the core bug this PR fixes)

All existing + new tests pass locally.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants