Skip to content

format and minor bug fixes#38

Merged
AlanRockefeller merged 2 commits intomainfrom
test
Jan 29, 2026
Merged

format and minor bug fixes#38
AlanRockefeller merged 2 commits intomainfrom
test

Conversation

@AlanRockefeller
Copy link
Copy Markdown
Owner

@AlanRockefeller AlanRockefeller commented Jan 29, 2026

Summary by CodeRabbit

  • Bug Fixes

    • More robust file-deletion handling with improved error reporting and safer behavior when image paths are missing.
  • Refactor

    • Internal file-operation helpers consolidated for more reliable deletion and directory management.
  • Style

    • Consistent code formatting and minor cleanup across the codebase.
  • Tests

    • Expanded and hardened tests and setup to improve reliability and coverage.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 29, 2026

Walkthrough

Refactors deletion file operations with internal helpers and stricter None-path handling; adds backward-compatibility aliases in UI provider; updates imports and many tests to match internal helper usage and small formatting changes across scripts and tests.

Changes

Cohort / File(s) Summary
Core Deletion and Path Handling
faststack/io/deletion.py
Adds internal helpers _mkdir and _unlink; replaces direct Path.mkdir/Path.unlink calls with these helpers; switches log.error to log.exception for error cases; makes confirm_permanent_delete guard against None image paths and conditionally include JPG files, returning False when no files found.
Tests for Deletion Logic
faststack/tests/test_permanent_delete.py
Updates tests to patch _mkdir/_unlink instead of Path methods; loosens MockImageFile typing to allow None path; adds test_confirm_handles_none_path; expects log.exception on failures.
UI Provider Backward Compatibility
faststack/ui/provider.py
Adds private _app_controller aliases in ImageProvider and UIState; removes duplicate preloadingStateChanged signal declaration.
Import & Small App Changes
faststack/app.py, run_app.py, debug_al.py, inspect_app.py
Removes unused imports (e.g., QMessageBox, os); normalizes string quoting; trivial formatting-only edits.
Watcher & Misc IO
faststack/io/watcher.py
Minor formatting change (removed inline comment) with no behavioral impact.
Test imports and helpers
faststack/tests/check_imports.py, faststack/tests/test_config_setters.py
Moves traceback import to module level; comments out numpy MagicMock in one test (no longer mocking numpy).
Concurrency & Test helpers
faststack/tests/test_prefetch_concurrency.py, tests/verify_manual.py, reproduce_bug.py
Ensures worker exceptions set stop_event for coordinated shutdown; supplies concrete pass-through methods on DummyController in tests; add test directory cleanup in a test setup.
Formatting-only and script edits
scripts/smoke_verify.py, test_*, tests/*, reproduce_*.py, verify_*.py, repro_crash.py, reproduce_issue.py, reproduce_config_issue.py, reproduce_mmap_error.py
Widespread cosmetic edits: consistent double-quote usage, whitespace/blank-line adjustments, minor test formatting changes, and a few restored operations (e.g., rename in reproduce_issue.py). No broad behavioral changes besides those noted above.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.14% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the primary intent of the pull request, which consists of formatting changes (quote style consistency, whitespace/blank line adjustments) and minor bug fixes (internal helpers, error handling improvements, test updates).

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

✨ Finishing touches
  • 📝 Generate docstrings

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

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (1)
faststack/io/deletion.py (1)

102-106: Guard batch delete against img.path=None to avoid AttributeError.

Line 103 still assumes img.path is always set, but single-delete now treats it as optional; batch delete can crash on None. Consider mirroring the same guard.

🛠️ Proposed fix
-    for img in images:
-        file_names.append(img.path.name)
-        total_files += 1
-        if img.raw_pair and img.raw_pair.exists():
-            total_files += 1
+    for img in images:
+        if img.path:
+            file_names.append(img.path.name)
+            total_files += 1
+        else:
+            log.warning("confirm_batch_permanent_delete called with image_file.path=None")
+        if img.raw_pair and img.raw_pair.exists():
+            total_files += 1
🤖 Fix all issues with AI agents
In `@repro_crash.py`:
- Around line 38-40: The except block that currently does "except Exception as
e: print(f\"CRASHED: {e}\"); raise e" should re-raise the caught exception with
its original traceback by replacing "raise e" with a bare "raise" in the same
except block (the handler that binds the exception to "e"), leaving the
print/log statement intact; locate the except Exception as e block in
repro_crash.py and make this single-line change.

In `@tests/test_highlights_v2.py`:
- Around line 19-20: The test calls _apply_headroom_shoulder with an incorrect
keyword argument name; change the call to use max_overshoot=steepness (i.e.,
replace steepness=steepness) and rename the local test variable from steepness
to max_overshoot (or update the docstring/variable to match) so names align with
the function signature; also update the test docstring/comment to reference
max_overshoot instead of steepness to keep naming consistent.

In `@verify_fix_auto_levels.py`:
- Around line 45-48: Remove the unused variable t1 assigned by t1 = time.time()
in the block that updates the file mtime (the img_path.touch() call); either
delete the t1 assignment entirely or use it where intended, but do not leave an
unused local variable named t1 next to the img_path.touch() call.
- Line 62: Remove the unused variable assignment target_path =
Path(saved_path).resolve() in verify_fix_auto_levels.py; either delete that line
entirely or replace subsequent uses to reference Path(saved_path).resolve()
directly (if intended), ensuring no leftover references to target_path remain
and leaving saved_path as the sole variable if nothing else needs changing.
🧹 Nitpick comments (4)
tests/test_prefetch_concurrency.py (1)

27-41: Silence Ruff ARG001 in mock_decode_and_cache.

Rename unused varargs to indicate intent and keep lint clean.

♻️ Proposed fix
-    def mock_decode_and_cache(*args, **kwargs):
+    def mock_decode_and_cache(*_args, **_kwargs):
         time.sleep(0.0001)  # fast sleep
         return Path("/mock/image_x.jpg"), 1
debug_al.py (1)

17-17: Consider prefixing unused variables with underscore.

Static analysis flags blacks, whites, and p_low as unused. Since this is a debug script and only p_high is printed, you could use _ placeholders for clarity:

_, _, _, p_high = editor.auto_levels(threshold_percent=0.1)

This is optional for a debug utility file.

reproduce_bug.py (1)

37-38: Remove unused variable t1.

The variable t1 is assigned but never used. While it serves as documentation that "T1" is the new timestamp, it can be removed to clean up the code.

♻️ Proposed fix
     # 2. Save Main (update mtime to T1)
-    t1 = time.time()
     img_path.touch()  # Updates mtime
faststack/io/deletion.py (1)

31-31: Remove the exception object from log.exception() calls—let the automatic traceback capture handle it.

logging.exception() automatically includes the current exception traceback, so passing e is redundant. Instead, log contextual information (path/filename) in the message to improve readability without duplicating the exception details.

♻️ Proposed cleanup
-        log.exception("Failed to create recycle bin directory: %s", e)
+        log.exception("Failed to create recycle bin directory: %s", recycle_bin_dir)
-            log.exception("Failed to permanently delete %s: %s", jpg_path.name, e)
+            log.exception("Failed to permanently delete %s", jpg_path.name)
-            log.exception("Failed to permanently delete %s: %s", raw_path.name, e)
+            log.exception("Failed to permanently delete %s", raw_path.name)

Also applies to: 166, 175

Comment thread repro_crash.py
Comment on lines +38 to +40
except Exception as e:
print(f"CRASHED: {e}")
raise e
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

Use bare raise to preserve the original traceback.
raise e resets context and can hide the true origin.

Suggested fix
-                raise e
+                raise
🧰 Tools
🪛 Ruff (0.14.14)

40-40: Use raise without specifying exception name

Remove exception name

(TRY201)

🤖 Prompt for AI Agents
In `@repro_crash.py` around lines 38 - 40, The except block that currently does
"except Exception as e: print(f\"CRASHED: {e}\"); raise e" should re-raise the
caught exception with its original traceback by replacing "raise e" with a bare
"raise" in the same except block (the handler that binds the exception to "e"),
leaving the print/log statement intact; locate the except Exception as e block
in repro_crash.py and make this single-line change.

Comment thread tests/test_highlights_v2.py Outdated
Comment thread verify_fix_auto_levels.py
Comment on lines 45 to +48
# 2. Save Main (update mtime to T1)
t1 = time.time()
img_path.touch() # Updates mtime
img_path.touch() # Updates mtime

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

Remove unused t1.
Line 46 assigns t1 but never uses it.

Suggested fix
-    t1 = time.time()
     img_path.touch()  # Updates mtime
📝 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
# 2. Save Main (update mtime to T1)
t1 = time.time()
img_path.touch() # Updates mtime
img_path.touch() # Updates mtime
# 2. Save Main (update mtime to T1)
img_path.touch() # Updates mtime
🧰 Tools
🪛 Ruff (0.14.14)

46-46: Local variable t1 is assigned to but never used

Remove assignment to unused variable t1

(F841)

🤖 Prompt for AI Agents
In `@verify_fix_auto_levels.py` around lines 45 - 48, Remove the unused variable
t1 assigned by t1 = time.time() in the block that updates the file mtime (the
img_path.touch() call); either delete the t1 assignment entirely or use it where
intended, but do not leave an unused local variable named t1 next to the
img_path.touch() call.

Comment thread verify_fix_auto_levels.py

# FIX LOGIC:
new_index = -1
target_path = Path(saved_path).resolve()
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

Remove unused target_path.
It’s never referenced after assignment.

Suggested fix
-    target_path = Path(saved_path).resolve()
📝 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
target_path = Path(saved_path).resolve()
🧰 Tools
🪛 Ruff (0.14.14)

62-62: Local variable target_path is assigned to but never used

Remove assignment to unused variable target_path

(F841)

🤖 Prompt for AI Agents
In `@verify_fix_auto_levels.py` at line 62, Remove the unused variable assignment
target_path = Path(saved_path).resolve() in verify_fix_auto_levels.py; either
delete that line entirely or replace subsequent uses to reference
Path(saved_path).resolve() directly (if intended), ensuring no leftover
references to target_path remain and leaving saved_path as the sole variable if
nothing else needs changing.

@AlanRockefeller AlanRockefeller merged commit 095a82d into main Jan 29, 2026
1 check passed
@coderabbitai coderabbitai Bot mentioned this pull request Mar 13, 2026
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.

1 participant