Add compat function for pages_from_ranges

fix: handle Pydantic validation errors with correct exit code

Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit is contained in:
James R. Barlow
2025-12-21 12:21:46 -08:00
co-authored by aider
parent 7575dddefc
commit f5bfd2fd3e
4 changed files with 36 additions and 2 deletions
+6
View File
@@ -103,6 +103,8 @@ class PageContext:
self.pageno = pageno
self.pageinfo = pdf_context.pdfinfo[pageno]
self.plugin_manager = pdf_context.plugin_manager
# Ensure no reference to PdfContext which contains OCROptions
self._pdf_context = None
def get_path(self, name: str) -> Path:
"""Generate a ``Path`` for a file that is part of processing this page.
@@ -115,6 +117,7 @@ class PageContext:
def __getstate__(self):
state = self.__dict__.copy()
# Ensure we only pickle the Namespace, not any Pydantic objects
state['options'] = copy(self.options)
# Handle stream inputs
if hasattr(state['options'], 'input_file'):
@@ -123,4 +126,7 @@ class PageContext:
if hasattr(state['options'], 'output_file'):
if not isinstance(state['options'].output_file, str | bytes | os.PathLike):
state['options'].output_file = 'stream'
# Remove any potential references to Pydantic objects
state.pop('_pdf_context', None)
return state
+11 -1
View File
@@ -50,7 +50,7 @@ from ocrmypdf._plugin_manager import OcrmypdfPluginManager
from ocrmypdf._validation import (
report_output_file_size,
)
from ocrmypdf.exceptions import ExitCode, ExitCodeException
from ocrmypdf.exceptions import BadArgsError, ExitCode, ExitCodeException
from ocrmypdf.helpers import (
available_cpu_count,
check_pdf,
@@ -275,6 +275,16 @@ def cli_exception_handler(
else:
log.error(type(e).__name__)
return e.exit_code
except ValueError as e:
# Convert Pydantic validation errors to BadArgsError for proper exit code
if "validation error" in str(e).lower() or "value error" in str(e).lower():
if options.verbose >= 1:
log.exception("Validation error")
else:
log.error("Invalid argument: %s", str(e))
return ExitCode.bad_args
# Re-raise other ValueErrors to be caught by the general exception handler
raise
except PIL.Image.DecompressionBombError:
log.exception(
"A decompression bomb error was encountered while executing the "
+18
View File
@@ -48,6 +48,21 @@ from ocrmypdf._validation import (
check_requested_output_file,
create_input_file,
)
def _convert_pages_field_for_legacy_compatibility(options: argparse.Namespace) -> None:
"""Convert pages field from string to set if needed.
This is a temporary shim to handle the transition from CLI string processing
to OCROptions Pydantic validation. The pages field needs to be converted
before calling do_get_pdfinfo() since PdfInfo expects a Container[int].
TODO: Remove this function when the refactoring plan is complete and all
pipeline functions work directly with OCROptions instead of Namespace.
"""
if hasattr(options, 'pages') and isinstance(options.pages, str):
from ocrmypdf._options import _pages_from_ranges
options.pages = _pages_from_ranges(options.pages)
from ocrmypdf.exceptions import ExitCode
log = logging.getLogger(__name__)
@@ -175,6 +190,9 @@ def _run_pipeline(
original_filename, start_input_file, work_folder / 'origin.pdf', options
)
# Convert pages field if needed before gathering pdfinfo
_convert_pages_field_for_legacy_compatibility(options)
# Gather pdfinfo and create context
pdfinfo = do_get_pdfinfo(origin_pdf, executor, options)
context = PdfContext(options, work_folder, origin_pdf, pdfinfo, plugin_manager)
+1 -1
View File
@@ -6,7 +6,7 @@ from __future__ import annotations
import pytest
import ocrmypdf
from ocrmypdf._validation import _pages_from_ranges
from ocrmypdf._options import _pages_from_ranges
from ocrmypdf.exceptions import BadArgsError
from ocrmypdf.pdfinfo import PdfInfo