diff --git a/setup.cfg b/setup.cfg index ef55ea95..9bc31e8c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -55,7 +55,6 @@ install_requires = tqdm>=4 importlib-metadata>=4;python_version<'3.8' # until Python 3.8 importlib-resources>=5;python_version<'3.9' # until Python 3.9 - typing-extensions;python_version<'3.8' # until Python 3.8 python_requires = >=3.7 include_package_data = True package_dir = diff --git a/tests/conftest.py b/tests/conftest.py index 4b20d94b..2f25a857 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -10,7 +10,7 @@ import platform import sys from pathlib import Path from subprocess import PIPE, CompletedProcess, run -from typing import AnyStr, List, Tuple, overload +from typing import List import pytest @@ -19,11 +19,6 @@ from ocrmypdf._exec import unpaper from ocrmypdf._plugin_manager import get_parser_options_plugins from ocrmypdf.exceptions import ExitCode -try: - from typing import Literal -except ImportError: - from typing_extensions import Literal - def is_linux(): return platform.system() == 'Linux' @@ -122,21 +117,9 @@ def run_ocrmypdf_api(input_file: Path, output_file: Path, *args) -> ExitCode: return api.run_pipeline(options, plugin_manager=None, api=False) -@overload def run_ocrmypdf( - input_file: Path, output_file: Path, *args, text: Literal[True] = True -) -> Tuple[CompletedProcess, str, str]: - ... - - -@overload -def run_ocrmypdf( - input_file: Path, output_file: Path, *args, text: Literal[False] -) -> Tuple[CompletedProcess, bytes, bytes]: - ... - - -def run_ocrmypdf(input_file: Path, output_file: Path, *args, text: bool = True): + input_file: Path, output_file: Path, *args, text: bool = True +) -> CompletedProcess: """Run ocrmypdf in a subprocess and let test deal with results. If an exception is thrown this fact will be returned as part of the result @@ -157,7 +140,7 @@ def run_ocrmypdf(input_file: Path, output_file: Path, *args, text: bool = True): check=False, ) # print(p.stderr) - return p, p.stdout, p.stderr + return p def first_page_dimensions(pdf: Path): diff --git a/tests/test_ghostscript.py b/tests/test_ghostscript.py index 28ecfe26..45b1ca37 100644 --- a/tests/test_ghostscript.py +++ b/tests/test_ghostscript.py @@ -76,7 +76,7 @@ def test_rasterize_rotated(francais, outdir, caplog): def test_gs_render_failure(resources, outpdf): - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'blank.pdf', outpdf, '--plugin', @@ -84,12 +84,12 @@ def test_gs_render_failure(resources, outpdf): '--plugin', 'tests/plugins/gs_render_failure.py', ) - assert 'Casper is not a friendly ghost' in err + assert 'Casper is not a friendly ghost' in p.stderr assert p.returncode == ExitCode.child_process_error def test_gs_raster_failure(resources, outpdf): - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'francais.pdf', outpdf, '--plugin', @@ -97,12 +97,12 @@ def test_gs_raster_failure(resources, outpdf): '--plugin', 'tests/plugins/gs_raster_failure.py', ) - assert 'Ghost story archive not found' in err + assert 'Ghost story archive not found' in p.stderr assert p.returncode == ExitCode.child_process_error def test_ghostscript_pdfa_failure(resources, outpdf): - p, _out, _err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'francais.pdf', outpdf, '--plugin', diff --git a/tests/test_main.py b/tests/test_main.py index c9b8ad51..910b2120 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -203,7 +203,7 @@ def test_force_ocr_on_pdf_with_no_images(resources, no_outpdf): # As a correctness test, make sure that --force-ocr on a PDF with no # content still triggers tesseract. If tesseract crashes, then it was # called. - p, _, _ = run_ocrmypdf( + p = run_ocrmypdf( resources / 'blank.pdf', no_outpdf, '--force-ocr', @@ -241,7 +241,7 @@ def test_german(resources, outdir): def test_klingon(resources, outpdf): - p, _, _ = run_ocrmypdf(resources / 'francais.pdf', outpdf, '-l', 'klz') + p = run_ocrmypdf(resources / 'francais.pdf', outpdf, '-l', 'klz') assert p.returncode == ExitCode.missing_dependency @@ -354,7 +354,7 @@ def test_tesseract_thresholding_invalid(value, resources, no_outpdf): @pytest.mark.parametrize('renderer', RENDERERS) def test_tesseract_crash(renderer, resources, no_outpdf): - p, _, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'ccitt.pdf', no_outpdf, '-v', @@ -366,11 +366,11 @@ def test_tesseract_crash(renderer, resources, no_outpdf): ) assert p.returncode == ExitCode.child_process_error assert not no_outpdf.exists() - assert "SubprocessOutputError" in err + assert "SubprocessOutputError" in p.stderr def test_tesseract_crash_autorotate(resources, no_outpdf): - p, out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'ccitt.pdf', no_outpdf, '-r', @@ -379,9 +379,9 @@ def test_tesseract_crash_autorotate(resources, no_outpdf): ) assert p.returncode == ExitCode.child_process_error assert not no_outpdf.exists() - assert "uncaught exception" in err - print(out) - print(err) + assert "uncaught exception" in p.stderr + print(p.stdout) + print(p.stderr) @pytest.mark.parametrize('renderer', RENDERERS) @@ -401,7 +401,7 @@ def test_tesseract_image_too_big(renderer, resources, outpdf): def test_algo4(resources, outpdf): - p, _, _ = run_ocrmypdf( + p = run_ocrmypdf( resources / 'encrypted_algo4.pdf', outpdf, '--plugin', @@ -471,7 +471,7 @@ def test_destination_not_writable(resources, outdir): protected_file = outdir / 'protected.pdf' protected_file.touch() protected_file.chmod(0o400) # Read-only - p, _out, _err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'jbig2.pdf', protected_file, '--plugin', @@ -512,7 +512,7 @@ THIS FILE IS INVALID ''' ) - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'ccitt.pdf', outdir / 'out.pdf', '--pdf-renderer', @@ -521,8 +521,8 @@ THIS FILE IS INVALID cfg_file, ) assert ( - "parameter not found" in err.lower() - or "error occurred while parsing" in err.lower() + "parameter not found" in p.stderr.lower() + or "error occurred while parsing" in p.stderr.lower() ), "No error message" assert p.returncode == ExitCode.invalid_config @@ -781,15 +781,13 @@ def test_pdfa_n(pdfa_level, resources, outpdf): def test_decompression_bomb_error(resources, outpdf): - p, _out, err = run_ocrmypdf(resources / 'hugemono.pdf', outpdf) - assert 'decompression bomb' in err and '--max-image-mpixels' in err + p = run_ocrmypdf(resources / 'hugemono.pdf', outpdf) + assert 'decompression bomb' in p.stderr and '--max-image-mpixels' in p.stderr @pytest.mark.slow def test_decompression_bomb_succeeds(resources, outpdf): - p, _out, err = run_ocrmypdf( - resources / 'hugemono.pdf', outpdf, '--max-image-mpixels', '2000' - ) + p = run_ocrmypdf(resources / 'hugemono.pdf', outpdf, '--max-image-mpixels', '2000') assert p.returncode == 0 @@ -818,7 +816,7 @@ def test_text_curves(resources, outpdf): def test_output_is_dir(resources, outdir): - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'trivial.pdf', outdir, '--force-ocr', @@ -826,28 +824,28 @@ def test_output_is_dir(resources, outdir): 'tests/plugins/tesseract_noop.py', ) assert p.returncode == ExitCode.file_access_error - assert 'is not a writable file' in err + assert 'is not a writable file' in p.stderr @pytest.mark.skipif(os.name == 'nt', reason="symlink needs admin permissions") def test_output_is_symlink(resources, outdir): sym = Path(outdir / 'this_is_a_symlink') sym.symlink_to(outdir / 'out.pdf') - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'trivial.pdf', sym, '--force-ocr', '--plugin', 'tests/plugins/tesseract_noop.py', ) - assert p.returncode == ExitCode.ok, err + assert p.returncode == ExitCode.ok, p.stderr assert (outdir / 'out.pdf').stat().st_size > 0, 'target file not created' def test_livecycle(resources, no_outpdf): - p, _, err = run_ocrmypdf(resources / 'livecycle.pdf', no_outpdf) + p = run_ocrmypdf(resources / 'livecycle.pdf', no_outpdf) - assert p.returncode == ExitCode.input_file, err + assert p.returncode == ExitCode.input_file, p.stderr def test_version_check(): @@ -904,7 +902,7 @@ def test_image_dpi_not_image(caplog, resources, outpdf): def test_outputtype_none_bad_setup(resources, outpdf): - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'trivial.pdf', outpdf, '--output-type=none', @@ -912,11 +910,11 @@ def test_outputtype_none_bad_setup(resources, outpdf): 'tests/plugins/tesseract_noop.py', ) assert p.returncode == ExitCode.bad_args - assert 'Set the output file to' in err + assert 'Set the output file to' in p.stderr def test_outputtype_none(resources, outtxt): - p, out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'trivial.pdf', '-', '--output-type=none', diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 6b3c5771..cde1e60c 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -62,7 +62,7 @@ def test_override_metadata(output_type, resources, outpdf): german = 'Du siehst den Wald vor lauter Bäumen nicht.' chinese = '孔子' - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( input_file, outpdf, '--title', @@ -75,7 +75,7 @@ def test_override_metadata(output_type, resources, outpdf): 'tests/plugins/tesseract_noop.py', ) - assert p.returncode == ExitCode.ok, err + assert p.returncode == ExitCode.ok, p.stderr before = pikepdf.open(input_file) after = pikepdf.open(outpdf) @@ -99,7 +99,7 @@ def test_high_unicode(resources, no_outpdf): input_file = resources / 'c02-22.pdf' high_unicode = 'U+1030C is: 𐌌' - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( input_file, no_outpdf, '--subject', @@ -110,7 +110,7 @@ def test_high_unicode(resources, no_outpdf): 'tests/plugins/tesseract_noop.py', ) - assert p.returncode == ExitCode.bad_args, err + assert p.returncode == ExitCode.bad_args, p.stderr @pytest.mark.skipif(not fitz, reason="test uses fitz") diff --git a/tests/test_rotation.py b/tests/test_rotation.py index 3052449e..d43ce1b9 100644 --- a/tests/test_rotation.py +++ b/tests/test_rotation.py @@ -242,7 +242,7 @@ def test_rotate_page_level(image_angle, page_angle, resources, outdir): test = make_rotate_test('test', image_angle, page_angle) out = test.with_suffix('.out.pdf') - p, _, err = run_ocrmypdf( + p = run_ocrmypdf( test, out, '-O0', @@ -251,7 +251,7 @@ def test_rotate_page_level(image_angle, page_angle, resources, outdir): '0.001', text=False, ) - err = err.decode('utf-8', errors='replace') + err = p.stderr.decode('utf-8', errors='replace') assert p.returncode == 0, err assert compare_images_monochrome(outdir, reference, 1, out, 1) > 0.2 diff --git a/tests/test_stdio.py b/tests/test_stdio.py index 06135dc1..4c8bbacc 100644 --- a/tests/test_stdio.py +++ b/tests/test_stdio.py @@ -60,10 +60,10 @@ def test_stdout(ocrmypdf_exec, resources, outpdf): @pytest.mark.skipif(os.name == 'nt', reason="invalid test on Windows") def test_bad_locale(monkeypatch): monkeypatch.setenv('LC_ALL', 'C') - p, out, err = run_ocrmypdf('a', 'b') - assert out == '', "stdout not clean" + p = run_ocrmypdf('a', 'b') + assert p.stdout == '', "stdout not clean" assert p.returncode != 0 - assert 'configured to use ASCII as encoding' in err, "should whine" + assert 'configured to use ASCII as encoding' in p.stderr, "should whine" @pytest.mark.xfail( @@ -74,7 +74,7 @@ def test_dev_null(resources): if 'COV_CORE_DATAFILE' in os.environ: pytest.skip(msg="Coverage uses stdout") - p, out, _err = run_ocrmypdf( + p = run_ocrmypdf( resources / 'trivial.pdf', os.devnull, '--force-ocr', @@ -82,4 +82,4 @@ def test_dev_null(resources): 'tests/plugins/tesseract_noop.py', ) assert p.returncode == 0, "could not send output to /dev/null" - assert len(out) == 0, "wrote to stdout" + assert len(p.stdout) == 0, "wrote to stdout" diff --git a/tests/test_unpaper.py b/tests/test_unpaper.py index de5a7f1f..e39b6bf6 100644 --- a/tests/test_unpaper.py +++ b/tests/test_unpaper.py @@ -71,7 +71,7 @@ def test_unpaper_args_valid(resources, outpdf): @pytest.mark.skipif(not have_unpaper(), reason="requires unpaper") def test_unpaper_args_invalid_filename(resources, outpdf): - p, _out, err = run_ocrmypdf( + p = run_ocrmypdf( resources / "skew.pdf", outpdf, "-c", @@ -80,13 +80,13 @@ def test_unpaper_args_invalid_filename(resources, outpdf): '--plugin', 'tests/plugins/tesseract_noop.py', ) - assert "No filenames allowed" in err + assert "No filenames allowed" in p.stderr assert p.returncode == ExitCode.bad_args @pytest.mark.skipif(not have_unpaper(), reason="requires unpaper") def test_unpaper_args_invalid(resources, outpdf): - p, _out, _err = run_ocrmypdf( + p = run_ocrmypdf( resources / "skew.pdf", outpdf, "-c",