Skip to content
Closed
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
33 changes: 26 additions & 7 deletions pandas/_testing/_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io
import pathlib
import tarfile
import tempfile
from typing import (
TYPE_CHECKING,
Any,
Expand All @@ -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
Expand Down Expand Up @@ -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):
Expand All @@ -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


Expand Down
Loading