77from pypdf .constants import CatalogAttributes as CA
88from pypdf .constants import FileSpecificationDictionaryEntries
99from pypdf .constants import PageAttributes as PG
10- from pypdf .errors import PdfReadError
10+ from pypdf .errors import PdfReadError , PyPdfError
1111from pypdf .generic import (
1212 ArrayObject ,
1313 ByteStringObject ,
@@ -36,14 +36,16 @@ class EmbeddedFile:
3636
3737 Further information on embedded files can be found in section 7.11 of the PDF 2.0 specification.
3838 """
39- def __init__ (self , name : str , pdf_object : DictionaryObject ) -> None :
39+ def __init__ (self , name : str , pdf_object : DictionaryObject , parent : ArrayObject | None = None ) -> None :
4040 """
4141 Args:
4242 name: The (primary) name as provided in the name tree.
4343 pdf_object: The corresponding PDF object to allow retrieving further data.
44+ parent: The parent list.
4445 """
4546 self ._name = name
4647 self .pdf_object = pdf_object
48+ self ._parent = parent
4749
4850 @property
4951 def name (self ) -> str :
@@ -105,7 +107,7 @@ def _create_new(cls, writer: PdfWriter, name: str, content: str | bytes) -> Embe
105107 names_array .extend ([create_string_object (name ), filespec ])
106108
107109 # Return an EmbeddedFile instance
108- return cls (name = name , pdf_object = filespec )
110+ return cls (name = name , pdf_object = filespec , parent = names_array )
109111
110112 @property
111113 def alternative_name (self ) -> str | None :
@@ -276,6 +278,17 @@ def checksum(self, value: ByteStringObject | None) -> None:
276278 else :
277279 params [NameObject ("/CheckSum" )] = value
278280
281+ def delete (self ) -> None :
282+ """Delete the file from the document."""
283+ if not self ._parent :
284+ raise PyPdfError ("Parent required to delete file from document." )
285+ if self .pdf_object not in self ._parent :
286+ raise PyPdfError ("File not found in parent object." )
287+ index = self ._parent .index (self .pdf_object )
288+ self ._parent .pop (index ) # Reference.
289+ self ._parent .pop (index - 1 ) # Name.
290+ self .pdf_object = DictionaryObject () # Invalidate.
291+
279292 def __repr__ (self ) -> str :
280293 return f"<{ self .__class__ .__name__ } name={ self .name !r} >"
281294
@@ -296,7 +309,7 @@ def _load_from_names(cls, names: ArrayObject) -> Generator[EmbeddedFile]:
296309 # Skip plain strings and retrieve them as `direct_name` by index.
297310 file_dictionary = name .get_object ()
298311 direct_name = names [i - 1 ].get_object ()
299- yield EmbeddedFile (name = direct_name , pdf_object = file_dictionary )
312+ yield EmbeddedFile (name = direct_name , pdf_object = file_dictionary , parent = names )
300313
301314 @classmethod
302315 def _load (cls , catalog : DictionaryObject ) -> Generator [EmbeddedFile ]:
0 commit comments