diff --git a/pypdf/_page.py b/pypdf/_page.py index b787430ffe..ae6434b6fa 100644 --- a/pypdf/_page.py +++ b/pypdf/_page.py @@ -497,6 +497,17 @@ class PageObject(DictionaryObject): original_page: "PageObject" # very local use in writer when appending + def __new__(cls, *args: Any, **kwargs: Any) -> "PageObject": + # __new__ used here to make sure instance.pdf attribute + # is set. related to #3467. + instance = super().__new__(cls, *args, **kwargs) + + instance.pdf = None + instance.inline_images = None + instance.indirect_reference = None + + return instance + def __init__( self, pdf: Optional[PdfCommonDocProtocol] = None, diff --git a/pypdf/generic/_data_structures.py b/pypdf/generic/_data_structures.py index b826652708..fdd732aaf2 100644 --- a/pypdf/generic/_data_structures.py +++ b/pypdf/generic/_data_structures.py @@ -293,7 +293,9 @@ def clone( visited: set[tuple[int, int]] = set() # (idnum, generation) d__ = cast( "DictionaryObject", - self._reference_clone(self.__class__(), pdf_dest, force_duplicate), + # self.__new__(self.__class__) because we want instance of type __class__, + # where we copy values into later below + self._reference_clone(self.__new__(self.__class__), pdf_dest, force_duplicate), ) if ignore_fields is None: ignore_fields = [] diff --git a/tests/generic/test_files.py b/tests/generic/test_files.py index 9d488e0681..eb997cf914 100644 --- a/tests/generic/test_files.py +++ b/tests/generic/test_files.py @@ -8,6 +8,7 @@ import pytest from pypdf import PdfReader, PdfWriter +from pypdf.annotations._markup_annotations import Polygon from pypdf.constants import AFRelationship from pypdf.errors import PdfReadError, PyPdfError from pypdf.generic import ( @@ -575,3 +576,26 @@ def test_embedded_file__order(): "test.txt", attachment4.pdf_object.indirect_reference, "xyz.txt", attachment3.pdf_object.indirect_reference, ] + + +def test_merge_page_with_annotation(): + writer = PdfWriter() + writer2 = PdfWriter() + writer.add_blank_page(100, 100) + writer2.add_blank_page(100, 100) + + annotation = Polygon( + vertices=[(50, 550), (200, 650), (70, 750), (50, 700)], + ) + + writer.add_annotation(0, annotation) + + page1 = writer.pages[0] + page2 = writer2.pages[0] + page2.merge_page(page1) + + assert page2.annotations[0].get_object()["/Type"] == annotation["/Type"] + assert page2.annotations[0].get_object()["/Subtype"] == annotation["/Subtype"] + assert page2.annotations[0].get_object()["/Vertices"] == annotation["/Vertices"] + assert page2.annotations[0].get_object()["/IT"] == annotation["/IT"] + assert page2.annotations[0].get_object()["/Rect"] == annotation["/Rect"]