diff --git a/src/ocrmypdf/api.py b/src/ocrmypdf/api.py index 008d284d..7e389d88 100644 --- a/src/ocrmypdf/api.py +++ b/src/ocrmypdf/api.py @@ -143,7 +143,7 @@ def create_options( # These arguments with special handling for which we bypass # argparse - if arg in {'tesseract_env', 'progress_bar', 'plugins'}: + if arg in {'progress_bar', 'plugins'}: deferred.append((arg, val)) continue diff --git a/src/ocrmypdf/builtin_plugins/tesseract_ocr.py b/src/ocrmypdf/builtin_plugins/tesseract_ocr.py index d5f5eb7b..150fcedf 100644 --- a/src/ocrmypdf/builtin_plugins/tesseract_ocr.py +++ b/src/ocrmypdf/builtin_plugins/tesseract_ocr.py @@ -81,7 +81,6 @@ def add_options(parser): metavar='FILE', help="Specify the location of the Tesseract user patterns file.", ) - tess.add_argument('--tesseract-env', type=str, help=argparse.SUPPRESS) @hookimpl @@ -98,15 +97,13 @@ def check_options(options): options.pdf_renderer = 'sandwich' if options.pdf_renderer == 'sandwich' and not tesseract.has_textonly_pdf( - options.tesseract_env, set(options.languages) + set(options.languages) ): raise MissingDependencyError( "You are using an alpha version of Tesseract 4.0 that does not support " "the textonly_pdf parameter. We don't support versions this old." ) - if not tesseract.has_user_words(options.tesseract_env) and ( - options.user_words or options.user_patterns - ): + if not tesseract.has_user_words() and (options.user_words or options.user_patterns): log.warning( "Tesseract 4.0 ignores --user-words and --user-patterns, so these " "arguments have no effect." @@ -120,13 +117,6 @@ def check_options(options): @hookimpl def validate(pdfinfo, options): - if not options.tesseract_env: - return - - # If we are running a Tesseract spoof, ensure it knows what the input file is - if os.environ.get('PYTEST_CURRENT_TEST'): - options.tesseract_env['_OCRMYPDF_TEST_INFILE'] = os.fspath(options.input_file) - # Tesseract 4.x can be multithreaded, and we also run multiple workers. We want # to manage how many threads it uses to avoid creating total threads than cores. # Performance testing shows we're better off @@ -135,11 +125,11 @@ def validate(pdfinfo, options): # input file is small, then we allow Tesseract to use threads, subject to the # constraint: (ocrmypdf workers) * (tesseract threads) <= max_workers. # As of Tesseract 4.1, 3 threads is the most effective on a 4 core/8 thread system. - if not options.tesseract_env.get('OMP_THREAD_LIMIT', '').isnumeric(): + if not os.environ.get('OMP_THREAD_LIMIT', '').isnumeric(): tess_threads = min(3, options.jobs // len(pdfinfo), len(pdfinfo)) - options.tesseract_env['OMP_THREAD_LIMIT'] = str(tess_threads) + os.environ['OMP_THREAD_LIMIT'] = str(tess_threads) else: - tess_threads = int(options.tesseract_env['OMP_THREAD_LIMIT']) + tess_threads = int(os.environ['OMP_THREAD_LIMIT']) if tess_threads > 1: log.info("Using Tesseract OpenMP thread limit %d", tess_threads) @@ -160,7 +150,7 @@ class TesseractOcrEngine(OcrEngine): @staticmethod def languages(options): - return tesseract.get_languages(options.tesseract_env) + return tesseract.get_languages() @staticmethod def get_orientation(input_file, options): @@ -168,7 +158,6 @@ class TesseractOcrEngine(OcrEngine): input_file, engine_mode=options.tesseract_oem, timeout=options.tesseract_timeout, - tesseract_env=options.tesseract_env, ) @staticmethod @@ -184,7 +173,6 @@ class TesseractOcrEngine(OcrEngine): pagesegmode=options.tesseract_pagesegmode, user_words=options.user_words, user_patterns=options.user_patterns, - tesseract_env=options.tesseract_env, ) @staticmethod @@ -200,7 +188,6 @@ class TesseractOcrEngine(OcrEngine): pagesegmode=options.tesseract_pagesegmode, user_words=options.user_words, user_patterns=options.user_patterns, - tesseract_env=options.tesseract_env, ) diff --git a/src/ocrmypdf/exec/tesseract.py b/src/ocrmypdf/exec/tesseract.py index 591445b7..d163d305 100644 --- a/src/ocrmypdf/exec/tesseract.py +++ b/src/ocrmypdf/exec/tesseract.py @@ -65,11 +65,11 @@ class TesseractLoggerAdapter(logging.LoggerAdapter): return '[tesseract] %s' % (msg), kwargs -def version(tesseract_env=None): - return get_version('tesseract', regex=r'tesseract\s(.+)', env=tesseract_env) +def version(): + return get_version('tesseract', regex=r'tesseract\s(.+)') -def has_textonly_pdf(tesseract_env=None, langs=None): +def has_textonly_pdf(langs=None): """Does Tesseract have textonly_pdf capability? Available in v4.00.00alpha since January 2017. Best to @@ -79,12 +79,7 @@ def has_textonly_pdf(tesseract_env=None, langs=None): params = '' try: proc = run( - args_tess, - check=True, - universal_newlines=True, - stdout=PIPE, - stderr=STDOUT, - env=tesseract_env, + args_tess, check=True, universal_newlines=True, stdout=PIPE, stderr=STDOUT ) params = proc.stdout except CalledProcessError as e: @@ -97,16 +92,16 @@ def has_textonly_pdf(tesseract_env=None, langs=None): return False -def has_user_words(tesseract_env=None): +def has_user_words(): """Does Tesseract have --user-words capability? Not available in 4.0, but available in 4.1. Also available in 3.x, but we no longer support 3.x. """ - return version(tesseract_env) >= '4.1' + return version() >= '4.1' -def get_languages(tesseract_env=None): +def get_languages(): def lang_error(output): msg = ( "Tesseract failed to report available languages.\n" @@ -119,12 +114,7 @@ def get_languages(tesseract_env=None): args_tess = ['tesseract', '--list-langs'] try: proc = run( - args_tess, - universal_newlines=True, - stdout=PIPE, - stderr=STDOUT, - check=True, - env=tesseract_env, + args_tess, universal_newlines=True, stdout=PIPE, stderr=STDOUT, check=True ) output = proc.stdout except CalledProcessError as e: @@ -146,7 +136,7 @@ def tess_base_args(langs: List[str], engine_mode) -> List[str]: return args -def get_orientation(input_file: Path, engine_mode, timeout: float, tesseract_env=None): +def get_orientation(input_file: Path, engine_mode, timeout: float): args_tesseract = tess_base_args(['osd'], engine_mode) + [ '--psm', '0', @@ -155,14 +145,7 @@ def get_orientation(input_file: Path, engine_mode, timeout: float, tesseract_env ] try: - p = run( - args_tesseract, - stdout=PIPE, - stderr=STDOUT, - timeout=timeout, - check=True, - env=tesseract_env, - ) + p = run(args_tesseract, stdout=PIPE, stderr=STDOUT, timeout=timeout, check=True) stdout = p.stdout except TimeoutExpired: return OrientationConfidence(angle=0, confidence=0.0) @@ -257,7 +240,6 @@ def generate_hocr( pagesegmode: int, user_words, user_patterns, - tesseract_env, ): prefix = output_hocr.with_suffix('') @@ -276,14 +258,7 @@ def generate_hocr( # to the number of order parameters here args_tesseract.extend([input_file, prefix, 'hocr', 'txt'] + tessconfig) try: - p = run( - args_tesseract, - stdout=PIPE, - stderr=STDOUT, - timeout=timeout, - check=True, - env=tesseract_env, - ) + p = run(args_tesseract, stdout=PIPE, stderr=STDOUT, timeout=timeout, check=True) stdout = p.stdout except TimeoutExpired: # Generate a HOCR file with no recognized text if tesseract times out @@ -325,7 +300,6 @@ def generate_pdf( pagesegmode: int, user_words, user_patterns, - tesseract_env, ): """Use Tesseract to render a PDF. @@ -358,14 +332,7 @@ def generate_pdf( args_tesseract.extend([input_file, prefix, 'pdf', 'txt'] + tessconfig) try: - p = run( - args_tesseract, - stdout=PIPE, - stderr=STDOUT, - timeout=timeout, - check=True, - env=tesseract_env, - ) + p = run(args_tesseract, stdout=PIPE, stderr=STDOUT, timeout=timeout, check=True) stdout = p.stdout if os.path.exists(prefix + '.txt'): shutil.move(prefix + '.txt', output_text) diff --git a/tests/conftest.py b/tests/conftest.py index b520d73b..34bbba86 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -133,8 +133,6 @@ def run_ocrmypdf_api(input_file, output_file, *args): str(arg) for arg in args if arg is not None ] _parser, options, plugin_manager = get_parser_options_plugins(args=args) - if options.tesseract_env: - assert all(isinstance(v, (str, bytes)) for v in options.tesseract_env.values()) api.check_options(options, plugin_manager) return api.run_pipeline(options, plugin_manager=None, api=False) diff --git a/tests/test_tesseract.py b/tests/test_tesseract.py index 99222d5a..a8a28dc6 100644 --- a/tests/test_tesseract.py +++ b/tests/test_tesseract.py @@ -70,13 +70,11 @@ def test_content_preservation(resources, outpdf): assert len(page.images) > 1, "masks were rasterized" -def test_no_languages(tmp_path): - env = os.environ.copy() +def test_no_languages(tmp_path, monkeypatch): (tmp_path / 'tessdata').mkdir() - env['TESSDATA_PREFIX'] = fspath(tmp_path) - + monkeypatch.setenv('TESSDATA_PREFIX', fspath(tmp_path)) with pytest.raises(MissingDependencyError): - tesseract.get_languages(tesseract_env=env) + tesseract.get_languages() def test_image_too_large_hocr(monkeypatch, resources, outdir): @@ -95,7 +93,6 @@ def test_image_too_large_hocr(monkeypatch, resources, outdir): pagesegmode=None, user_words=None, user_patterns=None, - tesseract_env=None, ) assert "name='ocr-capabilities'" in Path(outdir / 'out.hocr').read_text() @@ -116,7 +113,6 @@ def test_image_too_large_pdf(monkeypatch, resources, outdir): pagesegmode=None, user_words=None, user_patterns=None, - tesseract_env=None, ) assert Path(outdir / 'txt.txt').read_text() == '[skipped page]' if os.name != 'nt': # different semantics