Repository: dask/dask

Issue:
Update `tmpdir` and `tmpfile` context manager docstrings
We have `tmpdir` and `tmpfile` utility context managers

https://github.com/dask/dask/blob/b46d8710ea648dbc822e104b0991f8a29bf5d125/dask/utils.py#L124-L125

https://github.com/dask/dask/blob/b46d8710ea648dbc822e104b0991f8a29bf5d125/dask/utils.py#L106-L107

which I suspect were originally introduced back when Dask still supported Python 2.7.

Today, since our minimum supported Python version is 3.7, we can replace our internal usage of `tmpdir` with [`tempfile.TemporaryDirectory`](https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryDirectory) (or the pytest `tmpdir` fixture when used in a test) and `tmpfile` with [`tempfile.TemporaryFile`](https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryFile) from the standard library. 


Discussion:
I'm not sure if using tempfile.TemporaryFile (or tempfile.NamedTemporaryFile) is the right way to proceed. From the [documentation](https://docs.python.org/3/library/tempfile.html) it seems that it can cause troubles on Windows:

> Whether the name can be used to open the file a second time, while the named temporary file is still open, varies across platforms (it can be so used on Unix; it cannot on Windows NT or later).

More info [here](https://stackoverflow.com/questions/15588314/cant-access-temporary-files-created-with-tempfile). This is further confirmed by the fact that the failing test in the [draft](https://github.com/dask/dask/pull/7803) are only on Windows environments.

In addition, if I understood correctly, `tmpfile` only returns the name of the file not the file itself, it creates the file and removes it immediately after.

> 
>     extension = "." + extension.lstrip(".")
>     handle, filename = tempfile.mkstemp(extension, dir=dir)
>     os.close(handle)
>     os.remove(filename)
> 
>     try:
>         yield filename

A possible solution would be to do something around [this line](https://stackoverflow.com/questions/26541416/generate-temporary-file-names-without-creating-actual-file-in-python/45803022#45803022), but I don't know if is better than what is currently implemented.  
Nice detective work @mesejo! I left a comment over in https://github.com/dask/dask/pull/7803
@jrbourbeau checking in here, I noticed that the PR that "fixes" this issue was closed and not merged since there is still use for `tmpdir` and `tmpfile`. See https://github.com/dask/dask/pull/7803#issuecomment-893899855 . Should we close this issue then? 
Let's keep this issue open and use it to track updating the docstrings mentioned in https://github.com/dask/dask/pull/7803#issuecomment-893899855. I've updated the title of this issue accordingly. 

Resolving patch:
diff --git a/dask/utils.py b/dask/utils.py
--- a/dask/utils.py
+++ b/dask/utils.py
@@ -165,6 +165,31 @@ def import_required(mod_name, error_msg):
 
 @contextmanager
 def tmpfile(extension="", dir=None):
+    """
+    Function to create and return a unique temporary file with the given extension, if provided.
+
+    Parameters
+    ----------
+    extension : str
+        The extension of the temporary file to be created
+    dir : str
+        If ``dir`` is not None, the file will be created in that directory; otherwise,
+        Python's default temporary directory is used.
+
+    Returns
+    -------
+    out : str
+        Path to the temporary file
+
+    See Also
+    --------
+    NamedTemporaryFile : Built-in alternative for creating temporary files
+    tmp_path : pytest fixture for creating a temporary directory unique to the test invocation
+
+    Notes
+    -----
+    This context manager is particularly useful on Windows for opening temporary files multiple times.
+    """
     extension = "." + extension.lstrip(".")
     handle, filename = tempfile.mkstemp(extension, dir=dir)
     os.close(handle)
@@ -183,6 +208,24 @@ def tmpfile(extension="", dir=None):
 
 @contextmanager
 def tmpdir(dir=None):
+    """
+    Function to create and return a unique temporary directory.
+
+    Parameters
+    ----------
+    dir : str
+        If ``dir`` is not None, the directory will be created in that directory; otherwise,
+        Python's default temporary directory is used.
+
+    Returns
+    -------
+    out : str
+        Path to the temporary directory
+
+    Notes
+    -----
+    This context manager is particularly useful on Windows for opening temporary directories multiple times.
+    """
     dirname = tempfile.mkdtemp(dir=dir)
 
     try:


Test patch: