Skip to content

fix: code quality - variable typo, dead import, PEP 8 identity checks, unnecessary f-strings - #993

Merged
northdpole merged 7 commits into
OWASP:mainfrom
BEAST04289:fix/code-quality-round-2
Aug 9, 2026
Merged

fix: code quality - variable typo, dead import, PEP 8 identity checks, unnecessary f-strings#993
northdpole merged 7 commits into
OWASP:mainfrom
BEAST04289:fix/code-quality-round-2

Conversation

@BEAST04289

@BEAST04289 BEAST04289 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Code quality fixes found during a full codebase audit. All changes are zero-behavior-change.

Follows up on leftover items from #836 / #837 (which was scoped down to just the get_by_tags shadowing fix during rebase).

Note:

This PR includes an intentional security behavior change to the smartlink path. It resolves a CodeQL alert by URL-encoding inputs and strictly allowlisting cwe.mitre.org and capec.mitre.org to prevent open-redirect and javascript: URI injection.

Changes

Variable Typo Fix

  • pentaltypenalty in gap_analysis.py (3 occurrences, lines 100–102) — misspelled local variable from get_path_score()

Dead Import Removal

  • import json as _json removed from cre_main.py — imported but never referenced anywhere in the file (json is already imported on line 4)

PEP 8: == Noneis None (6 occurrences across 5 files)

Per PEP 8: comparisons to singletons like None should use is / is not, because == invokes __eq__ which a custom class could override, while is checks object identity — and None is a singleton, so identity is the correct check.

Files: spreadsheet_parsers.py (×2), oscal_utils.py, export_format_parser.py, inmemory_graph.py, db.py

Unnecessary f-string Prefixes (production code only)

Removed f prefix from ~23 strings that contain no {} placeholders:

  • web_main.py — 13 posthog event names + 1 logger call
  • db.py — 4 exception/log messages
  • cre_main.py — 4 logger calls
  • prompt_client.py — 2 logger calls

Test files were intentionally left untouched to keep the diff focused.

Testing

  • All 9 modified files compile cleanly (python -m py_compile)
  • Verified via grep: zero remaining pentalty, _json, or == None in the codebase
  • All changes are cosmetic/style only — zero behavior change

Copilot AI review requested due to automatic review settings July 23, 2026 21:19
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 98cb7c26-fb4a-4232-8d30-e533205c27c7

📥 Commits

Reviewing files that changed from the base of the PR and between 6771031 and f01050a.

📒 Files selected for processing (3)
  • application/tests/web_main_test.py
  • application/utils/redirectors.py
  • application/web/web_main.py

Summary by CodeRabbit

  • Bug Fixes

    • Corrected gap-analysis penalty scoring for more consistent results.
    • Improved handling of missing or unset values across graph, export, OSCAL, and spreadsheet processing.
    • Added validation to ensure external redirects use HTTPS; invalid links now return a not-found response.
    • URL-encoded identifiers in CWE and CAPEC links for safer redirects.
  • Refactor

    • Simplified logging, JSON serialization, and conditional checks without changing core behavior.
  • Tests

    • Added coverage for rejected external redirect URLs.

Walkthrough

This PR modernizes None checks, corrects gap-analysis penalty scoring, removes unnecessary f-string prefixes, uses direct JSON and telemetry strings, updates redirect URL construction, and validates smartlink HTTPS redirects.

Changes

Python cleanup and redirect validation

Layer / File(s) Summary
Null checks and penalty scoring
application/database/db.py, application/database/inmemory_graph.py, application/utils/{external_project_parsers,spreadsheet_parsers}.py, application/utils/gap_analysis.py, application/utils/oscal_utils.py
Null comparisons use is None, and gap-analysis scoring uses the penalty variable.
Serialization and message cleanup
application/cmd/cre_main.py, application/database/db.py, application/prompt_client/prompt_client.py
JSON serialization uses json, and database, Neo4j, and prompt-client messages use direct strings.
Smartlink redirect validation and telemetry
application/web/web_main.py, application/utils/redirectors.py, application/tests/web_main_test.py
PostHog event names use literal strings. Redirect identifiers are URL-encoded. smartlink accepts only HTTPS string redirects and returns 404 otherwise. Tests cover rejected redirect values.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: pa04rth, paoga87, robvanderveer

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.46% 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
Title check ✅ Passed The title clearly describes the main code-quality changes, although it does not mention redirect hardening or regression tests.
Description check ✅ Passed The description covers the cleanup changes and testing, but incorrectly states that all changes have zero behavior change.
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.
✨ 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.

Copilot AI 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.

Pull request overview

This PR aims to apply code-quality cleanups across the Python codebase (typo fix, PEP 8 None identity checks, and removal of unnecessary f-strings) while keeping behavior unchanged.

Changes:

  • Rename misspelled local variable pentaltypenalty in gap analysis scoring.
  • Replace == None checks with is None for PEP 8 singleton comparisons across multiple modules.
  • Remove f prefixes from strings that have no interpolation, and remove a purportedly-dead JSON import alias.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
application/web/web_main.py Removes unnecessary f-strings in PostHog event names and one logger call.
application/utils/spreadsheet_parsers.py Replaces == None with is None in parsing logic.
application/utils/oscal_utils.py Replaces uuid == None with uuid is None in OSCAL conversion.
application/utils/gap_analysis.py Fixes local variable typo (pentaltypenalty) in path scoring.
application/utils/external_project_parsers/parsers/export_format_parser.py Replaces == None with is None in export-format parsing.
application/prompt_client/prompt_client.py Removes unnecessary f-strings from logger messages.
application/database/inmemory_graph.py Replaces == None with is None for graph cache check.
application/database/db.py Replaces == None with is None and removes unnecessary f-strings in exception/log strings.
application/cmd/cre_main.py Removes f-strings and removes import json as _json (but _json is still referenced later).

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

Comment on lines 11 to 15
from collections import deque
from typing import Any, Callable, Dict, List, Optional, Tuple, TYPE_CHECKING
import hashlib
import json as _json
from rq import Queue, job, exceptions
from sqlalchemy import not_
@northdpole

Copy link
Copy Markdown
Collaborator

Please rebase onto latest main (~68 commits behind) before review — small cleanup PRs go stale quickly against formatting/CI changes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
application/cmd/cre_main.py (2)

895-907: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add test coverage for the noise-filter CLI path.

This branch adds new behavior. Add a test that verifies the stripped run ID, noise_filter_dry_run, JSON output, and early return before other commands execute.

As per coding guidelines: **/*.{py,ts,tsx,js} requires test-first development for new behavior and importers.

🤖 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 `@application/cmd/cre_main.py` around lines 895 - 907, The run_noise_filter CLI
branch lacks coverage for its argument handling and control flow. Add a focused
test for the command entry point that mocks db_connect and run_noise_filter,
verifies args.run_id is stripped, noise_filter_dry_run is propagated,
summary.to_json() is printed, and execution returns before subsequent commands
run.

Source: Coding guidelines


895-907: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Teardown the Flask-SQLAlchemy session after the noise filter run.

run_noise_filter hands lifecycle ownership to the caller, but this run() branch returns/printing JSON after success and does not tear down the connection when the pipeline raises. Wrap the connect/run/print block with sqla.session.remove() and app_context.pop() in try/finally on the error path.

🤖 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 `@application/cmd/cre_main.py` around lines 895 - 907, Update the
run_noise_filter branch in run() to wrap db_connect, run_noise_filter, and
summary output in try/finally. In the finally block, call sqla.session.remove()
and pop the Flask application context via the existing app-context handle,
ensuring both cleanup actions run when the pipeline raises or after successful
output.
🤖 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.

Outside diff comments:
In `@application/cmd/cre_main.py`:
- Around line 895-907: The run_noise_filter CLI branch lacks coverage for its
argument handling and control flow. Add a focused test for the command entry
point that mocks db_connect and run_noise_filter, verifies args.run_id is
stripped, noise_filter_dry_run is propagated, summary.to_json() is printed, and
execution returns before subsequent commands run.
- Around line 895-907: Update the run_noise_filter branch in run() to wrap
db_connect, run_noise_filter, and summary output in try/finally. In the finally
block, call sqla.session.remove() and pop the Flask application context via the
existing app-context handle, ensuring both cleanup actions run when the pipeline
raises or after successful output.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 243a246e-19a1-45c1-a6bb-96d94f3a7f79

📥 Commits

Reviewing files that changed from the base of the PR and between 671e9fa and fcd41aa.

📒 Files selected for processing (3)
  • application/cmd/cre_main.py
  • application/database/db.py
  • application/web/web_main.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • application/database/db.py
  • application/web/web_main.py

@BEAST04289
BEAST04289 force-pushed the fix/code-quality-round-2 branch from fcd41aa to 16bc020 Compare August 8, 2026 05:04
Comment thread application/web/web_main.py Fixed
… unnecessary f-strings

- Fix misspelled variable pentalty -> penalty in gap_analysis.py (3 occurrences)

- Remove unused import json as _json in cre_main.py

- Use is None instead of == None per PEP 8 (6 occurrences across 5 files)

- Strip unnecessary f-string prefixes from strings with no placeholders (production code only)
@BEAST04289
BEAST04289 force-pushed the fix/code-quality-round-2 branch from 16bc020 to 24ffdb2 Compare August 8, 2026 11:03
logger.info(
f"did not find node of type {ntype}, name {name} and section {section}, redirecting to external resource"
)
return redirect(url)

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
application/web/web_main.py (1)

797-806: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression tests for rejected redirect values.

Test http://..., javascript:..., and non-string resolver results. Assert a 404 response. Also assert that redirectors.redirect is called once. Keep the existing HTTPS MITRE case as the success case.

As per coding guidelines, **/*.{py,ts,tsx,js}: Do not guess or leave incomplete code; make minimal-scope changes. Use test-first development for new behavior and importers.

