Compare commits

...
6 Commits
Author SHA1 Message Date
James R. Barlow 42713b77d7 v12.7.0 release notes 2021-10-12 13:39:49 -07:00
James R. Barlow 690f88119d Fix test failures on pikepdf 3.2.0 + pybind11 2.8.0
When compiled without pybind11 2.8.0, pikepdf supplies a shim to implement
pikepdf._ObjectMapping.values() which has subtly different semantics
from a true dict-like objects; in particular it supports
next(objectmap.values())
where a standard dict requires
next(iter(objectmap.values()).

pybind11 2.8.0 now implements .values() properly, meaning some misuses of
protocol  in ocrmypdf fail.

If pybind11 < 2.8.0, pikepdf will
continue to offer its shim. If pybind11 >= 2.8.0, pikepdf does not add its shim.

Consequently no changes were needed in pikepdf.

Closes #843
2021-10-12 13:38:52 -07:00
James R. Barlow 78f391536b Offer hint to user to use --max-image-mpixels after decompression bob error
Closes #801
2021-10-06 00:19:11 -07:00
mara004andGitHub 7bdd1828a9 [ci skip] docs/conf.py: add intersphinx mapping to make external links work (#838) 2021-10-04 00:34:59 -07:00
mara004andGitHub a8f513eeeb [ci skip] Update api.rst (#839) 2021-10-04 00:34:39 -07:00
fedeliallalineaandGitHub af18bc0684 fixs importlib.{metadata,resource} for new python version (#840)
Signed-off-by: Marco Genasci <fedeliallalinea@gmail.com>
2021-10-03 23:30:11 -07:00
10 changed files with 47 additions and 22 deletions
+8 -8
View File
@@ -12,7 +12,7 @@ subprocess call anyway, as this provides isolation of its activities.
Example Example
======= =======
OCRmyPDF one high-level function to run its main engine from an OCRmyPDF provides one high-level function to run its main engine from an
application. The parameters are symmetric to the command line arguments application. The parameters are symmetric to the command line arguments
and largely have the same functions. and largely have the same functions.
@@ -23,7 +23,7 @@ and largely have the same functions.
if __name__ == '__main__': # To ensure correct behavior on Windows and macOS if __name__ == '__main__': # To ensure correct behavior on Windows and macOS
ocrmypdf.ocr('input.pdf', 'output.pdf', deskew=True) ocrmypdf.ocr('input.pdf', 'output.pdf', deskew=True)
With a few exceptions, all of the command line arguments are available With some exceptions, all of the command line arguments are available
and may be passed as equivalent keywords. and may be passed as equivalent keywords.
A few differences are that ``verbose`` and ``quiet`` are not available. A few differences are that ``verbose`` and ``quiet`` are not available.
@@ -41,29 +41,29 @@ execution. To do this, it will:
- manage the signal flags of its worker processes - manage the signal flags of its worker processes
- execute other subprocesses (forking and executing other programs) - execute other subprocesses (forking and executing other programs)
The Python process that calls ``ocrmypdf.ocr()`` must be sufficiently The Python process that calls :func:`ocrmypdf.ocr()` must be sufficiently
privileged to perform these actions. privileged to perform these actions.
There currently is no option to manage how jobs are scheduled other There currently is no option to manage how jobs are scheduled other
than the argument ``jobs=`` which will limit the number of worker than the argument ``jobs=`` which will limit the number of worker
processes. processes.
Creating a child process to call ``ocrmypdf.ocr()`` is suggested. That Creating a child process to call :func:`ocrmypdf.ocr()` is suggested. That
way your application will survive and remain interactive even if way your application will survive and remain interactive even if
OCRmyPDF fails for any reason. OCRmyPDF fails for any reason.
Programs that call ``ocrmypdf.ocr()`` should also install a SIGBUS signal Programs that call :func:`ocrmypdf.ocr()` should also install a SIGBUS signal
handler (except on Windows), to raise an exception if access to a memory handler (except on Windows), to raise an exception if access to a memory
mapped file fails. OCRmyPDF may use memory mapping. mapped file fails. OCRmyPDF may use memory mapping.
``ocrmypdf.ocr()`` will take a threading lock to prevent multiple runs of itself :func:`ocrmypdf.ocr()` will take a threading lock to prevent multiple runs of itself
in the same Python interpreter process. This is not thread-safe, because of how in the same Python interpreter process. This is not thread-safe, because of how
OCRmyPDF's plugins and Python's library import system work. If you need to parallelize OCRmyPDF's plugins and Python's library import system work. If you need to parallelize
OCRmyPDF, use processes. OCRmyPDF, use processes.
.. warning:: .. warning::
On Windows and macOS, the script that calls ``ocrmypdf.ocr()`` must be On Windows and macOS, the script that calls :func:`ocrmypdf.ocr()` must be
protected by an "ifmain" guard (``if __name__ == '__main__'``). If you do protected by an "ifmain" guard (``if __name__ == '__main__'``). If you do
not take at least one of these steps, process semantics will prevent not take at least one of these steps, process semantics will prevent
OCRmyPDF from working correctly. OCRmyPDF from working correctly.
@@ -96,7 +96,7 @@ Exceptions
OCRmyPDF may throw standard Python exceptions, ``ocrmypdf.exceptions.*`` OCRmyPDF may throw standard Python exceptions, ``ocrmypdf.exceptions.*``
exceptions, some exceptions related to multiprocessing, and exceptions, some exceptions related to multiprocessing, and
``KeyboardInterrupt``. The parent process should provide an exception :exc:`KeyboardInterrupt`. The parent process should provide an exception
handler. OCRmyPDF will clean up its temporary files and worker processes handler. OCRmyPDF will clean up its temporary files and worker processes
automatically when an exception occurs. automatically when an exception occurs.
+1
View File
@@ -40,6 +40,7 @@ extensions = [
] ]
# Extension settings # Extension settings
intersphinx_mapping = {'https://docs.python.org/': None}
napoleon_use_rtype = False napoleon_use_rtype = False
issues_github_path = "jbarlow83/OCRmyPDF" issues_github_path = "jbarlow83/OCRmyPDF"
+12
View File
@@ -18,6 +18,18 @@ wish to use some of its features for working with PDFs.
for Python 3.6 around that time. The change will be marked with a major for Python 3.6 around that time. The change will be marked with a major
release. release.
v12.7.0
=======
- Fixed test suite failure when using pikepdf 3.2.0 that was compiled with pybind11
2.8.0. :issue:`843`
- Improve advice to user about using ``--max-image-mpixels`` if OCR fails for this
reason.
- Minor documentation fixes. (Thanks to @mara004.)
- Don't require importlib-metadata and importlib-resources backports on versions of
Python where the standard library implementation is sufficient.
(Thanks to Marco Genasci.)
v12.6.0 v12.6.0
======= =======
+3 -3
View File
@@ -49,8 +49,8 @@ install_requires =
cffi>=1.9.1 # must be a setup and install requirement cffi>=1.9.1 # must be a setup and install requirement
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
importlib-metadata>=4 # until Python 3.8 importlib-metadata>=4;python_version<'3.8' # until Python 3.8
importlib-resources>=5 # until Python 3.9 importlib-resources>=5;python_version<'3.9' # until Python 3.9
pdfminer.six!=20200720,>=20191110,<=20201018 pdfminer.six!=20200720,>=20191110,<=20201018
pikepdf>=2.10.0 pikepdf>=2.10.0
pikepdf<3;implementation_name=="pypy" and python_version=='3.6' pikepdf<3;implementation_name=="pypy" and python_version=='3.6'
@@ -112,4 +112,4 @@ ignore =
ignore = D203,F401,W503,E501,E203,F841 ignore = D203,F401,W503,E501,E203,F841
exclude = .git,__pycache__,docs/conf.py,build,dist,.venv,.venvpp,.eggs,tmp,src/ocrmypdf/lib/ exclude = .git,__pycache__,docs/conf.py,build,dist,.venv,.venvpp,.eggs,tmp,src/ocrmypdf/lib/
max-complexity = 10 max-complexity = 10
max-line-length = 100 max-line-length = 100
+7
View File
@@ -414,6 +414,13 @@ def run_pipeline(options, *, plugin_manager, api=False):
else: else:
log.error(type(e).__name__) log.error(type(e).__name__)
return e.exit_code return e.exit_code
except (PIL.Image.DecompressionBombError if not api else NeverRaise) as e:
log.exception(
"A decompression bomb error was encountered while executing the "
"pipeline. Use the argument --max-image-mpixels to raise the maximum "
"image pixel limit."
)
return ExitCode.other_error
except (Exception if not api else NeverRaise): # pylint: disable=broad-except except (Exception if not api else NeverRaise): # pylint: disable=broad-except
log.exception("An exception occurred while executing the pipeline") log.exception("An exception occurred while executing the pipeline")
return ExitCode.other_error return ExitCode.other_error
+4 -1
View File
@@ -5,7 +5,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
from importlib_metadata import version as _package_version try:
from importlib_metadata import version as _package_version
except ImportError:
from importlib.metadata import version as _package_version
PROGRAM_NAME = 'ocrmypdf' PROGRAM_NAME = 'ocrmypdf'
+1 -1
View File
@@ -454,7 +454,7 @@ def _transcode_png(pike: Pdf, filename: Path, xref: Xref) -> bool:
img2pdf.convert(fspath(filename), outputstream=f) img2pdf.convert(fspath(filename), outputstream=f)
with Pdf.open(output) as pdf_image: with Pdf.open(output) as pdf_image:
foreign_image = next(pdf_image.pages[0].images.values()) foreign_image = next(iter(pdf_image.pages[0].images.values()))
local_image = pike.copy_foreign(foreign_image) local_image = pike.copy_foreign(foreign_image)
im_obj = pike.get_object(xref, 0) im_obj = pike.get_object(xref, 0)
+5 -2
View File
@@ -13,7 +13,10 @@ import base64
from pathlib import Path from pathlib import Path
from typing import Dict, Iterator, Union from typing import Dict, Iterator, Union
import importlib_resources try:
from importlib_resources import read_binary
except ImportError:
from importlib.resources import read_binary
import pikepdf import pikepdf
import pkg_resources # deprecated import pkg_resources # deprecated
@@ -104,7 +107,7 @@ def generate_pdfa_ps(target_filename: Path, icc: str = 'sRGB'):
if icc != 'sRGB': if icc != 'sRGB':
raise NotImplementedError("Only supporting sRGB") raise NotImplementedError("Only supporting sRGB")
bytes_icc_profile = importlib_resources.read_binary( bytes_icc_profile = read_binary(
'ocrmypdf.data', SRGB_ICC_PROFILE_NAME 'ocrmypdf.data', SRGB_ICC_PROFILE_NAME
) )
ps = '\n'.join(_make_postscript(icc, bytes_icc_profile, 3)) ps = '\n'.join(_make_postscript(icc, bytes_icc_profile, 3))
+1 -1
View File
@@ -87,4 +87,4 @@ def test_jpeg_in_jpeg_out(resources, outpdf):
'tests/plugins/tesseract_noop.py', 'tests/plugins/tesseract_noop.py',
) )
with pikepdf.open(outpdf) as pdf: with pikepdf.open(outpdf) as pdf:
assert next(pdf.pages[0].images.values()).Filter == pikepdf.Name.DCTDecode assert next(iter(pdf.pages[0].images.values())).Filter == pikepdf.Name.DCTDecode
+5 -6
View File
@@ -745,14 +745,13 @@ def test_pdfa_n(pdfa_level, resources, outpdf):
assert pdfa_info['conformance'] == f'PDF/A-{pdfa_level}B' assert pdfa_info['conformance'] == f'PDF/A-{pdfa_level}B'
@pytest.mark.skipif( def test_decompression_bomb_error(resources, outpdf):
PIL.__version__ < '5.0.0', reason="Pillow < 5.0.0 doesn't raise the exception"
)
@pytest.mark.slow
def test_decompression_bomb(resources, outpdf):
p, _out, err = run_ocrmypdf(resources / 'hugemono.pdf', outpdf) p, _out, err = run_ocrmypdf(resources / 'hugemono.pdf', outpdf)
assert 'decompression bomb' in err assert 'decompression bomb' in err and '--max-image-mpixels' in err
@pytest.mark.slow
def test_decompression_bomb_succeeds(resources, outpdf):
p, _out, err = run_ocrmypdf( p, _out, err = run_ocrmypdf(
resources / 'hugemono.pdf', outpdf, '--max-image-mpixels', '2000' resources / 'hugemono.pdf', outpdf, '--max-image-mpixels', '2000'
) )