diff --git a/setup.cfg b/setup.cfg
index 4325685a..73ea8553 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -14,5 +14,12 @@ testpaths = tests
filterwarnings =
ignore:.*XMLParser.*:DeprecationWarning
+[isort]
+multi_line_output=3
+include_trailing_comma=True
+force_grid_wrap=0
+use_parentheses=True
+line_length=88
+
[metadata]
license_file = LICENSE
diff --git a/src/ocrmypdf/__main__.py b/src/ocrmypdf/__main__.py
index 841fbad3..5f9b3573 100755
--- a/src/ocrmypdf/__main__.py
+++ b/src/ocrmypdf/__main__.py
@@ -16,40 +16,37 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from tempfile import mkdtemp
-from pathlib import Path
-import sys
+import argparse
+import atexit
+import logging
import os
import re
-import atexit
+import sys
import textwrap
-import logging
-import argparse
+from pathlib import Path
+from tempfile import mkdtemp
import PIL
-
-import ruffus.ruffus_exceptions as ruffus_exceptions
import ruffus.cmdline as cmdline
import ruffus.proxy_logger as proxy_logger
+import ruffus.ruffus_exceptions as ruffus_exceptions
+from . import PROGRAM_NAME, VERSION
+from . import exceptions as ocrmypdf_exceptions
from ._jobcontext import JobContext, JobContextManager, cleanup_working_files
from ._pipeline import build_pipeline
-from .pdfa import file_claims_pdfa
-from .helpers import re_symlink, is_file_writable, available_cpu_count
-from .exec import tesseract, qpdf, ghostscript
-from . import PROGRAM_NAME, VERSION
-
+from ._unicodefun import verify_python3_env
from .exceptions import (
+ BadArgsError,
ExitCode,
ExitCodeException,
- MissingDependencyError,
InputFileError,
- BadArgsError,
+ MissingDependencyError,
OutputFileAccessError,
)
-from . import exceptions as ocrmypdf_exceptions
-from ._unicodefun import verify_python3_env
-
+from .exec import ghostscript, qpdf, tesseract
+from .helpers import available_cpu_count, is_file_writable, re_symlink
+from .pdfa import file_claims_pdfa
# -------------
# External dependencies
diff --git a/src/ocrmypdf/_jobcontext.py b/src/ocrmypdf/_jobcontext.py
index 95c92119..b6afe328 100644
--- a/src/ocrmypdf/_jobcontext.py
+++ b/src/ocrmypdf/_jobcontext.py
@@ -15,10 +15,10 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
+import shutil
+import sys
from contextlib import suppress
from multiprocessing.managers import SyncManager
-import sys
-import shutil
from .pdfinfo import PdfInfo
diff --git a/src/ocrmypdf/_pipeline.py b/src/ocrmypdf/_pipeline.py
index 0e2c0eab..d731120b 100644
--- a/src/ocrmypdf/_pipeline.py
+++ b/src/ocrmypdf/_pipeline.py
@@ -15,39 +15,36 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from contextlib import suppress
-from shutil import copyfileobj, copyfile
-from pathlib import Path
-from datetime import datetime, timezone
-import sys
import os
import re
+import sys
+from contextlib import suppress
+from datetime import datetime, timezone
+from pathlib import Path
+from shutil import copyfile, copyfileobj
import img2pdf
-import pikepdf
-
from PIL import Image
-from ruffus import formatter, regex, Pipeline, suffix
+from ruffus import Pipeline, formatter, regex, suffix
+import pikepdf
from pikepdf.models.metadata import encode_pdf_date
-from .hocrtransform import HocrTransform
-from .pdfinfo import PdfInfo, Colorspace
-from .pdfa import generate_pdfa_ps
-from .helpers import re_symlink, is_iterable_notstr, page_number, flatten_groups
-from .exec import ghostscript, tesseract
-from .exceptions import (
- UnsupportedImageFormatError,
- DpiError,
- PriorOcrFoundError,
- InputFileError,
- EncryptedPdfError,
-)
-from . import leptonica
-from . import PROGRAM_NAME, VERSION
-from .optimize import optimize
+from . import PROGRAM_NAME, VERSION, leptonica
from ._weave import weave_layers
-
+from .exceptions import (
+ DpiError,
+ EncryptedPdfError,
+ InputFileError,
+ PriorOcrFoundError,
+ UnsupportedImageFormatError,
+)
+from .exec import ghostscript, tesseract
+from .helpers import flatten_groups, is_iterable_notstr, page_number, re_symlink
+from .hocrtransform import HocrTransform
+from .optimize import optimize
+from .pdfa import generate_pdfa_ps
+from .pdfinfo import Colorspace, PdfInfo
VECTOR_PAGE_DPI = 400
diff --git a/src/ocrmypdf/_unicodefun.py b/src/ocrmypdf/_unicodefun.py
index c6b0ad16..79f1b829 100644
--- a/src/ocrmypdf/_unicodefun.py
+++ b/src/ocrmypdf/_unicodefun.py
@@ -33,9 +33,9 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import codecs
import os
import sys
-import codecs
def verify_python3_env(): # pragma: no cover
diff --git a/src/ocrmypdf/_weave.py b/src/ocrmypdf/_weave.py
index e4aefca7..03f7ced9 100644
--- a/src/ocrmypdf/_weave.py
+++ b/src/ocrmypdf/_weave.py
@@ -15,13 +15,13 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from pathlib import Path
from itertools import groupby
+from pathlib import Path
import pikepdf
-from .helpers import flatten_groups, page_number
from .exec import tesseract
+from .helpers import flatten_groups, page_number
def _update_page_resources(*, page, font, font_key, procset):
diff --git a/src/ocrmypdf/exec/ghostscript.py b/src/ocrmypdf/exec/ghostscript.py
index a4c67fb3..7885393b 100644
--- a/src/ocrmypdf/exec/ghostscript.py
+++ b/src/ocrmypdf/exec/ghostscript.py
@@ -15,15 +15,17 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from tempfile import NamedTemporaryFile
-from subprocess import run, PIPE, STDOUT
-from shutil import copy
-from functools import lru_cache
import re
+from functools import lru_cache
+from os import fspath
+from shutil import copy
+from subprocess import PIPE, STDOUT, run
+from tempfile import NamedTemporaryFile
+
from PIL import Image
+
from . import get_version
from ..exceptions import SubprocessOutputError
-from os import fspath
@lru_cache(maxsize=1)
diff --git a/src/ocrmypdf/exec/jbig2enc.py b/src/ocrmypdf/exec/jbig2enc.py
index f9e23645..771e58a3 100644
--- a/src/ocrmypdf/exec/jbig2enc.py
+++ b/src/ocrmypdf/exec/jbig2enc.py
@@ -15,8 +15,8 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from subprocess import run, PIPE
from functools import lru_cache
+from subprocess import PIPE, run
from . import get_version
from ..exceptions import MissingDependencyError
diff --git a/src/ocrmypdf/exec/pngquant.py b/src/ocrmypdf/exec/pngquant.py
index cd6a3844..7ddad095 100644
--- a/src/ocrmypdf/exec/pngquant.py
+++ b/src/ocrmypdf/exec/pngquant.py
@@ -15,8 +15,8 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from subprocess import run
from functools import lru_cache
+from subprocess import run
from . import get_version
from ..exceptions import MissingDependencyError
diff --git a/src/ocrmypdf/exec/qpdf.py b/src/ocrmypdf/exec/qpdf.py
index 38d0202a..653cc4ff 100644
--- a/src/ocrmypdf/exec/qpdf.py
+++ b/src/ocrmypdf/exec/qpdf.py
@@ -15,11 +15,11 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from subprocess import CalledProcessError, STDOUT, PIPE, run
from functools import lru_cache
+from os import fspath
+from subprocess import PIPE, STDOUT, CalledProcessError, run
from . import get_version
-from os import fspath
@lru_cache(maxsize=1)
diff --git a/src/ocrmypdf/exec/tesseract.py b/src/ocrmypdf/exec/tesseract.py
index 8e184eb5..f4081a34 100644
--- a/src/ocrmypdf/exec/tesseract.py
+++ b/src/ocrmypdf/exec/tesseract.py
@@ -15,26 +15,26 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-import sys
import os
import shutil
-from functools import lru_cache
+import sys
from collections import namedtuple
-from textwrap import dedent
+from contextlib import suppress
+from functools import lru_cache
+from os import fspath
from subprocess import (
+ PIPE,
+ STDOUT,
CalledProcessError,
TimeoutExpired,
check_output,
- STDOUT,
run,
- PIPE,
)
-from contextlib import suppress
-from os import fspath
+from textwrap import dedent
+from . import get_version
from ..exceptions import MissingDependencyError, TesseractConfigError
from ..helpers import page_number
-from . import get_version
OrientationConfidence = namedtuple('OrientationConfidence', ('angle', 'confidence'))
diff --git a/src/ocrmypdf/exec/unpaper.py b/src/ocrmypdf/exec/unpaper.py
index cb8e7c24..87104f99 100644
--- a/src/ocrmypdf/exec/unpaper.py
+++ b/src/ocrmypdf/exec/unpaper.py
@@ -18,14 +18,14 @@
# unpaper documentation:
# https://github.com/Flameeyes/unpaper/blob/master/doc/basic-concepts.md
-from subprocess import CalledProcessError, STDOUT, check_output
-from tempfile import NamedTemporaryFile
-import sys
import os
+import sys
from functools import lru_cache
-from ..exceptions import MissingDependencyError
-from . import get_version
+from subprocess import STDOUT, CalledProcessError, check_output
+from tempfile import NamedTemporaryFile
+from . import get_version
+from ..exceptions import MissingDependencyError
try:
from PIL import Image
diff --git a/src/ocrmypdf/helpers.py b/src/ocrmypdf/helpers.py
index b2b30f25..3d56a1f5 100644
--- a/src/ocrmypdf/helpers.py
+++ b/src/ocrmypdf/helpers.py
@@ -15,14 +15,14 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from functools import partial, wraps
+import multiprocessing
+import os
+import sys
+import warnings
from collections.abc import Iterable
from contextlib import suppress
+from functools import partial, wraps
from pathlib import Path
-import sys
-import os
-import multiprocessing
-import warnings
def re_symlink(input_file, soft_link_name, log=None):
diff --git a/src/ocrmypdf/hocrtransform.py b/src/ocrmypdf/hocrtransform.py
index de502ebc..e7c28e54 100755
--- a/src/ocrmypdf/hocrtransform.py
+++ b/src/ocrmypdf/hocrtransform.py
@@ -28,14 +28,14 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-from reportlab.pdfgen.canvas import Canvas
-from reportlab.lib.units import inch
-from xml.etree import ElementTree
-from collections import namedtuple
-from math import atan, sin, cos
-import re
import argparse
+import re
+from collections import namedtuple
+from math import atan, cos, sin
+from xml.etree import ElementTree
+from reportlab.lib.units import inch
+from reportlab.pdfgen.canvas import Canvas
Rect = namedtuple('Rect', ['x1', 'y1', 'x2', 'y2'])
diff --git a/src/ocrmypdf/leptonica.py b/src/ocrmypdf/leptonica.py
index eb0dbc9f..99630d0c 100644
--- a/src/ocrmypdf/leptonica.py
+++ b/src/ocrmypdf/leptonica.py
@@ -20,20 +20,20 @@
#
# Python FFI wrapper for Leptonica library
-from collections.abc import Sequence
-from contextlib import suppress
-from ctypes.util import find_library
-from functools import lru_cache
-from io import BytesIO
-from tempfile import TemporaryFile
import argparse
import logging
import os
import sys
import warnings
+from collections.abc import Sequence
+from contextlib import suppress
+from ctypes.util import find_library
+from functools import lru_cache
+from io import BytesIO
+from os import fspath
+from tempfile import TemporaryFile
from .lib._leptonica import ffi
-from os import fspath
# pylint: disable=protected-access
diff --git a/src/ocrmypdf/optimize.py b/src/ocrmypdf/optimize.py
index 3c0a32ec..2b93b5cb 100644
--- a/src/ocrmypdf/optimize.py
+++ b/src/ocrmypdf/optimize.py
@@ -15,21 +15,21 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from pathlib import Path
import concurrent.futures
-from collections import defaultdict
import logging
import sys
+from collections import defaultdict
from os import fspath
+from pathlib import Path
from PIL import Image
import pikepdf
-from ._jobcontext import JobContext
from . import leptonica
+from ._jobcontext import JobContext
+from .exec import jbig2enc, pngquant
from .helpers import re_symlink
-from .exec import pngquant, jbig2enc
DEFAULT_JPEG_QUALITY = 75
DEFAULT_PNG_QUALITY = 70
diff --git a/src/ocrmypdf/pdfa.py b/src/ocrmypdf/pdfa.py
index 6350622f..00b9db18 100644
--- a/src/ocrmypdf/pdfa.py
+++ b/src/ocrmypdf/pdfa.py
@@ -31,22 +31,19 @@ Ghostscript's handling of pdfmark.
"""
+import os
from binascii import hexlify
from pathlib import Path
from string import Template
+
import pkg_resources
-import os
import pikepdf
-
-from pikepdf.models.metadata import (
- encode_pdf_date as _encode_date,
- decode_pdf_date as _decode_date,
-)
+from pikepdf.models.metadata import decode_pdf_date as _decode_date
+from pikepdf.models.metadata import encode_pdf_date as _encode_date
from .helpers import deprecated
-
ICC_PROFILE_RELPATH = 'data/sRGB.icc'
SRGB_ICC_PROFILE = pkg_resources.resource_filename('ocrmypdf', ICC_PROFILE_RELPATH)
diff --git a/src/ocrmypdf/pdfinfo/layout.py b/src/ocrmypdf/pdfinfo/layout.py
index d6c2d889..9b2b60a9 100644
--- a/src/ocrmypdf/pdfinfo/layout.py
+++ b/src/ocrmypdf/pdfinfo/layout.py
@@ -38,9 +38,9 @@ from pdfminer.pdfdocument import PDFTextExtractionNotAllowed
from pdfminer.pdffont import (
PDFCIDFont,
PDFFont,
+ PDFSimpleFont,
PDFType3Font,
PDFUnicodeNotDefined,
- PDFSimpleFont,
)
from pdfminer.pdfpage import PDFPage
from pdfminer.utils import bbox2str, fsplit, matrix2str
diff --git a/tests/conftest.py b/tests/conftest.py
index 60793aa5..b9976f50 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -15,14 +15,15 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-import sys
import os
import platform
+import sys
from pathlib import Path
-from subprocess import Popen, PIPE
+from subprocess import PIPE, Popen
+
+import pytest
pytest_plugins = ['helpers_namespace']
-import pytest
try:
from pytest_cov.embed import cleanup_on_sigterm
diff --git a/tests/spoof/gs_feature_elision.py b/tests/spoof/gs_feature_elision.py
index 91246cd8..ad65a619 100755
--- a/tests/spoof/gs_feature_elision.py
+++ b/tests/spoof/gs_feature_elision.py
@@ -21,10 +21,11 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-import sys
import os
+import sys
from subprocess import check_call
+
"""Replicate one type of Ghostscript feature elision warning during
PDF/A creation."""
diff --git a/tests/spoof/gs_pdfa_failure.py b/tests/spoof/gs_pdfa_failure.py
index 110ee34f..730fa5b5 100755
--- a/tests/spoof/gs_pdfa_failure.py
+++ b/tests/spoof/gs_pdfa_failure.py
@@ -20,8 +20,9 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-import sys
import os
+import sys
+
"""Replicate Ghostscript PDF/A conversion failure by suppressing some
arguments"""
diff --git a/tests/spoof/gs_raster_failure.py b/tests/spoof/gs_raster_failure.py
index 1658e706..b404cca8 100755
--- a/tests/spoof/gs_raster_failure.py
+++ b/tests/spoof/gs_raster_failure.py
@@ -21,8 +21,8 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-import sys
import os
+import sys
"""Replicate Ghostscript raster failure while allowing rendering"""
diff --git a/tests/spoof/gs_render_failure.py b/tests/spoof/gs_render_failure.py
index 9bafc280..3027a684 100755
--- a/tests/spoof/gs_render_failure.py
+++ b/tests/spoof/gs_render_failure.py
@@ -22,8 +22,8 @@
"""Replicate Ghostscript render failure while allowing rasterizing"""
-import sys
import os
+import sys
def real_ghostscript(argv):
diff --git a/tests/spoof/tesseract_badutf8.py b/tests/spoof/tesseract_badutf8.py
index 7981070b..e38a7cf5 100755
--- a/tests/spoof/tesseract_badutf8.py
+++ b/tests/spoof/tesseract_badutf8.py
@@ -21,10 +21,10 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import sys
+
import img2pdf
from PIL import Image
-
"""Tesseract bad utf8 spoof
In 'hocr' mode or 'pdf' mode, return error code 1 and some non-Unicode
diff --git a/tests/spoof/tesseract_big_image_error.py b/tests/spoof/tesseract_big_image_error.py
index 44e8b74a..d3ee53d8 100755
--- a/tests/spoof/tesseract_big_image_error.py
+++ b/tests/spoof/tesseract_big_image_error.py
@@ -23,7 +23,6 @@
import sys
-
VERSION_STRING = '''tesseract 4.0.0
leptonica-1.77.0
libjpeg 9c : libpng 1.6.35 : libtiff 4.0.10 : zlib 1.2.11 : libopenjp2 2.3.0
diff --git a/tests/spoof/tesseract_cache.py b/tests/spoof/tesseract_cache.py
index 4e2c7ac0..31531106 100755
--- a/tests/spoof/tesseract_cache.py
+++ b/tests/spoof/tesseract_cache.py
@@ -49,15 +49,15 @@ Assumes Tesseract 4.0.0-alpha or higher.
"""
-from pathlib import Path
-import sys
-import os
-import shutil
-import subprocess
import argparse
import json
+import os
import platform
import re
+import shutil
+import subprocess
+import sys
+from pathlib import Path
if '_OCRMYPDF_SAVE_PATH' in os.environ:
os.environ['PATH'] = os.environ['_OCRMYPDF_SAVE_PATH']
diff --git a/tests/spoof/tesseract_crash.py b/tests/spoof/tesseract_crash.py
index 399da380..0ad89909 100755
--- a/tests/spoof/tesseract_crash.py
+++ b/tests/spoof/tesseract_crash.py
@@ -20,10 +20,9 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-import sys
import os
import signal
-
+import sys
VERSION_STRING = '''tesseract 4.0.0
leptonica-1.77.0
diff --git a/tests/spoof/tesseract_noop.py b/tests/spoof/tesseract_noop.py
index c8ed485e..cdb71664 100755
--- a/tests/spoof/tesseract_noop.py
+++ b/tests/spoof/tesseract_noop.py
@@ -32,11 +32,11 @@ In orientation check mode, report the orientation is upright.
"""
import sys
+
import img2pdf
import PyPDF2 as pypdf
from PIL import Image
-
VERSION_STRING = '''tesseract 4.0.0
leptonica-1.77.0
libjpeg 9c : libpng 1.6.35 : libtiff 4.0.10 : zlib 1.2.11 : libopenjp2 2.3.0
diff --git a/tests/test_hocrtransform.py b/tests/test_hocrtransform.py
index 54bdc35c..e36fe7ee 100644
--- a/tests/test_hocrtransform.py
+++ b/tests/test_hocrtransform.py
@@ -15,12 +15,14 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from ocrmypdf import hocrtransform
-from ocrmypdf.exec.tesseract import HOCR_TEMPLATE
-from ocrmypdf.exec import qpdf
-from PIL import Image
from pathlib import Path
+
import pytest
+from PIL import Image
+
+from ocrmypdf import hocrtransform
+from ocrmypdf.exec import qpdf
+from ocrmypdf.exec.tesseract import HOCR_TEMPLATE
# pylint: disable=redefined-outer-name
diff --git a/tests/test_main.py b/tests/test_main.py
index 2372e664..59249367 100644
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -15,23 +15,23 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from subprocess import Popen, PIPE, DEVNULL
-from pathlib import Path
-from math import isclose
+import logging
import os
import shutil
import sys
-import logging
+from math import isclose
+from pathlib import Path
+from subprocess import DEVNULL, PIPE, Popen
-from PIL import Image
import PIL
import pytest
+from PIL import Image
-from ocrmypdf.pdfinfo import PdfInfo, Colorspace, Encoding
from ocrmypdf.exceptions import ExitCode, MissingDependencyError
from ocrmypdf.exec import ghostscript, qpdf, tesseract
-from ocrmypdf.pdfa import file_claims_pdfa
from ocrmypdf.leptonica import Pix
+from ocrmypdf.pdfa import file_claims_pdfa
+from ocrmypdf.pdfinfo import Colorspace, Encoding, PdfInfo
# pytest.helpers is dynamic
# pylint: disable=no-member,redefined-outer-name
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index d0e2b5d1..e12bbb21 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -16,21 +16,20 @@
# along with OCRmyPDF. If not, see .
-import pytest
-
+import datetime
from datetime import timezone
+from os import fspath
from pathlib import Path
from shutil import copyfile
-from unittest.mock import patch, MagicMock
-import datetime
-from os import fspath
+from unittest.mock import MagicMock, patch
+
+import pytest
import pikepdf
-from pikepdf.models.metadata import decode_pdf_date
-
from ocrmypdf.exceptions import ExitCode
-from ocrmypdf.pdfa import file_claims_pdfa, generate_pdfa_ps, SRGB_ICC_PROFILE
from ocrmypdf.exec import ghostscript
+from ocrmypdf.pdfa import SRGB_ICC_PROFILE, file_claims_pdfa, generate_pdfa_ps
+from pikepdf.models.metadata import decode_pdf_date
try:
import fitz
diff --git a/tests/test_multiprocessing.py b/tests/test_multiprocessing.py
index 147f906a..a25457ba 100644
--- a/tests/test_multiprocessing.py
+++ b/tests/test_multiprocessing.py
@@ -14,11 +14,12 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from ocrmypdf.pdfinfo import PdfInfo, PageInfo
-from ocrmypdf._jobcontext import JobContext, JobContextManager
from multiprocessing import Process
from multiprocessing.managers import BaseProxy
+from ocrmypdf._jobcontext import JobContext, JobContextManager
+from ocrmypdf.pdfinfo import PageInfo, PdfInfo
+
def test_jobcontext_proxy(resources):
# Prove that managers are set up correctly to share state among processes
diff --git a/tests/test_optimize.py b/tests/test_optimize.py
index d868541a..f73cd60c 100644
--- a/tests/test_optimize.py
+++ b/tests/test_optimize.py
@@ -15,20 +15,17 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from pathlib import Path
+import logging
from os import fspath
+from pathlib import Path
import pytest
-import logging
-
from PIL import Image
import pikepdf
-
from ocrmypdf import optimize as opt
-from ocrmypdf.exec.ghostscript import rasterize_pdf
from ocrmypdf.exec import jbig2enc, pngquant
-
+from ocrmypdf.exec.ghostscript import rasterize_pdf
check_ocrmypdf = pytest.helpers.check_ocrmypdf
diff --git a/tests/test_pdfinfo.py b/tests/test_pdfinfo.py
index 88f2a879..1e931904 100644
--- a/tests/test_pdfinfo.py
+++ b/tests/test_pdfinfo.py
@@ -15,20 +15,22 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from ocrmypdf import pdfinfo
-from reportlab.pdfgen.canvas import Canvas
-from PIL import Image
-from tempfile import NamedTemporaryFile
-from math import isclose
-from ocrmypdf.pdfinfo import Colorspace, Encoding
-from contextlib import suppress
import os
-import shutil
-import pytest
-import img2pdf
-import sys
-import pikepdf
import pickle
+import shutil
+import sys
+from contextlib import suppress
+from math import isclose
+from tempfile import NamedTemporaryFile
+
+import img2pdf
+import pytest
+from PIL import Image
+from reportlab.pdfgen.canvas import Canvas
+
+import pikepdf
+from ocrmypdf import pdfinfo
+from ocrmypdf.pdfinfo import Colorspace, Encoding
def test_single_page_text(outdir):
diff --git a/tests/test_rotation.py b/tests/test_rotation.py
index c210c3a9..a32ccba5 100644
--- a/tests/test_rotation.py
+++ b/tests/test_rotation.py
@@ -17,18 +17,17 @@
import logging
from io import BytesIO
-from unittest.mock import Mock
from os import fspath
+from unittest.mock import Mock
-from PIL import Image
-import pytest
import img2pdf
+import pytest
+from PIL import Image
+
import pikepdf
-
from ocrmypdf import leptonica
-from ocrmypdf.pdfinfo import PdfInfo
from ocrmypdf.exec import ghostscript, tesseract
-
+from ocrmypdf.pdfinfo import PdfInfo
# pytest.helpers is dynamic
# pylint: disable=no-member
diff --git a/tests/test_tess4.py b/tests/test_tess4.py
index d2d25a5f..afd5b1dc 100644
--- a/tests/test_tess4.py
+++ b/tests/test_tess4.py
@@ -15,10 +15,10 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from os import fspath
-import sys
import os
+import sys
from contextlib import contextmanager
+from os import fspath
from pathlib import Path
import PyPDF2 as pypdf
diff --git a/tests/test_unpaper.py b/tests/test_unpaper.py
index 6409f624..62f06656 100644
--- a/tests/test_unpaper.py
+++ b/tests/test_unpaper.py
@@ -16,7 +16,9 @@
# along with OCRmyPDF. If not, see .
from pathlib import Path
+
import pytest
+
from ocrmypdf.exceptions import ExitCode
# pytest.helpers is dynamic
diff --git a/tests/test_userunit.py b/tests/test_userunit.py
index 6120a7fa..3f220146 100644
--- a/tests/test_userunit.py
+++ b/tests/test_userunit.py
@@ -15,19 +15,20 @@
# You should have received a copy of the GNU General Public License
# along with OCRmyPDF. If not, see .
-from subprocess import Popen, PIPE, check_output, check_call, DEVNULL
+import logging
import os
import shutil
-import pytest
-from ocrmypdf.pdfinfo import PdfInfo, Colorspace, Encoding
-import PyPDF2 as pypdf
-from ocrmypdf.exceptions import ExitCode
-from ocrmypdf import leptonica
-from ocrmypdf.pdfa import file_claims_pdfa
-from ocrmypdf.exec import ghostscript
-import logging
from math import isclose
+from subprocess import DEVNULL, PIPE, Popen, check_call, check_output
+import PyPDF2 as pypdf
+import pytest
+
+from ocrmypdf import leptonica
+from ocrmypdf.exceptions import ExitCode
+from ocrmypdf.exec import ghostscript
+from ocrmypdf.pdfa import file_claims_pdfa
+from ocrmypdf.pdfinfo import Colorspace, Encoding, PdfInfo
check_ocrmypdf = pytest.helpers.check_ocrmypdf
run_ocrmypdf = pytest.helpers.run_ocrmypdf