Compare commits

...
14 Commits
Author SHA1 Message Date
James R. Barlow 194ca699a8 v16.10.4 release notes 2025-07-07 12:36:15 -07:00
James R. Barlow 175b743ffe Fix version test 2025-07-03 11:30:05 -07:00
James R. Barlow 080b73e7c0 Merge remote-tracking branch 'origin/main' 2025-07-03 09:22:20 -07:00
James R. Barlow df6079c06d Merge remote-tracking branch 'origin/dependabot/github_actions/sigstore/gh-action-sigstore-python-3.0.1' 2025-07-03 09:21:44 -07:00
James R. Barlow 45cf92f40b xfail Python logging bug in 3.13.3/4 2025-07-03 09:21:31 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5b1900beec Bump sigstore/gh-action-sigstore-python from 3.0.0 to 3.0.1 (#1541)
Bumps [sigstore/gh-action-sigstore-python](https://github.com/sigstore/gh-action-sigstore-python) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/sigstore/gh-action-sigstore-python/releases)
- [Changelog](https://github.com/sigstore/gh-action-sigstore-python/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sigstore/gh-action-sigstore-python/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: sigstore/gh-action-sigstore-python
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-03 00:40:08 -07:00
dependabot[bot]andGitHub c0208f0da1 Bump sigstore/gh-action-sigstore-python from 3.0.0 to 3.0.1
Bumps [sigstore/gh-action-sigstore-python](https://github.com/sigstore/gh-action-sigstore-python) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/sigstore/gh-action-sigstore-python/releases)
- [Changelog](https://github.com/sigstore/gh-action-sigstore-python/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sigstore/gh-action-sigstore-python/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: sigstore/gh-action-sigstore-python
  dependency-version: 3.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-23 12:15:26 +00:00
James R. Barlow 61163c2aa9 Fix stupid Python runtimeerror 2025-06-13 01:46:30 -07:00
James R. Barlow 332369f1b0 Adjust set_start_method decision, changing fork to forkserver for platforms other than win32, darwin 2025-06-13 01:22:01 -07:00
James R. Barlow 7ea940a3a6 v16.10.3 release notes 2025-06-13 00:28:33 -07:00
James R. Barlow 8a784d6052 Drop explicit norecursedirs setting, which we no longer need 2025-06-13 00:03:24 -07:00
James R. Barlow 5cf86a7c2e Update uv.lock 2025-06-13 00:02:53 -07:00
James R. Barlow 3beabf55e7 Skip optimizing images with pre-blended soft masks
Fixes issue [Bug]: Optimized pdf not rendering with Quartz / Core Graphics #1536
2025-06-12 23:58:43 -07:00
James R. Barlow 6f6448f286 Update dependency lockfile 2025-05-27 14:19:09 -07:00
8 changed files with 772 additions and 621 deletions
+1 -1
View File
@@ -273,7 +273,7 @@ jobs:
path: dist path: dist
- name: Sign the dists with Sigstore - name: Sign the dists with Sigstore
uses: sigstore/gh-action-sigstore-python@v3.0.0 uses: sigstore/gh-action-sigstore-python@v3.0.1
with: with:
inputs: | inputs: |
./dist/*.tar.gz ./dist/*.tar.gz
+10
View File
@@ -25,6 +25,16 @@ about a forthcoming release that has not been tagged yet. A release is only
official when it's tagged and posted to PyPI. official when it's tagged and posted to PyPI.
::: :::
## v16.10.4
- Corrected build errors in Python 3.13.3 and 3.13.4.
## v16.10.3 (not released)
- Blocked optimization of images with pre-blended soft masks. {issue}`1536`
- Fixed warning from hypothesis on running tests.
- Release incomplete due to new test failures in Python 3.13.3 and 3.13.4.
## v16.10.2 ## v16.10.2
- Blacklist pikepdf 9.8.0 due to an incompatible change. - Blacklist pikepdf 9.8.0 due to an incompatible change.
+2 -3
View File
@@ -16,8 +16,8 @@ dependencies = [
"img2pdf>=0.5", "img2pdf>=0.5",
"packaging>=20", "packaging>=20",
"pdfminer.six>=20220319", "pdfminer.six>=20220319",
"pi-heif", # Heif image format - maintainers: if this is removed, it will NOT break "pi-heif", # Heif image format - maintainers: if this is removed, it will NOT break
"pikepdf>=8.10.1, != 9.8.0", "pikepdf>=8.10.1,!=9.8.0",
"Pillow>=10.0.1", "Pillow>=10.0.1",
"pluggy>=1", "pluggy>=1",
"rich>=13", "rich>=13",
@@ -102,7 +102,6 @@ exclude_lines = [
[tool.pytest.ini_options] [tool.pytest.ini_options]
minversion = "6.0" minversion = "6.0"
norecursedirs = ["lib", ".pc", ".git", "venv", "output", "cache", "resources"]
testpaths = ["tests"] testpaths = ["tests"]
addopts = "-n auto" addopts = "-n auto"
markers = ["slow"] markers = ["slow"]
+3 -2
View File
@@ -78,6 +78,7 @@ def run(args=None):
if __name__ == '__main__': if __name__ == '__main__':
multiprocessing.freeze_support() multiprocessing.freeze_support()
if os.name == 'posix': if sys.platform not in ('win32', 'darwin'):
multiprocessing.set_start_method('forkserver') with suppress(RuntimeError):
multiprocessing.set_start_method('forkserver')
sys.exit(run()) sys.exit(run())
+7
View File
@@ -126,6 +126,13 @@ def extract_image_filter(
if Name.Decode in image: if Name.Decode in image:
log.debug(f"xref {xref}: skipping image with Decode table") log.debug(f"xref {xref}: skipping image with Decode table")
return None # Don't mess with custom Decode tables return None # Don't mess with custom Decode tables
if image.get(Name.SMask, Dictionary()).get(Name.Matte, None) is not None:
# https://github.com/ocrmypdf/OCRmyPDF/issues/1536
# Do not attempt to optimize images that have a SMask with a Matte.
# That means alpha channel pre-blending is used, and we're not prepared
# to deal with the complexities of that.
log.debug(f"xref {xref}: skipping image whose SMask has Matte")
return None
return pim, filtdp return pim, filtdp
+9
View File
@@ -6,6 +6,7 @@ from __future__ import annotations
import logging import logging
import secrets import secrets
import subprocess import subprocess
import sys
from decimal import Decimal from decimal import Decimal
from unittest.mock import patch from unittest.mock import patch
@@ -165,6 +166,10 @@ class TestDuplicateFilter:
logger.addFilter(DuplicateFilter(logger)) logger.addFilter(DuplicateFilter(logger))
return logger return logger
@pytest.mark.xfail(
(3, 13, 3) <= sys.version_info[:3] <= (3, 13, 5),
reason="https://github.com/python/cpython/pull/135858",
)
def test_filter_duplicate_messages(self, duplicate_filter_logger, caplog): def test_filter_duplicate_messages(self, duplicate_filter_logger, caplog):
log = duplicate_filter_logger log = duplicate_filter_logger
log.error("test error message") log.error("test error message")
@@ -194,6 +199,10 @@ class TestDuplicateFilter:
assert caplog.records[1].msg == "another error message" assert caplog.records[1].msg == "another error message"
assert caplog.records[2].msg == "yet another error message" assert caplog.records[2].msg == "yet another error message"
@pytest.mark.xfail(
(3, 13, 3) <= sys.version_info[:3] <= (3, 13, 5),
reason="https://github.com/python/cpython/pull/135858",
)
def test_filter_alt_messages(self, duplicate_filter_logger, caplog): def test_filter_alt_messages(self, duplicate_filter_logger, caplog):
log = duplicate_filter_logger log = duplicate_filter_logger
log.error("test error message") log.error("test error message")
+32 -9
View File
@@ -6,7 +6,7 @@ from __future__ import annotations
from io import BytesIO from io import BytesIO
from os import fspath from os import fspath
from pathlib import Path from pathlib import Path
from unittest.mock import MagicMock, patch from unittest.mock import patch
import img2pdf import img2pdf
import pikepdf import pikepdf
@@ -220,7 +220,7 @@ def test_find_formx(resources):
def test_extract_image_filter_with_pdf_image(): def test_extract_image_filter_with_pdf_image():
image = MagicMock() image = Dictionary()
image.Subtype = Name.Image image.Subtype = Name.Image
image.Length = 200 image.Length = 200
image.Width = 10 image.Width = 10
@@ -235,20 +235,20 @@ def test_extract_image_filter_with_pdf_image():
def test_extract_image_filter_with_non_image(): def test_extract_image_filter_with_non_image():
image = MagicMock() image = Dictionary()
image.Subtype = Name.Form image.Subtype = Name.Form
assert extract_image_filter(image, None) is None assert extract_image_filter(image, None) is None
def test_extract_image_filter_with_small_stream_size(): def test_extract_image_filter_with_small_stream_size():
image = MagicMock() image = Dictionary()
image.Subtype = Name.Image image.Subtype = Name.Image
image.Length = 50 image.Length = 50
assert extract_image_filter(image, None) is None assert extract_image_filter(image, None) is None
def test_extract_image_filter_with_small_dimensions(): def test_extract_image_filter_with_small_dimensions():
image = MagicMock() image = Dictionary()
image.Subtype = Name.Image image.Subtype = Name.Image
image.Length = 200 image.Length = 200
image.Width = 5 image.Width = 5
@@ -257,7 +257,7 @@ def test_extract_image_filter_with_small_dimensions():
def test_extract_image_filter_with_multiple_compression_filters(): def test_extract_image_filter_with_multiple_compression_filters():
image = MagicMock() image = Dictionary()
image.Subtype = Name.Image image.Subtype = Name.Image
image.Length = 200 image.Length = 200
image.Width = 10 image.Width = 10
@@ -268,7 +268,7 @@ def test_extract_image_filter_with_multiple_compression_filters():
def test_extract_image_filter_with_wide_gamut_image(): def test_extract_image_filter_with_wide_gamut_image():
image = MagicMock() image = Dictionary()
image.Subtype = Name.Image image.Subtype = Name.Image
image.Length = 200 image.Length = 200
image.Width = 10 image.Width = 10
@@ -296,7 +296,7 @@ def test_extract_image_filter_with_jpeg2000_image():
def test_extract_image_filter_with_ccitt_group_3_image(): def test_extract_image_filter_with_ccitt_group_3_image():
image = MagicMock() image = Dictionary()
image.Subtype = Name.Image image.Subtype = Name.Image
image.Length = 200 image.Length = 200
image.Width = 10 image.Width = 10
@@ -309,7 +309,7 @@ def test_extract_image_filter_with_ccitt_group_3_image():
# Triggers pikepdf bug # Triggers pikepdf bug
# def test_extract_image_filter_with_decode_table(): # def test_extract_image_filter_with_decode_table():
# image = MagicMock() # image = Dictionary()
# image.Subtype = Name.Image # image.Subtype = Name.Image
# image.Length = 200 # image.Length = 200
# image.Width = 10 # image.Width = 10
@@ -319,3 +319,26 @@ def test_extract_image_filter_with_ccitt_group_3_image():
# image.ColorSpace = Name.DeviceGray # image.ColorSpace = Name.DeviceGray
# image.Decode = [42, 0] # image.Decode = [42, 0]
# assert extract_image_filter(image, None) is None # assert extract_image_filter(image, None) is None
def test_extract_image_filter_with_rgb_smask_matte():
image = Dictionary()
image.Subtype = Name.Image
image.Length = 200
image.Width = 10
image.Height = 10
image.Filter = Name.FlateDecode
image.BitsPerComponent = 8
image.ColorSpace = Name.DeviceRGB
image.SMask = Dictionary(
Type=Name.Image,
Subtype=Name.Image,
Length=200,
Width=10,
Height=10,
Filter=Name.FlateDecode,
BitsPerComponent=8,
ColorSpace=Name.DeviceGray,
Matte=Array([1, 2, 3]),
)
assert extract_image_filter(image, None) is None
Generated
+708 -606
View File
File diff suppressed because it is too large Load Diff