Rename OCROptions to OcrOptions for consistency
Technically OCROptions is more Pythonic but we have several pre-existing classes named OcrWhatever. Go with the local flow.
This commit is contained in:
+2
-2
@@ -107,14 +107,14 @@ def test_hocr_result_pickle():
|
||||
|
||||
def test_nested_plugin_option_access():
|
||||
"""Test that plugin options can be accessed via nested namespaces."""
|
||||
from ocrmypdf._options import OCROptions
|
||||
from ocrmypdf._options import OcrOptions
|
||||
from ocrmypdf.api import setup_plugin_infrastructure
|
||||
|
||||
# Set up plugin infrastructure to register plugin models
|
||||
setup_plugin_infrastructure()
|
||||
|
||||
# Create options with tesseract settings
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file='test.pdf',
|
||||
output_file='output.pdf',
|
||||
tesseract_timeout=120.0,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Test JSON serialization of OCROptions for multiprocessing compatibility."""
|
||||
"""Test JSON serialization of OcrOptions for multiprocessing compatibility."""
|
||||
|
||||
import multiprocessing
|
||||
from io import BytesIO
|
||||
@@ -6,28 +6,28 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from ocrmypdf._options import OCROptions
|
||||
from ocrmypdf._options import OcrOptions
|
||||
from ocrmypdf.builtin_plugins.tesseract_ocr import TesseractOptions
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def register_plugin_models():
|
||||
"""Register plugin models for tests."""
|
||||
OCROptions.register_plugin_models({'tesseract': TesseractOptions})
|
||||
OcrOptions.register_plugin_models({'tesseract': TesseractOptions})
|
||||
yield
|
||||
# Clean up after test (optional, but good practice)
|
||||
|
||||
|
||||
def worker_function(options_json: str) -> str:
|
||||
"""Worker function that deserializes OCROptions from JSON and returns a result."""
|
||||
"""Worker function that deserializes OcrOptions from JSON and returns a result."""
|
||||
# Register plugin models in worker process
|
||||
from ocrmypdf._options import OCROptions
|
||||
from ocrmypdf._options import OcrOptions
|
||||
from ocrmypdf.builtin_plugins.tesseract_ocr import TesseractOptions
|
||||
|
||||
OCROptions.register_plugin_models({'tesseract': TesseractOptions})
|
||||
OcrOptions.register_plugin_models({'tesseract': TesseractOptions})
|
||||
|
||||
# Reconstruct OCROptions from JSON in worker process
|
||||
options = OCROptions.model_validate_json_safe(options_json)
|
||||
# Reconstruct OcrOptions from JSON in worker process
|
||||
options = OcrOptions.model_validate_json_safe(options_json)
|
||||
|
||||
# Verify we can access various option types
|
||||
# Count only user-added extra_attrs (exclude plugin cache keys starting with '_')
|
||||
@@ -51,9 +51,9 @@ def worker_function(options_json: str) -> str:
|
||||
|
||||
|
||||
def test_json_serialization_multiprocessing():
|
||||
"""Test that OCROptions can be JSON serialized and used in multiprocessing."""
|
||||
# Create OCROptions with various field types
|
||||
options = OCROptions(
|
||||
"""Test that OcrOptions can be JSON serialized and used in multiprocessing."""
|
||||
# Create OcrOptions with various field types
|
||||
options = OcrOptions(
|
||||
input_file=Path('/test/input.pdf'),
|
||||
output_file=Path('/test/output.pdf'),
|
||||
languages=['eng', 'deu'],
|
||||
@@ -72,7 +72,7 @@ def test_json_serialization_multiprocessing():
|
||||
options_json = options.model_dump_json_safe()
|
||||
|
||||
# Test that we can deserialize in the main process
|
||||
reconstructed = OCROptions.model_validate_json_safe(options_json)
|
||||
reconstructed = OcrOptions.model_validate_json_safe(options_json)
|
||||
assert reconstructed.input_file == options.input_file
|
||||
assert reconstructed.output_file == options.output_file
|
||||
assert reconstructed.languages == options.languages
|
||||
@@ -112,7 +112,7 @@ def test_json_serialization_with_streams():
|
||||
input_stream = BytesIO(b'fake pdf data')
|
||||
output_stream = BytesIO()
|
||||
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file=input_stream,
|
||||
output_file=output_stream,
|
||||
languages=['eng'],
|
||||
@@ -123,7 +123,7 @@ def test_json_serialization_with_streams():
|
||||
options_json = options.model_dump_json_safe()
|
||||
|
||||
# Deserialize (streams will be placeholder strings)
|
||||
reconstructed = OCROptions.model_validate_json_safe(options_json)
|
||||
reconstructed = OcrOptions.model_validate_json_safe(options_json)
|
||||
|
||||
# Streams should be converted to placeholder strings
|
||||
assert reconstructed.input_file == 'stream'
|
||||
@@ -134,7 +134,7 @@ def test_json_serialization_with_streams():
|
||||
|
||||
def test_json_serialization_with_none_values():
|
||||
"""Test JSON serialization handles None values correctly."""
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file=Path('/test/input.pdf'),
|
||||
output_file=Path('/test/output.pdf'),
|
||||
languages=['eng'],
|
||||
@@ -145,7 +145,7 @@ def test_json_serialization_with_none_values():
|
||||
options_json = options.model_dump_json_safe()
|
||||
|
||||
# Deserialize
|
||||
reconstructed = OCROptions.model_validate_json_safe(options_json)
|
||||
reconstructed = OcrOptions.model_validate_json_safe(options_json)
|
||||
|
||||
# Verify None values are preserved (check actual defaults from model)
|
||||
assert reconstructed.tesseract_timeout == 0.0 # Default value, not None
|
||||
|
||||
@@ -74,14 +74,14 @@ class TestOcrEngineCliOption:
|
||||
|
||||
|
||||
class TestOcrEngineOptionsModel:
|
||||
"""Test OCROptions has ocr_engine field."""
|
||||
"""Test OcrOptions has ocr_engine field."""
|
||||
|
||||
def test_ocr_options_has_ocr_engine_field(self):
|
||||
"""OCROptions should have ocr_engine field."""
|
||||
from ocrmypdf._options import OCROptions
|
||||
"""OcrOptions should have ocr_engine field."""
|
||||
from ocrmypdf._options import OcrOptions
|
||||
|
||||
# Check field exists in model
|
||||
assert 'ocr_engine' in OCROptions.model_fields
|
||||
assert 'ocr_engine' in OcrOptions.model_fields
|
||||
|
||||
|
||||
class TestOcrEnginePluginSelection:
|
||||
@@ -91,8 +91,8 @@ class TestOcrEnginePluginSelection:
|
||||
"""TesseractOcrEngine should be returned when ocr_engine='auto'."""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from ocrmypdf.builtin_plugins.tesseract_ocr import TesseractOcrEngine
|
||||
from ocrmypdf.builtin_plugins import tesseract_ocr
|
||||
from ocrmypdf.builtin_plugins.tesseract_ocr import TesseractOcrEngine
|
||||
|
||||
options = MagicMock()
|
||||
options.ocr_engine = 'auto'
|
||||
@@ -104,8 +104,8 @@ class TestOcrEnginePluginSelection:
|
||||
"""TesseractOcrEngine should be returned when ocr_engine='tesseract'."""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from ocrmypdf.builtin_plugins.tesseract_ocr import TesseractOcrEngine
|
||||
from ocrmypdf.builtin_plugins import tesseract_ocr
|
||||
from ocrmypdf.builtin_plugins.tesseract_ocr import TesseractOcrEngine
|
||||
|
||||
options = MagicMock()
|
||||
options.ocr_engine = 'tesseract'
|
||||
@@ -117,8 +117,8 @@ class TestOcrEnginePluginSelection:
|
||||
"""NullOcrEngine should be returned when ocr_engine='none'."""
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from ocrmypdf.builtin_plugins.null_ocr import NullOcrEngine
|
||||
from ocrmypdf.builtin_plugins import null_ocr
|
||||
from ocrmypdf.builtin_plugins.null_ocr import NullOcrEngine
|
||||
|
||||
options = MagicMock()
|
||||
options.ocr_engine = 'none'
|
||||
|
||||
+16
-17
@@ -12,7 +12,7 @@ import pikepdf
|
||||
import pytest
|
||||
from PIL import Image
|
||||
|
||||
from ocrmypdf._options import OCROptions
|
||||
from ocrmypdf._options import OcrOptions
|
||||
from ocrmypdf._plugin_manager import get_plugin_manager
|
||||
from ocrmypdf.helpers import IMG2PDF_KWARGS, Resolution
|
||||
|
||||
@@ -67,7 +67,7 @@ class TestRasterizerOption:
|
||||
def test_rasterizer_invalid(self):
|
||||
"""Test that an invalid rasterizer value is rejected."""
|
||||
with pytest.raises(ValueError, match="rasterizer must be one of"):
|
||||
OCROptions(
|
||||
OcrOptions(
|
||||
input_file='test.pdf', output_file='out.pdf', rasterizer='invalid'
|
||||
)
|
||||
|
||||
@@ -127,7 +127,7 @@ class TestRasterizerHookDirect:
|
||||
pm = get_plugin_manager([])
|
||||
|
||||
# Create options requesting pypdfium
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file=resources / 'graph.pdf',
|
||||
output_file=tmp_path / 'out.pdf',
|
||||
rasterizer='pypdfium',
|
||||
@@ -162,7 +162,7 @@ class TestRasterizerHookDirect:
|
||||
pm = get_plugin_manager([])
|
||||
|
||||
# Create options requesting ghostscript
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file=resources / 'graph.pdf',
|
||||
output_file=tmp_path / 'out.pdf',
|
||||
rasterizer='ghostscript',
|
||||
@@ -190,7 +190,7 @@ class TestRasterizerHookDirect:
|
||||
"""Test that auto mode uses pypdfium when available."""
|
||||
pm = get_plugin_manager([])
|
||||
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file=resources / 'graph.pdf',
|
||||
output_file=tmp_path / 'out.pdf',
|
||||
rasterizer='auto',
|
||||
@@ -363,7 +363,7 @@ class TestRasterizerWithNonStandardBoxes:
|
||||
"""Compare output dimensions between rasterizers for nonstandard boxes."""
|
||||
pm = get_plugin_manager([])
|
||||
|
||||
options_gs = OCROptions(
|
||||
options_gs = OcrOptions(
|
||||
input_file=pdf_with_nonstandard_boxes,
|
||||
output_file=tmp_path / 'out_gs.pdf',
|
||||
rasterizer='ghostscript',
|
||||
@@ -388,7 +388,7 @@ class TestRasterizerWithNonStandardBoxes:
|
||||
gs_size = im_gs.size
|
||||
|
||||
if PYPDFIUM_AVAILABLE:
|
||||
options_pdfium = OCROptions(
|
||||
options_pdfium = OcrOptions(
|
||||
input_file=pdf_with_nonstandard_boxes,
|
||||
output_file=tmp_path / 'out_pdfium.pdf',
|
||||
rasterizer='pypdfium',
|
||||
@@ -445,7 +445,7 @@ class TestRasterizerWithRotationAndBoxes:
|
||||
"""Test Ghostscript produces correct dimensions with rotation."""
|
||||
pm = get_plugin_manager([])
|
||||
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file=pdf_with_nonstandard_boxes,
|
||||
output_file=tmp_path / 'out.pdf',
|
||||
rasterizer='ghostscript',
|
||||
@@ -481,13 +481,11 @@ class TestRasterizerWithRotationAndBoxes:
|
||||
)
|
||||
|
||||
@pytest.mark.skipif(not PYPDFIUM_AVAILABLE, reason="pypdfium2 not installed")
|
||||
def test_pypdfium_rotation_dimensions(
|
||||
self, pdf_with_nonstandard_boxes, tmp_path
|
||||
):
|
||||
def test_pypdfium_rotation_dimensions(self, pdf_with_nonstandard_boxes, tmp_path):
|
||||
"""Test pypdfium produces correct dimensions with rotation."""
|
||||
pm = get_plugin_manager([])
|
||||
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file=pdf_with_nonstandard_boxes,
|
||||
output_file=tmp_path / 'out.pdf',
|
||||
rasterizer='pypdfium',
|
||||
@@ -535,7 +533,7 @@ class TestRasterizerWithRotationAndBoxes:
|
||||
|
||||
for rotation in [0, 90, 180, 270]:
|
||||
# Rasterize with Ghostscript
|
||||
gs_options = OCROptions(
|
||||
gs_options = OcrOptions(
|
||||
input_file=pdf_with_nonstandard_boxes,
|
||||
output_file=tmp_path / 'out.pdf',
|
||||
rasterizer='ghostscript',
|
||||
@@ -556,7 +554,7 @@ class TestRasterizerWithRotationAndBoxes:
|
||||
)
|
||||
|
||||
# Rasterize with pypdfium
|
||||
pdfium_options = OCROptions(
|
||||
pdfium_options = OcrOptions(
|
||||
input_file=pdf_with_nonstandard_boxes,
|
||||
output_file=tmp_path / 'out.pdf',
|
||||
rasterizer='pypdfium',
|
||||
@@ -577,9 +575,10 @@ class TestRasterizerWithRotationAndBoxes:
|
||||
)
|
||||
|
||||
# Verify both produce the same MediaBox dimensions
|
||||
with Image.open(gs_img_path) as gs_img, Image.open(
|
||||
pdfium_img_path
|
||||
) as pdfium_img:
|
||||
with (
|
||||
Image.open(gs_img_path) as gs_img,
|
||||
Image.open(pdfium_img_path) as pdfium_img,
|
||||
):
|
||||
expected = self._get_expected_size(rotation)
|
||||
|
||||
assert abs(gs_img.size[0] - expected[0]) <= 2, (
|
||||
|
||||
@@ -329,11 +329,11 @@ def test_rotate_and_crop(
|
||||
|
||||
|
||||
def test_rasterize_rotates(resources, tmp_path):
|
||||
from ocrmypdf._options import OCROptions
|
||||
from ocrmypdf._options import OcrOptions
|
||||
|
||||
pm = get_plugin_manager([])
|
||||
|
||||
options = OCROptions(
|
||||
options = OcrOptions(
|
||||
input_file=resources / 'graph.pdf',
|
||||
output_file=tmp_path / 'out.pdf',
|
||||
rasterizer='ghostscript', # Use Ghostscript for consistent dimensions
|
||||
|
||||
@@ -13,7 +13,7 @@ import pytest
|
||||
from ocrmypdf import _validation as vd
|
||||
from ocrmypdf._concurrent import NullProgressBar, SerialExecutor
|
||||
from ocrmypdf._exec.tesseract import TesseractVersion
|
||||
from ocrmypdf._options import OCROptions
|
||||
from ocrmypdf._options import OcrOptions
|
||||
from ocrmypdf.api import create_options, setup_plugin_infrastructure
|
||||
from ocrmypdf.cli import get_parser
|
||||
from ocrmypdf.exceptions import BadArgsError, MissingDependencyError
|
||||
@@ -42,8 +42,8 @@ def make_opts(*args, **kwargs):
|
||||
|
||||
|
||||
def make_ocr_opts(input_file='a.pdf', output_file='b.pdf', **kwargs):
|
||||
"""Create OCROptions directly for testing Pydantic validation."""
|
||||
return OCROptions(input_file=input_file, output_file=output_file, **kwargs)
|
||||
"""Create OcrOptions directly for testing Pydantic validation."""
|
||||
return OcrOptions(input_file=input_file, output_file=output_file, **kwargs)
|
||||
|
||||
|
||||
def test_old_tesseract_error():
|
||||
@@ -95,7 +95,7 @@ def test_optimizing(caplog):
|
||||
|
||||
|
||||
def test_pillow_options():
|
||||
# Test that max_image_mpixels=0 is valid (validation now in OCROptions)
|
||||
# Test that max_image_mpixels=0 is valid (validation now in OcrOptions)
|
||||
opts = make_ocr_opts(max_image_mpixels=0)
|
||||
assert opts.max_image_mpixels == 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user