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
36 changes: 32 additions & 4 deletions Doc/library/tempfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@

This module creates temporary files and directories. It works on all
supported platforms. :class:`TemporaryFile`, :class:`NamedTemporaryFile`,
:class:`TemporaryDirectory`, and :class:`SpooledTemporaryFile` are high-level
interfaces which provide automatic cleanup and can be used as
:term:`context managers <context manager>`. :func:`mkstemp` and
:func:`mkdtemp` are lower-level functions which require manual cleanup.
:class:`TemporaryFileWrapper`, :class:`TemporaryDirectory`, and
:class:`SpooledTemporaryFile` are high-level interfaces which provide
automatic cleanup and can be used as :term:`context managers
<context manager>`. :func:`mkstemp` and :func:`mkdtemp` are lower-level
functions which require manual cleanup.

All the user-callable functions and constructors take additional arguments which
allow direct control over the location and name of temporary files and
Expand Down Expand Up @@ -140,6 +141,33 @@ The module defines the following user-callable items:
.. versionchanged:: 3.12
Added *delete_on_close* parameter.

.. class:: TemporaryFileWrapper(file, name, delete=True, delete_on_close=True)

A mutable wrapper returned by :func:`NamedTemporaryFile`. It wraps the
underlying file object, delegating attribute access to it, and ensures
the temporary file is deleted when appropriate.

.. attribute:: file

The underlying :term:`file-like object`.

.. attribute:: name

The file name of the temporary file.

.. method:: close()

Close the temporary file, possibly deleting it depending on the
*delete* and *delete_on_close* arguments passed to
:func:`NamedTemporaryFile`.

.. note::

``tempfile._TemporaryFileWrapper`` is kept as a backwards compatible
alias for this class.

.. versionadded:: next


.. class:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)

Expand Down
7 changes: 5 additions & 2 deletions Lib/tempfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"TMP_MAX", "gettempprefix", # constants
"tempdir", "gettempdir",
"gettempprefixb", "gettempdirb",
"TemporaryFileWrapper",
]


Expand Down Expand Up @@ -484,7 +485,7 @@ def __del__(self):
_warnings.warn(self.warn_message, ResourceWarning)


class _TemporaryFileWrapper:
class TemporaryFileWrapper:
"""Temporary file wrapper

This class provides a wrapper around files opened for
Expand Down Expand Up @@ -555,6 +556,8 @@ def __iter__(self):
for line in self.file:
yield line

_TemporaryFileWrapper = TemporaryFileWrapper

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, add a comment: why it is there.
Question: does it make sence to deprecate the older alias at the same time?

@Aniketsy Aniketsy Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, add a comment: why it is there.

sure 👍

Question: does it make sence to deprecate the older alias at the same time?

I think we can deprecate in follow up, but if you prefer we should add in this PR, only-- i'm happy to go with

Thanks for the review!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would deprecate it right away :)


def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None,
newline=None, suffix=None, prefix=None,
dir=None, delete=True, *, errors=None,
Expand Down Expand Up @@ -607,7 +610,7 @@ def opener(*args):
raw = getattr(file, 'buffer', file)
raw = getattr(raw, 'raw', raw)
raw.name = name
return _TemporaryFileWrapper(file, name, delete, delete_on_close)
return TemporaryFileWrapper(file, name, delete, delete_on_close)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_unexpected_error is failing because you did not change mock.patch('tempfile._TemporaryFileWrapper') to mock.patch('tempfile.TemporaryFileWrapper') in that function.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for pointing out

except:
file.close()
raise
Expand Down
16 changes: 15 additions & 1 deletion Lib/test/test_tempfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ def test_exports(self):
"template" : 1,
"SpooledTemporaryFile" : 1,
"TemporaryDirectory" : 1,
"TemporaryFileWrapper" : 1,
}

unexp = []
Expand Down Expand Up @@ -1141,7 +1142,7 @@ def my_func(dir):
try:
with self.assertWarnsRegex(
expected_warning=ResourceWarning,
expected_regex=r"Implicitly cleaning up <_TemporaryFileWrapper file=.*>",
expected_regex=r"Implicitly cleaning up <TemporaryFileWrapper file=.*>",
):
tmp_name = my_func(dir)
support.gc_collect()
Expand Down Expand Up @@ -1195,6 +1196,19 @@ def test_unexpected_error(self):

# How to test the mode and bufsize parameters?

class TestTemporaryFileWrapper(BaseTestCase):
"""Test TemporaryFileWrapper."""

def test_public_name(self):
self.assertIs(tempfile.TemporaryFileWrapper, tempfile._TemporaryFileWrapper)

def test_in_all(self):
self.assertIn("TemporaryFileWrapper", tempfile.__all__)

def test_is_return_type_of_named_temporary_file(self):
with tempfile.NamedTemporaryFile() as f:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose to move this check to any existing test above.

self.assertIsInstance(f, tempfile.TemporaryFileWrapper)

class TestSpooledTemporaryFile(BaseTestCase):
"""Test SpooledTemporaryFile()."""

Expand Down
Loading