Fix duplicate DialogManager methods and make tooling Python 3.14-aware

DialogManager defined show_transfer_stats and show_disable_debugging_reminder
twice; the later definitions silently shadowed the earlier ones. The live
show_transfer_stats(self, stats, operation) accepted only two arguments, but
TransferManager passed a third (deduplicator), raising TypeError inside the Tk
after() callback so the transfer-stats window never appeared after folder
transfers. The shadowed copies were also dead: they indexed stats keys
(bytes_saved/total_files/...) that the *_with_dedup TODO stubs never produce,
so they would have KeyError'd on the real {"message": ...} payload.

- Remove the dead, shadowed copies of both methods
- Drop the unused deduplicator argument at the caller (transfer_manager)
- Annotate the surviving methods with -> None

Also align linting/type config with the existing >=3.13,<3.15 support that CI
already exercises: black now targets py313+py314, and CLAUDE.md documents
3.13/3.14. mypy stays pinned to the 3.13 floor (the oldest supported runtime).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit was merged in pull request #48.
This commit is contained in:
2026-06-20 21:30:27 -05:00
committed by Jason Ross
co-authored by Claude Opus 4.8
parent b269fdc11d
commit 8020bede3a
4 changed files with 4 additions and 57 deletions
+1 -1
View File
@@ -158,6 +158,6 @@ The project uses GitHub Actions for multi-platform builds (`.github/workflows/re
## Notes ## Notes
- **ADB Binaries**: Stored in `src/platform-tools/` - do not modify or delete unless explictly instructed to - **ADB Binaries**: Stored in `src/platform-tools/` - do not modify or delete unless explictly instructed to
- **Python Version**: Requires Python 3.13 (< 3.14) - **Python Version**: Requires Python 3.13 or 3.14 (>=3.13, <3.15)
- **Package Mode**: Poetry is configured with `package-mode = false` - **Package Mode**: Poetry is configured with `package-mode = false`
- **License**: First-run license agreement required on Windows - **License**: First-run license agreement required on Windows
+1 -1
View File
@@ -41,7 +41,7 @@ pyinstaller = "^6.1.0"
[tool.black] [tool.black]
line-length = 88 line-length = 88
target-version = ['py313'] target-version = ['py313', 'py314']
[tool.mypy] [tool.mypy]
python_version = "3.13" python_version = "3.13"
+2 -54
View File
@@ -211,58 +211,6 @@ class DialogManager:
dialog.protocol("WM_DELETE_WINDOW", on_close) dialog.protocol("WM_DELETE_WINDOW", on_close)
ok_button.config(command=on_close) ok_button.config(command=on_close)
def show_disable_debugging_reminder(self) -> None:
"""Show reminder to disable USB debugging after transfer."""
msg = (
"Transfer completed!\n\n"
"For security, please disable USB debugging when done:\n"
"Settings → Developer Options → disable 'USB debugging'."
)
messagebox.showinfo("Disable USB Debugging", msg)
def show_transfer_stats(
self, stats: dict, operation: str, deduplicator=None
) -> None:
"""Show transfer statistics dialog.
Args:
stats: Dictionary containing transfer statistics
operation: Type of operation ("Pull" or "Push")
deduplicator: Optional deduplicator instance for byte formatting
"""
# Format bytes saved
bytes_saved_str = ""
if stats["bytes_saved"] > 0:
if deduplicator and hasattr(deduplicator, "format_bytes"):
bytes_saved_str = (
f" ({deduplicator.format_bytes(stats['bytes_saved'])} saved)"
)
else:
bytes_saved_str = f" ({stats['bytes_saved']} bytes saved)"
# Build message
title = f"{operation} Transfer Complete"
if stats["total_files"] == 0:
message = "No files were found to transfer."
else:
message_parts = [
f"Transfer completed successfully!\n",
f"Files found: {stats['total_files']}",
f"Files transferred: {stats['transferred']}",
f"Duplicate files skipped: {stats['skipped']}{bytes_saved_str}",
]
if stats["skipped"] > 0:
message_parts.append(
f"\nDuplicate detection helped avoid unnecessary transfers!"
)
message = "\n".join(message_parts)
# Show dialog
messagebox.showinfo(title, message)
def show_error(self, title: str, message: str) -> None: def show_error(self, title: str, message: str) -> None:
"""Show an error dialog. """Show an error dialog.
@@ -386,7 +334,7 @@ class DialogManager:
side="right" side="right"
) )
def show_transfer_stats(self, stats: dict, operation: str): def show_transfer_stats(self, stats: dict, operation: str) -> None:
"""Show transfer statistics in a dialog. """Show transfer statistics in a dialog.
Args: Args:
@@ -437,7 +385,7 @@ class DialogManager:
# Close button # Close button
tk.Button(main_frame, text="Close", command=stats_window.destroy).pack() tk.Button(main_frame, text="Close", command=stats_window.destroy).pack()
def show_disable_debugging_reminder(self): def show_disable_debugging_reminder(self) -> None:
"""Show reminder about disabling USB debugging after transfer.""" """Show reminder about disabling USB debugging after transfer."""
messagebox.showinfo( messagebox.showinfo(
"Security Reminder", "Security Reminder",
-1
View File
@@ -255,7 +255,6 @@ class TransferManager:
lambda: self.dialog_manager.show_transfer_stats( lambda: self.dialog_manager.show_transfer_stats(
stats, stats,
direction.capitalize(), direction.capitalize(),
self.device_manager.adb_manager.deduplicator,
), ),
) )