From b0725ff4b3c489b85ee0dd4c554673b66bb07db1 Mon Sep 17 00:00:00 2001 From: invain01 <3038026071@qq.com> Date: Tue, 4 Nov 2025 18:42:59 +0800 Subject: [PATCH 1/4] TST: Replace ensure_clean utility function with the temp_file pytest fixture in \_testing --- pandas/_testing/_io.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index aaa40541c3edb..0c2b46a3a210a 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,7 +54,11 @@ def round_trip_pickle( _path = path if _path is None: _path = f"__{uuid.uuid4()}__.pickle" - with ensure_clean(_path) as 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: + temp_path = pathlib.Path(tmpdir) / _path pd.to_pickle(obj, temp_path) return pd.read_pickle(temp_path) @@ -80,9 +84,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 From 322c49c3ec68780fd11bf43b3e39432442c70344 Mon Sep 17 00:00:00 2001 From: invain01 <3038026071@qq.com> Date: Tue, 4 Nov 2025 19:35:47 +0800 Subject: [PATCH 2/4] TST: Replace ensure_clean utility function (fixing CI error) --- pandas/_testing/_io.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index 0c2b46a3a210a..46c80ab938ee9 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -58,7 +58,13 @@ def round_trip_pickle( # keeping an open file handle (important on Windows) while still # ensuring automatic cleanup. with tempfile.TemporaryDirectory() as tmpdir: - temp_path = pathlib.Path(tmpdir) / _path + # 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 = pathlib.Path(tmpdir) / _path + else: + temp_path = _path pd.to_pickle(obj, temp_path) return pd.read_pickle(temp_path) From e64ea42b5f418ed392ce9f3e3145064a913564ae Mon Sep 17 00:00:00 2001 From: invain01 <3038026071@qq.com> Date: Tue, 4 Nov 2025 20:05:14 +0800 Subject: [PATCH 3/4] fix.CI error fix --- pandas/_testing/_io.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index 46c80ab938ee9..cc715bcebdfb2 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -61,6 +61,7 @@ def round_trip_pickle( # 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. + temp_path: pathlib.Path | ReadPickleBuffer if isinstance(_path, (str, pathlib.Path)): temp_path = pathlib.Path(tmpdir) / _path else: From 16b6f690fddf099f3ab3a805c39ff9db91289435 Mon Sep 17 00:00:00 2001 From: invain01 <3038026071@qq.com> Date: Tue, 4 Nov 2025 20:32:29 +0800 Subject: [PATCH 4/4] fix:mypy type errors resolved --- pandas/_testing/_io.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index cc715bcebdfb2..d53c67b059d7d 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -61,13 +61,18 @@ def round_trip_pickle( # 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. - temp_path: pathlib.Path | ReadPickleBuffer if isinstance(_path, (str, pathlib.Path)): - temp_path = pathlib.Path(tmpdir) / _path + temp_path: FilePath = pathlib.Path(tmpdir) / _path + pd.to_pickle(obj, temp_path) else: - temp_path = _path - pd.to_pickle(obj, temp_path) - return pd.read_pickle(temp_path) + # _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):