Skip to content
10 changes: 6 additions & 4 deletions pypdf/_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ def _get_clone_from(
# to prevent overwriting
self.temp_fileobj = fileobj
self.fileobj = ""
self.with_as_usage = False
# The root of our page tree node.
pages = DictionaryObject()
pages.update(
Expand Down Expand Up @@ -356,7 +355,6 @@ def __enter__(self) -> "PdfWriter":
"""Store that writer is initialized by 'with'."""
t = self.temp_fileobj
self.__init__() # type: ignore
self.with_as_usage = True
self.fileobj = t # type: ignore
return self

Expand All @@ -369,6 +367,9 @@ def __exit__(
"""Write data to the fileobj."""
if self.fileobj:
self.write(self.fileobj)
close_attr = getattr(self.fileobj, "close", None)
if callable(close_attr):
self.fileobj.close() # type: ignore[attr-defined]

def _repr_mimebundle_(
self,
Expand Down Expand Up @@ -1388,13 +1389,14 @@ def write(self, stream: Union[Path, StrByteType]) -> Tuple[bool, IO[Any]]:

if isinstance(stream, (str, Path)):
stream = FileIO(stream, "wb")
self.with_as_usage = True #
my_file = True

self.write_stream(stream)

if self.with_as_usage:
if my_file:
stream.close()
else:
stream.flush()

return my_file, stream

Expand Down
11 changes: 11 additions & 0 deletions tests/test_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2480,3 +2480,14 @@ def test_append_pdf_with_dest_without_page(caplog):
writer.append(reader)
assert "/__WKANCHOR_8" not in writer.named_destinations
assert len(writer.named_destinations) == 3


def test_stream_not_closed():
"""Tests for #2905"""
src = RESOURCE_ROOT / "pdflatex-outline.pdf"
with NamedTemporaryFile() as tmp:
with PdfReader(src) as reader, PdfWriter() as writer:
for i in range(4):
writer.add_page(reader.pages[i])
writer.write(tmp)
assert not tmp.file.closed
Loading