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:
@@ -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
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user