diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index aaa40541c3edb..d53c67b059d7d 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -4,6 +4,7 @@ import io import pathlib import tarfile +import tempfile from typing import ( TYPE_CHECKING, Any, @@ -14,7 +15,6 @@ from pandas.compat._optional import import_optional_dependency import pandas as pd -from pandas._testing.contexts import ensure_clean if TYPE_CHECKING: from collections.abc import Callable @@ -54,9 +54,25 @@ def round_trip_pickle( _path = path if _path is None: _path = f"__{uuid.uuid4()}__.pickle" - with ensure_clean(_path) as temp_path: - pd.to_pickle(obj, temp_path) - return pd.read_pickle(temp_path) + # use a temporary directory and create a path inside it. This avoids + # keeping an open file handle (important on Windows) while still + # ensuring automatic cleanup. + with tempfile.TemporaryDirectory() as tmpdir: + # Only join tmpdir with _path when _path is a string or Path-like. + # _path may be a ReadPickleBuffer (file-like) in which case it + # should be used directly for pickle operations. + if isinstance(_path, (str, pathlib.Path)): + temp_path: FilePath = pathlib.Path(tmpdir) / _path + pd.to_pickle(obj, temp_path) + else: + # _path is a ReadPickleBuffer (file-like object) + pd.to_pickle(obj, _path) # type: ignore[arg-type] + + # For read_pickle, handle both cases + if isinstance(_path, (str, pathlib.Path)): + return pd.read_pickle(pathlib.Path(tmpdir) / _path) + else: + return pd.read_pickle(_path) def round_trip_pathlib(writer, reader, path: str | None = None): @@ -80,9 +96,12 @@ def round_trip_pathlib(writer, reader, path: str | None = None): Path = pathlib.Path if path is None: path = "___pathlib___" - with ensure_clean(path) as path: - writer(Path(path)) - obj = reader(Path(path)) + # Use a temporary directory to host the file so we don't hold an open + # file handle while allowing callers to use pathlib.Path semantics. + with tempfile.TemporaryDirectory() as tmpdir: + p = pathlib.Path(tmpdir) / path + writer(Path(p)) + obj = reader(Path(p)) return obj