Skip to content

gh-87646: Added .path to tempfile #104466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
21 changes: 18 additions & 3 deletions Doc/library/tempfile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ The module defines the following user-callable items:
attribute is the underlying true file object. This :term:`file-like object`
can be used in a :keyword:`with` statement, just like a normal file. The
name of the temporary file can be retrieved from the :attr:`name` attribute
of the returned file-like object. On Unix, unlike with the
:func:`TemporaryFile`, the directory entry does not get unlinked immediately
after the file creation.
and :class:`pathlib.Path` path using :attr:`path` of the returned file-like
object. On Unix, unlike with the :func:`TemporaryFile`, the directory entry
does not get unlinked immediately after the file creation.

If *delete* is true (the default) and *delete_on_close* is true (the
default), the file is deleted as soon as it is closed. If *delete* is true
Expand Down Expand Up @@ -142,6 +142,9 @@ The module defines the following user-callable items:
.. versionchanged:: 3.12
Added *delete_on_close* parameter.

.. versionchanged:: 3.13
Added *path* property.


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

Expand Down Expand Up @@ -211,6 +214,9 @@ The module defines the following user-callable items:
.. versionchanged:: 3.12
Added the *delete* parameter.

.. versionchanged:: 3.13
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't new path property be explained somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought same, but even the .name is not explained in this file. I can add it if someone can point an apt location 👍

Copy link
Contributor Author

@ganesh-k13 ganesh-k13 May 14, 2023

Choose a reason for hiding this comment

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

NamedTemporaryFile indeed had a reference to .name, I added .path there. Thanks!, ref: diff. I'll leave the TemporaryDirectory for now, we may need to add name and path

Added *path* property.


.. function:: mkstemp(suffix=None, prefix=None, dir=None, text=False)

Expand Down Expand Up @@ -421,6 +427,15 @@ Here are some examples of typical usage of the :mod:`tempfile` module::
>>>
# directory and contents have been removed

# create a named temporary file, similar to TemporaryFile
# but location and name is accessible
>>> with tempfile.NamedTemporaryFile as fp:
... print('file name: ', fp.name)
... print('file path: ', fp.path)
file name: '/tmp/tmpfiehg5my'
file path: PosixPath('/tmp/tmpfiehg5my')


.. _tempfile-mktemp-deprecated:

Deprecated functions and variables
Expand Down
9 changes: 9 additions & 0 deletions Lib/tempfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import warnings as _warnings
import io as _io
import os as _os
from pathlib import Path as _Path
import shutil as _shutil
import errno as _errno
from random import Random as _Random
Expand Down Expand Up @@ -518,6 +519,10 @@ def __iter__(self):
for line in self.file:
yield line

@_functools.cached_property
def path(self):
return _Path(self.name)

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 @@ -918,6 +923,10 @@ def __exit__(self, exc, value, tb):
if self._delete:
self.cleanup()

@_functools.cached_property
def path(self):
return _Path(self.name)

def cleanup(self):
if self._finalizer.detach() or _os.path.exists(self.name):
self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_tempfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,12 @@ def test_unexpected_error(self):
mock_open().close.assert_called()
self.assertEqual(os.listdir(dir), [])

def test_path_method(self):
d = self.do_create()
path = d.path
self.assertTrue(issubclass(type(path), pathlib.Path), "unexpected return type")
self.assertEqual(str(path), d.name, ".path .name mismatch")

# How to test the mode and bufsize parameters?

class TestSpooledTemporaryFile(BaseTestCase):
Expand Down Expand Up @@ -1853,5 +1859,12 @@ def test_delete_false(self):
self.assertTrue(os.path.exists(working_dir))
shutil.rmtree(working_dir)

def test_path_method(self):
d = self.do_create()
path = d.path
self.assertTrue(issubclass(type(path), pathlib.Path), "unexpected return type")
self.assertEqual(str(path), d.name, ".path .name mismatch")


if __name__ == "__main__":
unittest.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:class:`tempfile.NamedTemporaryFile` and :class:`tempfile.TemporaryDirectory`
includes a new ``.path`` property. This provides the temporary file name as a
:class:`pathlib.Path` object