Compare commits

...
12 Commits
Author SHA1 Message Date
James R. Barlow 79382a6039 Docker: Change base image to debian
Debian has latest qpdf.
2022-04-04 00:40:03 -07:00
James R. Barlow 7788d94c4a v13.4.2 release notes, take 2 2022-04-03 23:58:37 -07:00
James R. Barlow 33bfba8449 ghostscript: match actual reported version 2022-04-03 23:35:30 -07:00
James R. Barlow 1d0584c644 Add advisory note to release notes 2022-04-03 23:04:55 -07:00
James Barlow 84b9d4d021 Speculation: Ghostscript 9.56 new PDF interpreter breaks things 2022-04-03 21:14:19 -07:00
James Barlow 41efd3bf0f Fix Python "3.10" 2022-04-03 21:13:59 -07:00
James Barlow 776ada6713 Upgrade pre-commit and associated tools; various lints 2022-04-03 20:53:01 -07:00
James Barlow f3593c915d ci: test Python 3.10 2022-04-03 19:06:50 -07:00
James Barlow dfe31a2f6d Add lock to certain "with patch" cases
Switch to --use-threads seems to have broken tests that assumed they could
monkeypatch things. Although that's odd, since while we can have multiple
worker threads, we should never have
parallel tests in the same process.
2022-04-03 17:22:04 -07:00
James Barlow 0c43963d69 Fix pytest deprecation warnings 2022-04-03 13:30:58 -07:00
James Barlow f29fe7f23e Fix Pillow deprecation warnings 2022-04-03 13:30:50 -07:00
James R. Barlow 04996caac3 pdfminer 20220319 2022-03-22 22:36:06 -07:00
20 changed files with 112 additions and 60 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
# OCRmyPDF # OCRmyPDF
# #
FROM ubuntu:21.04 as base FROM debian:bookworm-slim as base
ENV LANG=C.UTF-8 ENV LANG=C.UTF-8
ENV TZ=UTC ENV TZ=UTC
+9 -7
View File
@@ -21,17 +21,19 @@ jobs:
matrix: matrix:
include: include:
- os: ubuntu-18.04 - os: ubuntu-18.04
python: 3.7 python: "3.7"
- os: ubuntu-20.04 - os: ubuntu-20.04
python: 3.8 python: "3.8"
- os: ubuntu-20.04 - os: ubuntu-20.04
python: 3.9 python: "3.9"
- os: ubuntu-20.04
python: "3.10"
- os: ubuntu-latest - os: ubuntu-latest
python: 3.9 python: "3.9"
- os: ubuntu-latest - os: ubuntu-latest
python: "pypy-3.7" python: "pypy-3.7"
- os: ubuntu-latest - os: ubuntu-latest
python: 3.9 python: "3.9"
tesseract5: true tesseract5: true
env: env:
@@ -120,7 +122,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [macos-latest] os: [macos-latest]
python: ["3.9"] python: ["3.9", "3.10"]
env: env:
OS: ${{ matrix.os }} OS: ${{ matrix.os }}
@@ -175,7 +177,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [windows-latest] os: [windows-latest]
python: ["3.9"] python: ["3.9", "3.10"]
env: env:
OS: ${{ matrix.os }} OS: ${{ matrix.os }}
+6 -6
View File
@@ -1,6 +1,6 @@
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1 rev: v4.1.0
hooks: hooks:
- id: check-case-conflict - id: check-case-conflict
- id: check-merge-conflict - id: check-merge-conflict
@@ -8,26 +8,26 @@ repos:
- id: check-yaml - id: check-yaml
- id: debug-statements - id: debug-statements
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: 5.9.3 rev: 5.10.1
hooks: hooks:
- id: isort - id: isort
args: ["--profile", "black"] args: ["--profile", "black"]
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 21.9b0 rev: 22.3.0
hooks: hooks:
- id: black - id: black
language_version: python language_version: python
- repo: https://github.com/asottile/setup-cfg-fmt - repo: https://github.com/asottile/setup-cfg-fmt
rev: v1.19.0 rev: v1.20.1
hooks: hooks:
- id: setup-cfg-fmt - id: setup-cfg-fmt
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v2.29.0 rev: v2.31.1
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: ["--py37-plus"] args: ["--py37-plus"]
- repo: https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.910-1 rev: v0.942
hooks: hooks:
- id: mypy - id: mypy
additional_dependencies: additional_dependencies:
+28 -4
View File
@@ -10,7 +10,31 @@ that is, output messages may be improved at any release level, so parsing them
may be unreliable. Use the API to depend on precise behavior. may be unreliable. Use the API to depend on precise behavior.
The public API may be useful in scripts that launch OCRmyPDF processes or that The public API may be useful in scripts that launch OCRmyPDF processes or that
wish to use some of its features for working with PDFs.. wish to use some of its features for working with PDFs.
The most recent release of OCRmyPDF is |OCRmyPDF PyPI|. Any newer versions
referred to in these notes may exist the main branch but have not been
tagged yet.
.. |OCRmyPDF PyPI| image:: https://img.shields.io/pypi/v/ocrmypdf.svg
v13.4.2
=======
- Worked around a
`major regression in Ghostscript 9.56.0 <https://bugs.ghostscript.com/show_bug.cgi?id=705187>`__
where **all OCR text is stripped out of the PDF**. It simply removes all text,
even generated by software other than OCRmyPDF. Fortunately, we can ask
Ghostscript 9.56.0 to use its old behavior that worked correctly for our purposes.
Users must avoid the combination (Ghostscript 9.56.0, ocrmypdf <13.4.2) since
older versions of OCRmyPDF have no way of detecting that this particular
version of Ghostscript removes all OCR text.
- Marked pdfminer 20220319 as supported.
- Fixed some deprecation warnings from recent versions of Pillow and pytest.
- Test suite now covers Python 3.10 (Python 3.10 worked fine before, but was not
being tested).
- Docker image now uses debian:bookworm-slim as the base image to fix the Docker
image build.
v13.4.1 v13.4.1
======= =======
@@ -24,9 +48,9 @@ v13.4.0
- Fixed test failures when using pikepdf 5.0.0. - Fixed test failures when using pikepdf 5.0.0.
- Various improvements to the optimizer. In particular, we now recognize PDF images - Various improvements to the optimizer. In particular, we now recognize PDF images
that are encoded with both flate and DCT (JPEG), and also produce PDF with images that are encoded with both deflate (PNG) and DCT (JPEG), and also produce PDF
compressed with flate and DCT, since this often yields file size improvements with images compressed with deflate and DCT, since this often yields file size
compared to plain DCT. improvements compared to plain DCT.
v13.3.0 v13.3.0
======= =======
+1 -1
View File
@@ -59,7 +59,7 @@ def do_ocrmypdf(file):
return Response("--sidecar not supported", 501, mimetype='text/plain') return Response("--sidecar not supported", 501, mimetype='text/plain')
ocrmypdf_args = ["ocrmypdf", *cmd_args, up_file, down_file] ocrmypdf_args = ["ocrmypdf", *cmd_args, up_file, down_file]
proc = run(ocrmypdf_args, stdout=PIPE, stderr=PIPE, encoding="utf-8") proc = run(ocrmypdf_args, capture_output=True, encoding="utf-8")
if proc.returncode != 0: if proc.returncode != 0:
stderr = proc.stderr stderr = proc.stderr
return Response(stderr, 400, mimetype='text/plain') return Response(stderr, 400, mimetype='text/plain')
+2 -2
View File
@@ -49,8 +49,8 @@ install_requires =
coloredlogs>=14.0 # strictly optional coloredlogs>=14.0 # strictly optional
img2pdf>=0.3.0,<0.5 # pure Python img2pdf>=0.3.0,<0.5 # pure Python
packaging>=20 packaging>=20
pdfminer.six!=20200720,>=20191110,<=20211012 pdfminer.six!=20200720,>=20191110,<=20220319
pikepdf>=4.0.0,!=5.0.0 pikepdf!=5.0.0,>=4.0.0
pluggy>=0.13.0,<2 pluggy>=0.13.0,<2
reportlab>=3.5.66 reportlab>=3.5.66
tqdm>=4 tqdm>=4
+16 -5
View File
@@ -24,6 +24,13 @@ from ocrmypdf.exceptions import MissingDependencyError, SubprocessOutputError
from ocrmypdf.helpers import Resolution from ocrmypdf.helpers import Resolution
from ocrmypdf.subprocess import get_version, run, run_polling_stderr from ocrmypdf.subprocess import get_version, run, run_polling_stderr
# Remove this workaround when we require Pillow >= 10
try:
Transpose = Image.Transpose # type: ignore
except AttributeError:
# Pillow 9 shim
Transpose = Image # type: ignore
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
missing_gs_error = """ missing_gs_error = """
@@ -132,11 +139,11 @@ def rasterize_pdf(
# rotation is a clockwise angle and Image.ROTATE_* is # rotation is a clockwise angle and Image.ROTATE_* is
# counterclockwise so this cancels out the rotation # counterclockwise so this cancels out the rotation
if rotation == 90: if rotation == 90:
im = im.transpose(Image.ROTATE_90) im = im.transpose(Transpose.ROTATE_90)
elif rotation == 180: elif rotation == 180:
im = im.transpose(Image.ROTATE_180) im = im.transpose(Transpose.ROTATE_180)
elif rotation == 270: elif rotation == 270:
im = im.transpose(Image.ROTATE_270) im = im.transpose(Transpose.ROTATE_270)
if rotation % 180 == 90: if rotation % 180 == 90:
page_dpi = page_dpi.flip_axis() page_dpi = page_dpi.flip_axis()
im.save(fspath(output_file), dpi=page_dpi) im.save(fspath(output_file), dpi=page_dpi)
@@ -210,14 +217,18 @@ def generate_pdfa(
# Older versions of Ghostscript expect a leading slash in # Older versions of Ghostscript expect a leading slash in
# sColorConversionStrategy, newer ones should not have it. See Ghostscript # sColorConversionStrategy, newer ones should not have it. See Ghostscript
# git commit fe1c025d. # git commit fe1c025d.
strategy = ('/' + strategy) if version() < '9.19' else strategy gs_version = version()
strategy = ('/' + strategy) if gs_version < '9.19' else strategy
if version() == '9.23': if gs_version == '9.23':
# 9.23: added JPEG passthrough as a new feature, but with a bug that # 9.23: added JPEG passthrough as a new feature, but with a bug that
# incorrectly formats some images. Fixed as of 9.24. So we disable this # incorrectly formats some images. Fixed as of 9.24. So we disable this
# feature for 9.23. # feature for 9.23.
# https://bugs.ghostscript.com/show_bug.cgi?id=699216 # https://bugs.ghostscript.com/show_bug.cgi?id=699216
compression_args.append('-dPassThroughJPEGImages=false') compression_args.append('-dPassThroughJPEGImages=false')
elif gs_version == '9.56.0':
# 9.56.0 breaks our OCR...?
compression_args.append('-dNEWPDF=false')
# nb no need to specify ProcessColorModel when ColorConversionStrategy # nb no need to specify ProcessColorModel when ColorConversionStrategy
# is set; see: # is set; see:
+2 -2
View File
@@ -18,7 +18,7 @@ from decimal import Decimal
from pathlib import Path from pathlib import Path
from subprocess import PIPE, STDOUT from subprocess import PIPE, STDOUT
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
from typing import List, Optional, Tuple, Union from typing import Iterator, List, Optional, Tuple, Union
from PIL import Image from PIL import Image
@@ -76,7 +76,7 @@ def _convert_image(im: Image.Image) -> Tuple[Image.Image, bool, str]:
@contextmanager @contextmanager
def _setup_unpaper_io(input_file: Path) -> Tuple[Path, Path, Path]: def _setup_unpaper_io(input_file: Path) -> Iterator[Tuple[Path, Path, Path]]:
with Image.open(input_file) as im: with Image.open(input_file) as im:
if im.width * im.height >= UNPAPER_IMAGE_PIXEL_LIMIT: if im.width * im.height >= UNPAPER_IMAGE_PIXEL_LIMIT:
raise UnpaperImageTooLargeError(w=im.width, h=im.height) raise UnpaperImageTooLargeError(w=im.width, h=im.height)
+11 -2
View File
@@ -18,7 +18,7 @@ from typing import Dict, Iterable, Optional
import img2pdf import img2pdf
import pikepdf import pikepdf
from pikepdf.models.metadata import encode_pdf_date from pikepdf.models.metadata import encode_pdf_date
from PIL import Image, ImageDraw from PIL import Image, ImageColor, ImageDraw
from ocrmypdf._concurrent import Executor from ocrmypdf._concurrent import Executor
from ocrmypdf._exec import unpaper from ocrmypdf._exec import unpaper
@@ -38,6 +38,13 @@ from ocrmypdf.optimize import optimize
from ocrmypdf.pdfa import generate_pdfa_ps from ocrmypdf.pdfa import generate_pdfa_ps
from ocrmypdf.pdfinfo import Colorspace, Encoding, PdfInfo from ocrmypdf.pdfinfo import Colorspace, Encoding, PdfInfo
# Remove this workaround when we require Pillow >= 10
try:
BICUBIC = Image.Resampling.BICUBIC # type: ignore
except AttributeError:
# Pillow 9 shim
BICUBIC = Image.BICUBIC # type: ignore
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
VECTOR_PAGE_DPI = 400 VECTOR_PAGE_DPI = 400
@@ -484,7 +491,9 @@ def preprocess_deskew(input_file: Path, page_context: PageContext):
# According to Pillow docs, .rotate() will automatically use Image.NEAREST # According to Pillow docs, .rotate() will automatically use Image.NEAREST
# resampling if image is mode '1' or 'P' # resampling if image is mode '1' or 'P'
deskewed = im.rotate( deskewed = im.rotate(
deskew_angle_degrees, resample=Image.BICUBIC, fillcolor='white' deskew_angle_degrees,
resample=BICUBIC,
fillcolor=ImageColor.getcolor('white', mode=im.mode),
) )
deskewed.save(output_file, dpi=dpi) deskewed.save(output_file, dpi=dpi)
+1 -1
View File
@@ -41,7 +41,7 @@ log = logging.getLogger(__name__)
def check_platform(): def check_platform():
if os.name == 'nt' and sys.maxsize <= 2 ** 32: # pragma: no cover if os.name == 'nt' and sys.maxsize <= 2**32: # pragma: no cover
# 32-bit interpreter on Windows # 32-bit interpreter on Windows
log.error( log.error(
"You are running OCRmyPDF in a 32-bit (x86) Python interpreter." "You are running OCRmyPDF in a 32-bit (x86) Python interpreter."
+4 -4
View File
@@ -647,8 +647,8 @@ def _pdf_pageinfo_concurrent(
max_workers, max_workers,
check_pages, check_pages,
detailed_analysis=False, detailed_analysis=False,
) -> List[Optional['PageInfo']]: ) -> Sequence[Optional['PageInfo']]:
pages = [None] * len(pdf.pages) pages: Sequence[Optional['PageInfo']] = [None] * len(pdf.pages)
def update_pageinfo(result, pbar): def update_pageinfo(result, pbar):
page = result page = result
@@ -925,11 +925,11 @@ class PdfInfo:
@property @property
def min_version(self) -> str: def min_version(self) -> str:
# The minimum PDF is the maximum version that any particular page needs # The minimum PDF is the maximum version that any particular page needs
return max(page.min_version for page in self.pages) return max(page.min_version for page in self.pages if page)
@property @property
def has_userunit(self) -> bool: def has_userunit(self) -> bool:
return any(page.userunit != 1.0 for page in self.pages) return any(page.userunit != 1.0 for page in self.pages if page)
@property @property
def has_acroform(self) -> bool: def has_acroform(self) -> bool:
+4
View File
@@ -4,6 +4,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this # License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# type: ignore
# Non-Windows mypy now breaks when trying to typecheck winreg
import logging import logging
import os import os
import shutil import shutil
@@ -17,6 +20,7 @@ try:
except ModuleNotFoundError as e: except ModuleNotFoundError as e:
raise ModuleNotFoundError("This module is for Windows only") from e raise ModuleNotFoundError("This module is for Windows only") from e
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
T = TypeVar('T') T = TypeVar('T')
+1 -2
View File
@@ -134,8 +134,7 @@ def run_ocrmypdf(
p = run( p = run(
p_args, p_args,
stdout=PIPE, capture_output=True,
stderr=PIPE,
text=text, text=text,
check=False, check=False,
) )
+8 -5
View File
@@ -54,6 +54,7 @@ from functools import partial
from pathlib import Path from pathlib import Path
from subprocess import PIPE, CalledProcessError, CompletedProcess from subprocess import PIPE, CalledProcessError, CompletedProcess
from unittest.mock import patch from unittest.mock import patch
import threading
from ocrmypdf import hookimpl from ocrmypdf import hookimpl
from ocrmypdf.builtin_plugins.tesseract_ocr import TesseractOcrEngine from ocrmypdf.builtin_plugins.tesseract_ocr import TesseractOcrEngine
@@ -176,26 +177,28 @@ def cached_run(options, run_args, **run_kwargs):
class CacheOcrEngine(TesseractOcrEngine): class CacheOcrEngine(TesseractOcrEngine):
lock = threading.Lock()
@staticmethod @staticmethod
def get_orientation(input_file, options): def get_orientation(input_file, options):
with patch('ocrmypdf._exec.tesseract.run', new=partial(cached_run, options)): with CacheOcrEngine.lock, patch('ocrmypdf._exec.tesseract.run', new=partial(cached_run, options)):
return TesseractOcrEngine.get_orientation(input_file, options) return TesseractOcrEngine.get_orientation(input_file, options)
@staticmethod @staticmethod
def get_deskew(input_file, options) -> float: def get_deskew(input_file, options) -> float:
with patch('ocrmypdf._exec.tesseract.run', new=partial(cached_run, options)): with CacheOcrEngine.lock, patch('ocrmypdf._exec.tesseract.run', new=partial(cached_run, options)):
return TesseractOcrEngine.get_deskew(input_file, options) return TesseractOcrEngine.get_deskew(input_file, options)
@staticmethod @staticmethod
def generate_hocr(input_file, output_hocr, output_text, options): def generate_hocr(input_file, output_hocr, output_text, options):
with patch('ocrmypdf._exec.tesseract.run', new=partial(cached_run, options)): with CacheOcrEngine.lock, patch('ocrmypdf._exec.tesseract.run', new=partial(cached_run, options)):
TesseractOcrEngine.generate_hocr( TesseractOcrEngine.generate_hocr(
input_file, output_hocr, output_text, options input_file, output_hocr, output_text, options
) )
@staticmethod @staticmethod
def generate_pdf(input_file, output_pdf, output_text, options): def generate_pdf(input_file, output_pdf, output_text, options):
with patch('ocrmypdf._exec.tesseract.run', new=partial(cached_run, options)): with CacheOcrEngine.lock, patch('ocrmypdf._exec.tesseract.run', new=partial(cached_run, options)):
TesseractOcrEngine.generate_pdf( TesseractOcrEngine.generate_pdf(
input_file, output_pdf, output_text, options input_file, output_pdf, output_text, options
) )
+2 -4
View File
@@ -24,8 +24,7 @@ def test_fish():
['fish', '-n', 'misc/completion/ocrmypdf.fish'], ['fish', '-n', 'misc/completion/ocrmypdf.fish'],
check=True, check=True,
encoding='utf-8', encoding='utf-8',
stdout=PIPE, capture_output=True,
stderr=PIPE,
) )
assert proc.stderr == '', proc.stderr assert proc.stderr == '', proc.stderr
except FileNotFoundError: except FileNotFoundError:
@@ -41,8 +40,7 @@ def test_bash():
['bash', '-n', 'misc/completion/ocrmypdf.bash'], ['bash', '-n', 'misc/completion/ocrmypdf.bash'],
check=True, check=True,
encoding='utf-8', encoding='utf-8',
stdout=PIPE, capture_output=True,
stderr=PIPE,
) )
assert proc.stderr == '', proc.stderr assert proc.stderr == '', proc.stderr
except FileNotFoundError: except FileNotFoundError:
+2 -4
View File
@@ -630,8 +630,7 @@ def test_compression_preserved(ocrmypdf_exec, resources, image, outpdf):
] ]
p = run( p = run(
p_args, p_args,
stdout=PIPE, capture_output=True,
stderr=PIPE,
stdin=input_stream, stdin=input_stream,
text=True, text=True,
check=False, check=False,
@@ -691,8 +690,7 @@ def test_compression_changed(ocrmypdf_exec, resources, image, compression, outpd
] ]
p = run( p = run(
p_args, p_args,
stdout=PIPE, capture_output=True,
stderr=PIPE,
stdin=input_stream, stdin=input_stream,
text=True, text=True,
check=False, check=False,
+1 -1
View File
@@ -188,7 +188,7 @@ def test_xml_metadata_preserved(test_file, output_type, resources, outpdf):
try: try:
from libxmp.utils import file_to_dict # pylint: disable=import-outside-toplevel from libxmp.utils import file_to_dict # pylint: disable=import-outside-toplevel
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
pytest.skip("libxmp not available or libexempi3 not installed") pytest.skip(reason="libxmp not available or libexempi3 not installed")
before = file_to_dict(str(input_file)) before = file_to_dict(str(input_file))
+3 -5
View File
@@ -173,17 +173,15 @@ def test_stack_abuse():
p = pikepdf.Pdf.new() p = pikepdf.Pdf.new()
stream = pikepdf.Stream(p, b'q ' * 35) stream = pikepdf.Stream(p, b'q ' * 35)
with pytest.warns(None) as record: with pytest.warns(UserWarning, match="overflowed"):
pdfinfo.info._interpret_contents(stream) pdfinfo.info._interpret_contents(stream)
assert 'overflowed' in str(record[0].message)
stream = pikepdf.Stream(p, b'q Q Q Q Q') stream = pikepdf.Stream(p, b'q Q Q Q Q')
with pytest.warns(None) as record: with pytest.warns(UserWarning, match="underflowed") as record:
pdfinfo.info._interpret_contents(stream) pdfinfo.info._interpret_contents(stream)
assert 'underflowed' in str(record[0].message)
stream = pikepdf.Stream(p, b'q ' * 135) stream = pikepdf.Stream(p, b'q ' * 135)
with pytest.warns(None): with pytest.warns():
with pytest.raises(RuntimeError): with pytest.raises(RuntimeError):
pdfinfo.info._interpret_contents(stream) pdfinfo.info._interpret_contents(stream)
+7 -1
View File
@@ -25,6 +25,12 @@ from .conftest import check_ocrmypdf, run_ocrmypdf
# pylintx: disable=unused-variable # pylintx: disable=unused-variable
# Remove this workaround when we require Pillow >= 10
try:
Transpose = Image.Transpose # type: ignore
except AttributeError:
# Pillow 9 shim
Transpose = Image # type: ignore
RENDERERS = ['hocr', 'sandwich'] RENDERERS = ['hocr', 'sandwich']
@@ -222,7 +228,7 @@ def test_rotate_page_level(image_angle, page_angle, resources, outdir):
with Image.open(fspath(resources / 'typewriter.png')) as im: with Image.open(fspath(resources / 'typewriter.png')) as im:
if image_angle != 0: if image_angle != 0:
ccw_angle = -image_angle % 360 ccw_angle = -image_angle % 360
im = im.transpose(getattr(Image, f'ROTATE_{ccw_angle}')) im = im.transpose(getattr(Transpose, f'ROTATE_{ccw_angle}'))
im.save(memimg, format='PNG') im.save(memimg, format='PNG')
memimg.seek(0) memimg.seek(0)
mempdf = BytesIO() mempdf = BytesIO()
+3 -3
View File
@@ -30,12 +30,12 @@ def test_stdin(ocrmypdf_exec, resources, outpdf):
'--plugin', '--plugin',
'tests/plugins/tesseract_noop.py', 'tests/plugins/tesseract_noop.py',
] ]
run(p_args, stdout=PIPE, stderr=PIPE, stdin=input_stream, check=True) run(p_args, capture_output=True, stdin=input_stream, check=True)
def test_stdout(ocrmypdf_exec, resources, outpdf): def test_stdout(ocrmypdf_exec, resources, outpdf):
if 'COV_CORE_DATAFILE' in os.environ: if 'COV_CORE_DATAFILE' in os.environ:
pytest.skip(msg="Coverage uses stdout") pytest.skip(reason="Coverage uses stdout")
input_file = str(resources / 'francais.pdf') input_file = str(resources / 'francais.pdf')
output_file = str(outpdf) output_file = str(outpdf)
@@ -72,7 +72,7 @@ def test_bad_locale(monkeypatch):
) )
def test_dev_null(resources): def test_dev_null(resources):
if 'COV_CORE_DATAFILE' in os.environ: if 'COV_CORE_DATAFILE' in os.environ:
pytest.skip(msg="Coverage uses stdout") pytest.skip(reason="Coverage uses stdout")
p = run_ocrmypdf( p = run_ocrmypdf(
resources / 'trivial.pdf', resources / 'trivial.pdf',