🤖 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 `@application/web/web_main.py` around lines 797 - 806, Add regression tests
covering the redirect branch around redirectors.redirect for http:// URLs,
javascript: URLs, and non-string results, asserting each returns 404 and the
resolver is called once. Preserve the existing HTTPS MITRE test as the
successful redirect case, and keep implementation changes limited to what the
tests require.

Source: Coding guidelines

🤖 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.

Nitpick comments:
In `@application/web/web_main.py`:
- Around line 797-806: Add regression tests covering the redirect branch around
redirectors.redirect for http:// URLs, javascript: URLs, and non-string results,
asserting each returns 404 and the resolver is called once. Preserve the
existing HTTPS MITRE test as the successful redirect case, and keep
implementation changes limited to what the tests require.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: f13c19a3-83d1-499b-869d-ca8d663c3a03

📥 Commits

Reviewing files that changed from the base of the PR and between fcd41aa and 24ffdb2.

📒 Files selected for processing (1)
  • application/web/web_main.py

@northdpole northdpole left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Review — code quality + smartlink redirect hardening (#993)

Looks good. CI green, mergeable. Approving.

What checks out

  • pentaltypenalty is a local rename only (scoring already used PENALTIES[...]).
  • is None / dead _json alias / unnecessary f prefixes are safe cleanups; Copilot’s earlier _json NameError concern is fixed (json.dumps everywhere).
  • Smartlink: allowlisting https://cwe.mitre.org/ / https://capec.mitre.org/ + single redirectors.redirect call is the right CodeQL fix; quote(str(...)) in redirectors is fine defense-in-depth. Existing MITRE orphan case in test_smartlink_critical_edge_cases still matches; new rejection tests cover http / javascript / non-string.

Nits (non-blocking)

  • PR body still says “zero-behavior-change”; the smartlink path is an intentional security behavior change — worth a one-line update in the description before merge.
  • Still ~11 commits behind main — please rebase (or we can rebase-on-merge) so CI is current.

No need to chase CodeRabbit’s out-of-diff noise-filter comments; unrelated to this PR.

@northdpole

Copy link
Copy Markdown
Collaborator

Approved — quality cleanups + smartlink HTTPS allowlist look good, CI green.

Please rebase onto latest main when convenient (or we can take care of it at merge). Also a tiny description tweak: call out the smartlink redirect hardening (it’s not zero-behavior-change). Ping if you want us to merge after rebase.

@northdpole
northdpole merged commit 9ea779e into OWASP:main Aug 9, 2026
6 checks passed
@northdpole

Copy link
Copy Markdown
Collaborator

Merged (rebase) after updating onto main — CI green.

@BEAST04289
BEAST04289 deleted the fix/code-quality-round-2 branch August 14, 2026 14:21
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.

4 participants