From 5ed05e08b1f71e663316a4b2c8b1c84967c22701 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Fri, 9 Nov 2018 01:40:01 -0800 Subject: [PATCH] Fix "no languages" test and misuse of os.environ --- src/ocrmypdf/exec/tesseract.py | 31 +++++++++++++++++++++---------- tests/test_tess4.py | 22 +++++++++++++++++++--- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/ocrmypdf/exec/tesseract.py b/src/ocrmypdf/exec/tesseract.py index 1dce012c..fde6b066 100644 --- a/src/ocrmypdf/exec/tesseract.py +++ b/src/ocrmypdf/exec/tesseract.py @@ -21,7 +21,7 @@ import shutil from functools import lru_cache from collections import namedtuple from textwrap import dedent -from subprocess import CalledProcessError, TimeoutExpired, check_output, STDOUT +from subprocess import CalledProcessError, TimeoutExpired, check_output, STDOUT, run, PIPE from contextlib import suppress from ..exceptions import MissingDependencyError, TesseractConfigError @@ -92,22 +92,33 @@ def psm(): @lru_cache(maxsize=1) def languages(): + def lang_error(output): + msg = dedent("""Tesseract failed to report available languages. + Output from Tesseract: + ----------- + """) + msg += output + print(msg, file=sys.stderr) + args_tess = [ 'tesseract', '--list-langs' ] try: - langs = check_output( - args_tess, universal_newlines=True, stderr=STDOUT) + proc = run( + args_tess, universal_newlines=True, stdout=PIPE, stderr=STDOUT, + check=True + ) + output = proc.stdout except CalledProcessError as e: - msg = dedent("""Tesseract failed to report available languages. - Output from Tesseract: - ----------- - """) - msg += e.output - print(msg, file=sys.stderr) + lang_error(e.output) raise MissingDependencyError from e - return set(lang.strip() for lang in langs.splitlines()[1:]) + + header, *rest = output.splitlines() + if not header.startswith('List of available languages'): + lang_error(output) + raise MissingDependencyError + return set(lang.strip() for lang in rest) def tess_base_args(langs, engine_mode): diff --git a/tests/test_tess4.py b/tests/test_tess4.py index 859b3cbb..0af3b7e6 100644 --- a/tests/test_tess4.py +++ b/tests/test_tess4.py @@ -16,8 +16,9 @@ # along with OCRmyPDF. If not, see . import pytest -from ocrmypdf.exceptions import ExitCode +from ocrmypdf.exceptions import ExitCode, MissingDependencyError from ocrmypdf.exec import tesseract +from ocrmypdf.helpers import fspath from ocrmypdf import pdfinfo import sys import os @@ -43,6 +44,7 @@ def _ensure_tess4(): tess4 = Path(os.environ['OCRMYPDF_TESS4']) assert tess4.is_file() env['PATH'] = tess4.parent + ':' + env['PATH'] + env['OCRMYPDF_TESS4'] = os.environ['OCRMYPDF_TESS4'] return env raise EnvironmentError("Can't find Tesseract 4") @@ -56,9 +58,12 @@ def ensure_tess4(): @contextmanager def modified_os_environ(env): old_env = os.environ.copy() - os.environ = env + os.environ.update(env) yield - os.environ = old_env + for key in env: + del os.environ[key] + if key in old_env: + os.environ[key] = old_env[key] def tess4_available(): @@ -149,3 +154,14 @@ def test_content_preservation(ensure_tess4, resources, outpdf): info = pdfinfo.PdfInfo(outpdf) page = info[0] assert len(page.images) > 1, "masks were rasterized" + + +def test_no_languages(ensure_tess4, tmpdir): + env = ensure_tess4 + (tmpdir / 'tessdata').mkdir() + env['TESSDATA_PREFIX'] = fspath(tmpdir) + + with modified_os_environ(env): + with pytest.raises(MissingDependencyError): + tesseract.languages.cache_clear() + tesseract.languages()