Temporary files and directories in Python
Python Standard Library has a module to work with temporary files and
directories: tempfile
. This
module handles creating the files/directories, naming them, and cleaning-up
after done.

To create a temporary directory: instantiate a tempfile.TemporaryDirectory
object. By default, when this object is destroyed, the temporary directory
created along with all its contents are wiped from disk. The name of the
directory is saved in the name
attribute. After the directory fulfills its
duty, call the cleanup()
method to remove the temporary bits. For example, to
create a foo
file in a temporary directory:
import tempfile
# Create temporary directory on disk
tmp_dir = tempfile.TemporaryDirectory()
print(tmp_dir.name) # Prints something like `/tmp/tmpr8d4aomi` on Unix
# Create a file in there with some content
with open(tmp_dir.name + "/foo", "w") as foo_file:
foo_file.write("Temporary hello")
# Destroy dir and its contents
tmp_dir.cleanup()
tempfile.TemporaryDirectory
can also be used as a context
manager, to
automatically cleanup the resources after we are done with them. One key
difference is that, as a context manager, there’s no .name
attribute. The
snippet above can be rewritten to:
with tempfile.TemporaryDirectory() as tmp_dir:
with open(tmp_dir + "/foo", "w") as foo_file:
foo_file.write("Temporary hello")
The tempfile.TemporaryDirectory()
constructor has some knobs to add a prefix
or suffix to the directory name, specify a different base directory to use, and
control whether to delete the directory when exiting the context (defaults to
deleting).
In the examples above, we create a file in a temporary directory. But if all we
want is a temporary file, we are better served with tempfile.TemporaryFile
instead, which returns a file
object. This file is
deleted after closing:
tmp_file = tempfile.TemporaryFile()
tmp_file.write(b"Temporary hello")
tmp_file.close()
One interesting thing about this tempfile.TemporaryFile
object is that it is
kind of a ghost on Unixes: the file exists, but has no readable path, only a
file descriptor. The documentation says (as of Python 3.13): Under Unix, the
directory entry for the file is either not created at all or is removed
immediately after the file is created. Pretty weird, in my opinion, but also
cool.
If you need a file with a name, use tempfile.NamedTemporaryFile()
instead.
This way you get a file that has a visible name on disk, accessible via the
name
attribute. This named file is created under the tempfile.gettmpdir()
directory.
tempfile.TemporaryFile
and tempfile.NamedTemporaryFile
can also be used as
context managers, similar to tempfile.TemporaryDirectory
:
with tempfile.NamedTemporaryFile() as tmp_file:
tmp_file.write(b"Temporary hello")
In case you need temporary files in a test, don’t use tempfile
module
directly. Pytest provides the tmp_path
fixture for temporary
directories. This fixture is a pathlib.Path
object pointing to an existing
directory, unique to the test invocation.
Both pytest’s tmp_path
and tempfile.TemporaryDirectory
directories are
created with 700 permission, that is, only the user that owns the Python
process can read, write, and execute it, group and others have zero
permissions (rwx------
). Directories created via pathlib.Path.mkdir
have
755, so group and others can read and execute (rwxr-xr-x
).
Files created with open()
directly have 644 permission (rw-r--r--
), while
tempfile.TemporaryFile
have 600 permission.
These differences in permissions can bite hard. If you need to change the
permission, I suggest to create a pathlib.Path
for the directory or file and
then chmod
it:
import tempfile
from pathlib import Path
with tempfile.TemporaryDirectory() as tmp_dir:
tmp_path = Path(tmp_dir)
tmp_path.chmod(0o755)
foo(tmp_path)
You could also use the chmod
function from the os
module, but I’m a huge
fan of pathlib
and prefer it instead.