diff --git a/misc/batch.py b/misc/batch.py index fcd0e5cf..0b3793b2 100644 --- a/misc/batch.py +++ b/misc/batch.py @@ -52,7 +52,7 @@ logging.basicConfig( ocrmypdf.configure_logging(ocrmypdf.Verbosity.default) -for dir_name, subdirs, file_list in os.walk(start_dir): +for dir_name, _subdirs, file_list in os.walk(start_dir): logging.info(dir_name + '\n') os.chdir(dir_name) for filename in file_list: diff --git a/misc/synology.py b/misc/synology.py index 6e294ce1..7e243229 100644 --- a/misc/synology.py +++ b/misc/synology.py @@ -46,7 +46,7 @@ if len(sys.argv) > 1: else: start_dir = '.' -for dir_name, subdirs, file_list in os.walk(start_dir): +for dir_name, _subdirs, file_list in os.walk(start_dir): logging.info(dir_name) os.chdir(dir_name) for filename in file_list: diff --git a/setup.cfg b/setup.cfg index 42e362d5..a23304f7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -107,3 +107,9 @@ test = pytest [check-manifest] ignore = .github + +[flake8] +ignore = D203,F401,W503,E501,E203,F841 +exclude = .git,__pycache__,docs/conf.py,build,dist,.venv,.venvpp,.eggs,tmp,src/ocrmypdf/lib/ +max-complexity = 10 +max-line-length = 100 \ No newline at end of file diff --git a/src/ocrmypdf/_exec/tesseract.py b/src/ocrmypdf/_exec/tesseract.py index 33ead41e..79374670 100644 --- a/src/ocrmypdf/_exec/tesseract.py +++ b/src/ocrmypdf/_exec/tesseract.py @@ -20,7 +20,6 @@ from typing import List, Optional from PIL import Image -from ocrmypdf.api import StrPath from ocrmypdf.exceptions import ( MissingDependencyError, SubprocessOutputError, diff --git a/src/ocrmypdf/_exec/unpaper.py b/src/ocrmypdf/_exec/unpaper.py index 3c3ae72c..aec365c2 100644 --- a/src/ocrmypdf/_exec/unpaper.py +++ b/src/ocrmypdf/_exec/unpaper.py @@ -96,12 +96,12 @@ def run( try: with Image.open(output_pnm) as imout: imout.save(output_file, dpi=(dpi, dpi)) - except (FileNotFoundError, OSError): + except OSError as e: raise SubprocessOutputError( "unpaper: failed to produce the expected output file. " + " Called with: " + str(args_unpaper) - ) from None + ) from e def validate_custom_args(args: str) -> List[str]: diff --git a/src/ocrmypdf/_sync.py b/src/ocrmypdf/_sync.py index 303b0cf6..b6611595 100644 --- a/src/ocrmypdf/_sync.py +++ b/src/ocrmypdf/_sync.py @@ -399,7 +399,7 @@ def run_pipeline(options, *, plugin_manager, api=False): return ExitCode.invalid_output_pdf report_output_file_size(options, start_input_file, options.output_file) - except (KeyboardInterrupt if not api else NeverRaise) as e: + except (KeyboardInterrupt if not api else NeverRaise): if options.verbose >= 1: log.exception("KeyboardInterrupt") else: @@ -413,7 +413,7 @@ def run_pipeline(options, *, plugin_manager, api=False): else: log.error(type(e).__name__) return e.exit_code - except (Exception if not api else NeverRaise) as e: # pylint: disable=broad-except + except (Exception if not api else NeverRaise): # pylint: disable=broad-except log.exception("An exception occurred while executing the pipeline") return ExitCode.other_error finally: diff --git a/src/ocrmypdf/_validation.py b/src/ocrmypdf/_validation.py index f5ca30e6..47d97680 100644 --- a/src/ocrmypdf/_validation.py +++ b/src/ocrmypdf/_validation.py @@ -26,12 +26,7 @@ from ocrmypdf.exceptions import ( MissingDependencyError, OutputFileAccessError, ) -from ocrmypdf.helpers import ( - is_file_writable, - is_iterable_notstr, - monotonic, - safe_symlink, -) +from ocrmypdf.helpers import is_file_writable, monotonic, safe_symlink from ocrmypdf.hocrtransform import HOCR_OK_LANGS from ocrmypdf.subprocess import check_external_program @@ -68,7 +63,7 @@ def check_options_languages(options, ocr_engine_languages): missing_languages = options.languages - ocr_engine_languages if missing_languages: msg = ( - f"OCR engine does not have language data for the following " + "OCR engine does not have language data for the following " "requested languages: \n" ) msg += '\n'.join(lang for lang in missing_languages) diff --git a/src/ocrmypdf/api.py b/src/ocrmypdf/api.py index de3561e4..8f731fa3 100644 --- a/src/ocrmypdf/api.py +++ b/src/ocrmypdf/api.py @@ -15,10 +15,7 @@ from pathlib import Path from typing import AnyStr, BinaryIO, Iterable, Optional, Union from warnings import warn -from ocrmypdf._logging import ( # pylint: disable=unused-import - PageNumberFilter, - TqdmConsole, -) +from ocrmypdf._logging import PageNumberFilter, TqdmConsole from ocrmypdf._plugin_manager import get_plugin_manager from ocrmypdf._sync import run_pipeline from ocrmypdf._validation import check_options @@ -338,3 +335,17 @@ def ocr( # pylint: disable=unused-argument options = create_options(**create_options_kwargs) check_options(options, plugin_manager) return run_pipeline(options=options, plugin_manager=plugin_manager, api=True) + + +__all__ = [ + 'PageNumberFilter', + 'TqdmConsole', + 'Verbosity', + 'check_options', + 'configure_logging', + 'create_options', + 'get_parser', + 'get_plugin_manager', + 'ocr', + 'run_pipeline', +] diff --git a/src/ocrmypdf/builtin_plugins/concurrency.py b/src/ocrmypdf/builtin_plugins/concurrency.py index 1fe34d8c..74e6b504 100644 --- a/src/ocrmypdf/builtin_plugins/concurrency.py +++ b/src/ocrmypdf/builtin_plugins/concurrency.py @@ -21,7 +21,7 @@ import sys import threading from contextlib import suppress from multiprocessing.pool import Pool, ThreadPool -from typing import Callable, Iterable, Optional, Tuple, Type, Union +from typing import Callable, Iterable, Type, Union from tqdm import tqdm diff --git a/src/ocrmypdf/builtin_plugins/tesseract_ocr.py b/src/ocrmypdf/builtin_plugins/tesseract_ocr.py index a6973b01..f4f45639 100644 --- a/src/ocrmypdf/builtin_plugins/tesseract_ocr.py +++ b/src/ocrmypdf/builtin_plugins/tesseract_ocr.py @@ -11,7 +11,6 @@ import os from ocrmypdf import hookimpl from ocrmypdf._exec import tesseract from ocrmypdf.cli import numeric -from ocrmypdf.exceptions import MissingDependencyError from ocrmypdf.helpers import clamp from ocrmypdf.pluginspec import OcrEngine from ocrmypdf.subprocess import check_external_program diff --git a/src/ocrmypdf/helpers.py b/src/ocrmypdf/helpers.py index 3f012ef1..7ff2ea71 100644 --- a/src/ocrmypdf/helpers.py +++ b/src/ocrmypdf/helpers.py @@ -226,7 +226,7 @@ def check_pdf(input_file: Path) -> bool: except ( # Workaround for a problematic pikepdf version # pragma: no cover - getattr(pikepdf, 'ForeignObjectError') + pikepdf.ForeignObjectError if pikepdf.__version__ == '2.1.0' else NeverRaise ): diff --git a/src/ocrmypdf/optimize.py b/src/ocrmypdf/optimize.py index bec39f6e..55a8841a 100644 --- a/src/ocrmypdf/optimize.py +++ b/src/ocrmypdf/optimize.py @@ -533,12 +533,15 @@ def transcode_pngs( _transcode_png(pike, filename, xref) +DEFAULT_EXECUTOR = SerialExecutor() + + def optimize( input_file: Path, output_file: Path, context, save_settings, - executor: Executor = SerialExecutor(), + executor: Executor = DEFAULT_EXECUTOR, ) -> None: options = context.options if options.optimize == 0: diff --git a/src/ocrmypdf/pdfinfo/info.py b/src/ocrmypdf/pdfinfo/info.py index c977ce73..b656e107 100644 --- a/src/ocrmypdf/pdfinfo/info.py +++ b/src/ocrmypdf/pdfinfo/info.py @@ -9,7 +9,7 @@ import atexit import logging import re -from collections import defaultdict, namedtuple +from collections import defaultdict from contextlib import ExitStack from decimal import Decimal from enum import Enum @@ -449,7 +449,7 @@ def _image_xobjects(container) -> Iterator[Tuple[Object, str]]: xobjs = resources['/XObject'].as_dict() for xobj in xobjs: candidate: Object = xobjs[xobj] - if not '/Subtype' in candidate: + if '/Subtype' not in candidate: continue if candidate['/Subtype'] == '/Image': pdfimage = candidate @@ -877,6 +877,9 @@ class PageInfo: ) +DEFAULT_EXECUTOR = SerialExecutor() + + class PdfInfo: """Get summary information about a PDF""" @@ -888,7 +891,7 @@ class PdfInfo: progbar: bool = False, max_workers: int = None, check_pages=None, - executor: Executor = SerialExecutor(), + executor: Executor = DEFAULT_EXECUTOR, ): self._infile = infile if check_pages is None: diff --git a/src/ocrmypdf/subprocess/__init__.py b/src/ocrmypdf/subprocess/__init__.py index 99f052c6..28604648 100644 --- a/src/ocrmypdf/subprocess/__init__.py +++ b/src/ocrmypdf/subprocess/__init__.py @@ -15,7 +15,6 @@ from collections.abc import Mapping from contextlib import suppress from distutils.version import LooseVersion, Version from functools import lru_cache -from pathlib import Path from subprocess import PIPE, STDOUT, CalledProcessError, CompletedProcess, Popen from subprocess import run as subprocess_run from typing import Callable, Optional, Type, Union diff --git a/src/ocrmypdf/subprocess/_windows.py b/src/ocrmypdf/subprocess/_windows.py index aec082b7..d1cc31e0 100644 --- a/src/ocrmypdf/subprocess/_windows.py +++ b/src/ocrmypdf/subprocess/_windows.py @@ -9,9 +9,9 @@ import os import shutil import sys from distutils.version import LooseVersion -from itertools import chain, filterfalse +from itertools import chain from pathlib import Path -from typing import Any, Callable, Iterator, Optional, Tuple, TypeVar, cast +from typing import Any, Callable, Iterable, Iterator, Set, Tuple, TypeVar try: import winreg @@ -137,14 +137,12 @@ def fix_windows_args(program, args, env): return args -def unique_everseen(iterable, key=None): - "List unique elements, preserving order. Remember all elements ever seen." +def unique_everseen(iterable: Iterable[T], key: Callable[[T], T]) -> Iterator[T]: + "List unique elements, preserving order." # unique_everseen('AAAABBBCCDAABBB') --> A B C D # unique_everseen('ABBCcAD', str.lower) --> A B C D - seen = set() + seen: Set[T] = set() seen_add = seen.add - if key is None: - key = lambda x: x for element in iterable: k = key(element) if k not in seen: diff --git a/tests/test_metadata.py b/tests/test_metadata.py index ebcbf031..cea73dd7 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -287,7 +287,7 @@ def test_srgb_in_unicode_path(tmp_path): def test_kodak_toc(resources, outpdf): - _output = check_ocrmypdf( + check_ocrmypdf( resources / 'kcs.pdf', outpdf, '--output-type',