Fixing up the tests and redirecting the progress bar to stderr

This commit is contained in:
Trenton H
2026-02-25 14:46:42 -08:00
parent 7080322c41
commit 0c98e4f4f1
4 changed files with 39 additions and 20 deletions

View File

@@ -18,6 +18,7 @@ from typing import TypeVar
from django import db
from django.core.management import CommandError
from django_rich.management import RichCommand
from rich.console import Console
from rich.progress import BarColumn
from rich.progress import MofNCompleteColumn
from rich.progress import Progress
@@ -142,6 +143,12 @@ class PaperlessCommand(RichCommand):
"""
Create a configured Progress instance.
Progress output is directed to stderr to match the convention that
progress bars are transient UI feedback, not command output. This
mirrors tqdm's default behavior and prevents progress bar rendering
from interfering with stdout-based assertions in tests or piped
command output.
Args:
description: Text to display alongside the progress bar.
@@ -155,7 +162,7 @@ class PaperlessCommand(RichCommand):
MofNCompleteColumn(),
TimeElapsedColumn(),
TimeRemainingColumn(),
console=self.console,
console=Console(stderr=True),
transient=False,
)

View File

@@ -62,9 +62,10 @@ class Command(PaperlessCommand):
RATIO_MAX: Final[float] = 100.0
if options["delete"]:
self.console.print(
"[yellow]The command is configured to delete documents. "
"Use with caution.[/yellow]",
self.stdout.write(
self.style.WARNING(
"The command is configured to delete documents. Use with caution",
),
)
opt_ratio = options["ratio"]
@@ -90,17 +91,21 @@ class Command(PaperlessCommand):
work_pkgs.append(_WorkPackage(first_doc, second_doc))
results: list[_WorkResult] = []
for result in self.process_parallel(
_process_and_match,
work_pkgs,
description="Matching...",
):
if result.error:
self.console.print(
f"[red]Failed: {result.error}[/red]",
)
elif result.result is not None:
results.append(result.result)
if self.process_count == 1:
for work in self.track(work_pkgs, description="Matching..."):
results.append(_process_and_match(work))
else: # pragma: no cover
for proc_result in self.process_parallel(
_process_and_match,
work_pkgs,
description="Matching...",
):
if proc_result.error:
self.console.print(
f"[red]Failed: {proc_result.error}[/red]",
)
elif proc_result.result is not None:
results.append(proc_result.result)
messages: list[str] = []
maybe_delete_ids: list[int] = []
@@ -120,8 +125,9 @@ class Command(PaperlessCommand):
self.stdout.writelines(messages)
if options["delete"]:
self.console.print(
f"[yellow]Deleting {len(maybe_delete_ids)} documents "
f"based on ratio matches[/yellow]",
self.stdout.write(
self.style.NOTICE(
f"Deleting {len(maybe_delete_ids)} documents based on ratio matches",
),
)
Document.objects.filter(pk__in=maybe_delete_ids).delete()

View File

@@ -5,13 +5,19 @@ from documents.management.commands.base import PaperlessCommand
from documents.models import Document
from documents.parsers import get_parser_class_for_mime_type
logger = logging.getLogger("paperless.management.thumbnails")
def _process_document(doc_id: int) -> None:
document: Document = Document.objects.get(id=doc_id)
parser_class = get_parser_class_for_mime_type(document.mime_type)
if parser_class is None:
print(f"{document} No parser for mime type {document.mime_type}") # noqa: T201
logger.warning(
"%s: No parser for mime type %s",
document,
document.mime_type,
)
return
parser = parser_class(logging_group=None)

View File

@@ -140,7 +140,7 @@ class TestFuzzyMatchCommand(TestCase):
mime_type="application/pdf",
filename="final_test.pdf",
)
stdout, _ = self.call_command()
stdout, _ = self.call_command("--no-progress-bar")
lines = [x.strip() for x in stdout.splitlines() if x.strip()]
self.assertEqual(len(lines), 3)
for line in lines: