Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/docx/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ def _get_by_sha1(self, sha1: str) -> ImagePart | None:
"""Return the image part in this collection having a SHA1 hash matching `sha1`,
or |None| if not found."""
for image_part in self._image_parts:
# ---skip parts loaded for an unsupported image type (e.g. SVG), which
# ---come through the image relationships as a plain Part and have no sha1
if not hasattr(image_part, "sha1"):
continue
if image_part.sha1 == sha1:
return image_part
return None
Expand Down
13 changes: 13 additions & 0 deletions tests/test_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from docx.image.image import Image
from docx.opc.packuri import PackURI
from docx.opc.part import Part
from docx.package import ImageParts, Package
from docx.parts.image import ImagePart

Expand Down Expand Up @@ -102,6 +103,18 @@ def but_it_adds_a_new_image_part_when_match_fails(
_add_image_part_.assert_called_once_with(image_parts, image_)
assert image_part is image_part_

def it_skips_parts_without_a_sha1_when_matching(self, request: FixtureRequest):
# ---an unsupported image type (e.g. SVG) is reached through the image
# ---relationships as a plain Part with no sha1, and must be skipped
# ---rather than raising AttributeError---
non_image_part = instance_mock(request, Part)
image_part = instance_mock(request, ImagePart, sha1="f005ba11")
image_parts = ImageParts()
image_parts.append(non_image_part)
image_parts.append(image_part)

assert image_parts._get_by_sha1("f005ba11") is image_part

@pytest.mark.parametrize(
("existing_partname_numbers", "expected_partname_number"),
[
Expand Down