refactor: post-AI code cleanup

This commit is contained in:
James R. Barlow
2025-12-21 12:21:47 -08:00
parent e1d976168c
commit 1f493ba789
19 changed files with 119 additions and 119 deletions
-1
View File
@@ -18,7 +18,6 @@ def main(
engine: Annotated[str, typer.Option()] = 'pdftotext',
):
"""Compare text in PDFs."""
text1 = run(
['pdftotext', '-layout', '-', '-'], stdin=pdf1, capture_output=True, check=True
)
-1
View File
@@ -9,7 +9,6 @@ import logging
import os
import re
from collections import deque
from io import BytesIO
from os import fspath
from pathlib import Path
from subprocess import PIPE, CalledProcessError
+4 -6
View File
@@ -5,12 +5,9 @@
from __future__ import annotations
import os
from collections.abc import Iterator
from copy import copy
from argparse import Namespace
from collections.abc import Iterator
from pathlib import Path
from typing import Union
from pluggy import PluginManager
@@ -29,7 +26,7 @@ class PdfContext:
def __init__(
self,
options: Union[OCROptions, Namespace],
options: OCROptions | Namespace,
work_folder: Path,
origin: Path,
pdfinfo: PdfInfo,
@@ -114,7 +111,6 @@ class PageContext:
# Fallback: if JSON serialization fails, convert to namespace
# This shouldn't happen but provides safety
from argparse import Namespace
import os
clean_options = Namespace()
for key, value in vars(self.options.to_namespace()).items():
@@ -122,6 +118,7 @@ class PageContext:
continue
try:
import pickle
pickle.dumps(value)
setattr(clean_options, key, value)
except TypeError:
@@ -138,6 +135,7 @@ class PageContext:
# Reconstruct OCROptions from JSON if available
if 'options_json' in state:
from ocrmypdf._options import OCROptions
self.options = OCROptions.model_validate_json_safe(state['options_json'])
# Otherwise, we have a fallback Namespace (shouldn't happen in normal operation)
# Leave it as-is for compatibility
-1
View File
@@ -15,7 +15,6 @@ from pikepdf import Dictionary, Name, Pdf
from pikepdf import __version__ as PIKEPDF_VERSION
from pikepdf.models.metadata import PdfMetadata, encode_pdf_date
from ocrmypdf._annots import remove_broken_goto_annotations
from ocrmypdf._defaults import PROGRAM_NAME
from ocrmypdf._jobcontext import PdfContext
from ocrmypdf._version import __version__ as OCRMYPF_VERSION
+16 -10
View File
@@ -10,11 +10,10 @@ import logging
import os
import unicodedata
from argparse import Namespace
from collections.abc import Iterable, Sequence
from copy import copy
from collections.abc import Sequence
from io import IOBase
from pathlib import Path
from typing import Any, BinaryIO, Union
from typing import Any, BinaryIO
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
@@ -24,7 +23,7 @@ from ocrmypdf.helpers import monotonic
log = logging.getLogger(__name__)
PathOrIO = Union[BinaryIO, IOBase, Path, str, bytes]
PathOrIO = BinaryIO | IOBase | Path | str | bytes
def _pages_from_ranges(ranges: str) -> set[int]:
@@ -159,7 +158,6 @@ class OCROptions(BaseModel):
# Plugin system
plugins: Sequence[Path | str] | None = None
# Store any extra attributes (for plugins and dynamic options)
extra_attrs: dict[str, Any] = Field(
default_factory=dict, exclude=True, alias='_extra_attrs'
@@ -259,7 +257,6 @@ class OCROptions(BaseModel):
raise ValueError(f"pdf_renderer must be one of {valid_renderers}")
return v
@field_validator('clean_final')
@classmethod
def validate_clean_final(cls, v, info):
@@ -359,7 +356,10 @@ class OCROptions(BaseModel):
@model_validator(mode='after')
def validate_output_type_compatibility(self):
"""Validate output type is compatible with output file."""
if self.output_type == 'none' and str(self.output_file) not in (os.devnull, '-'):
if self.output_type == 'none' and str(self.output_file) not in (
os.devnull,
'-',
):
raise ValueError(
"Since you specified `--output-type none`, the output file "
f"{self.output_file} cannot be produced. Set the output file to "
@@ -370,12 +370,14 @@ class OCROptions(BaseModel):
@model_validator(mode='after')
def set_lossless_reconstruction(self):
"""Set lossless_reconstruction based on other options."""
lossless = not any([
lossless = not any(
[
self.deskew,
self.clean_final,
self.force_ocr,
self.remove_background,
])
]
)
if not lossless and self.redo_ocr:
raise ValueError(
@@ -396,7 +398,11 @@ class OCROptions(BaseModel):
def _serialize_value(value):
if isinstance(value, Path):
return {'__type__': 'Path', 'value': str(value)}
elif isinstance(value, (BinaryIO, IOBase)) or hasattr(value, 'read') or hasattr(value, 'write'):
elif (
isinstance(value, (BinaryIO, IOBase))
or hasattr(value, 'read')
or hasattr(value, 'write')
):
# Stream object - replace with placeholder
return {'__type__': 'Stream', 'value': 'stream'}
elif hasattr(value, '__class__') and 'Iterator' in value.__class__.__name__:
+3 -1
View File
@@ -915,7 +915,9 @@ def convert_to_pdfa(input_pdf: Path, input_ps_stub: Path, context: PdfContext) -
if options.output_type == 'pdfa':
pdfa_part = '2' # Default to PDF/A-2
else:
pdfa_part = options.output_type.split('-')[-1] # Extract number from pdfa-1, pdfa-2, etc.
pdfa_part = options.output_type.split('-')[
-1
] # Extract number from pdfa-1, pdfa-2, etc.
else:
pdfa_part = '2' # Fallback
+3 -5
View File
@@ -50,9 +50,8 @@ from ocrmypdf._plugin_manager import OcrmypdfPluginManager
from ocrmypdf._validation import (
report_output_file_size,
)
from ocrmypdf.exceptions import BadArgsError, ExitCode, ExitCodeException
from ocrmypdf.exceptions import ExitCode, ExitCodeException
from ocrmypdf.helpers import (
available_cpu_count,
check_pdf,
pikepdf_enable_mmap,
running_in_docker,
@@ -328,13 +327,12 @@ def setup_pipeline(
return executor
def do_get_pdfinfo(
pdf_path: Path, executor: Executor, options
) -> PdfInfo:
def do_get_pdfinfo(pdf_path: Path, executor: Executor, options) -> PdfInfo:
# Handle pages field - it might be a string that needs conversion
check_pages = options.pages
if isinstance(check_pages, str):
from ocrmypdf._options import _pages_from_ranges
check_pages = _pages_from_ranges(check_pages)
return get_pdfinfo(
+2 -8
View File
@@ -6,19 +6,17 @@
from __future__ import annotations
import locale
import logging
import os
import sys
from collections.abc import Sequence
from pathlib import Path
from shutil import copyfileobj
from typing import Union
import pikepdf
from pluggy import PluginManager
from ocrmypdf._defaults import DEFAULT_LANGUAGE, DEFAULT_ROTATE_PAGES_THRESHOLD
from ocrmypdf._defaults import DEFAULT_ROTATE_PAGES_THRESHOLD
from ocrmypdf._exec import unpaper
from ocrmypdf._options import OCROptions
from ocrmypdf.exceptions import (
@@ -74,7 +72,6 @@ def check_options_languages(
raise MissingDependencyError(msg)
def check_options_sidecar(options: OCROptions) -> None:
if options.sidecar == '\0':
if options.output_file == '-':
@@ -117,16 +114,13 @@ def check_options_preprocessing(options: OCROptions) -> None:
raise BadArgsError("--unpaper-args: " + str(e)) from e
def _check_plugin_invariant_options(options: OCROptions) -> None:
check_platform()
check_options_sidecar(options)
check_options_preprocessing(options)
def _check_plugin_options(
options: OCROptions, plugin_manager: PluginManager
) -> None:
def _check_plugin_options(options: OCROptions, plugin_manager: PluginManager) -> None:
plugin_manager.hook.check_options(options=options)
ocr_engine_languages = plugin_manager.hook.get_ocr_engine().languages(options)
check_options_languages(options, ocr_engine_languages)
+19 -8
View File
@@ -43,7 +43,6 @@ import logging
import os
import sys
import threading
from argparse import Namespace
from collections.abc import Iterable, Sequence
from enum import IntEnum
from io import IOBase
@@ -172,8 +171,6 @@ def configure_logging(
return log
def create_options(
*, input_file: PathOrIO, output_file: PathOrIO, parser: ArgumentParser, **kwargs
) -> OCROptions:
@@ -199,7 +196,9 @@ def create_options(
options_kwargs['output_file'] = output_file
# Handle special stream cases for sidecar
if 'sidecar' in options_kwargs and isinstance(options_kwargs['sidecar'], BinaryIO | IOBase):
if 'sidecar' in options_kwargs and isinstance(
options_kwargs['sidecar'], BinaryIO | IOBase
):
# Keep the stream object as-is - OCROptions can handle it
pass
@@ -454,7 +453,11 @@ def _pdf_to_hocr( # noqa: D417
# Add all the function parameters
for param_name, param_value in locals().items():
if param_name not in {'input_pdf', 'output_folder', 'kwargs', 'plugin_manager', 'plugins'} and param_value is not None:
if (
param_name
not in {'input_pdf', 'output_folder', 'kwargs', 'plugin_manager', 'plugins'}
and param_value is not None
):
options_kwargs[param_name] = param_value
# Handle plugins separately
@@ -484,7 +487,9 @@ def _pdf_to_hocr( # noqa: D417
if extra_attrs:
options.extra_attrs.update(extra_attrs)
except Exception as e:
raise TypeError(f"Failed to create OCROptions for hOCR pipeline: {e}") from e
raise TypeError(
f"Failed to create OCROptions for hOCR pipeline: {e}"
) from e
return run_hocr_pipeline(options=options, plugin_manager=plugin_manager)
@@ -533,7 +538,11 @@ def _hocr_to_ocr_pdf( # noqa: D417
# Add all the function parameters
for param_name, param_value in locals().items():
if param_name not in {'work_folder', 'output_file', 'kwargs', 'plugin_manager', 'plugins'} and param_value is not None:
if (
param_name
not in {'work_folder', 'output_file', 'kwargs', 'plugin_manager', 'plugins'}
and param_value is not None
):
options_kwargs[param_name] = param_value
# Handle plugins separately
@@ -563,7 +572,9 @@ def _hocr_to_ocr_pdf( # noqa: D417
if extra_attrs:
options.extra_attrs.update(extra_attrs)
except Exception as e:
raise TypeError(f"Failed to create OCROptions for hOCR to PDF pipeline: {e}") from e
raise TypeError(
f"Failed to create OCROptions for hOCR to PDF pipeline: {e}"
) from e
return run_hocr_to_ocr_pdf_pipeline(
options=options, plugin_manager=plugin_manager
-1
View File
@@ -44,7 +44,6 @@ from ocrmypdf.helpers import Resolution, available_cpu_count, pikepdf_enable_mma
from ocrmypdf.pdfinfo.layout import (
LTStateAwareChar,
PdfMinerState,
get_page_analysis,
get_text_boxes,
)
-1
View File
@@ -3,7 +3,6 @@
from __future__ import annotations
import pytest
from pikepdf import Array, Dictionary, Name, NameTree, Pdf
from ocrmypdf._annots import remove_broken_goto_annotations
+1 -3
View File
@@ -1,10 +1,8 @@
"""Test JSON serialization of OCROptions for multiprocessing compatibility."""
import multiprocessing
from pathlib import Path
from io import BytesIO
import pytest
from pathlib import Path
from ocrmypdf._options import OCROptions
-2
View File
@@ -10,10 +10,8 @@ from shutil import copyfile
import pikepdf
import pytest
from packaging.version import Version
from pikepdf.models.metadata import decode_pdf_date
from ocrmypdf._exec import ghostscript
from ocrmypdf._jobcontext import PdfContext
from ocrmypdf._metadata import metadata_fixup
from ocrmypdf._pipeline import convert_to_pdfa
+1 -1
View File
@@ -13,7 +13,7 @@ import pytest
from ocrmypdf import pdfinfo
from ocrmypdf._exec import tesseract
from ocrmypdf.exceptions import BadArgsError, ExitCode, MissingDependencyError
from ocrmypdf.exceptions import BadArgsError, MissingDependencyError
from .conftest import check_ocrmypdf, run_ocrmypdf_api