Skip to content

Commit 2b62da0

Browse files
BUG: func 'to_pickle' and 'read_pickle' where not accepting URL GH30299
1 parent 37dfcc1 commit 2b62da0

File tree

2 files changed

+50
-17
lines changed

2 files changed

+50
-17
lines changed

doc/source/whatsnew/v1.0.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ I/O
797797
- Bug in :func:`read_json` where default encoding was not set to ``utf-8`` (:issue:`29565`)
798798
- Bug in :class:`PythonParser` where str and bytes were being mixed when dealing with the decimal field (:issue:`29650`)
799799
- :meth:`read_gbq` now accepts ``progress_bar_type`` to display progress bar while the data downloads. (:issue:`29857`)
800-
-
800+
- Bug in :func: 'to_pickle' and :func: 'read_pickle' where not accepting URL (:issue:'30299')
801801

802802
Plotting
803803
^^^^^^^^

pandas/io/pickle.py

+49-16
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
""" pickle compat """
22
import pickle
3+
from typing import Any, Optional
34
import warnings
45

56
from pandas.compat import pickle_compat as pc
67

7-
from pandas.io.common import _get_handle, _stringify_path
8+
from pandas._typing import FilePathOrBuffer
89

10+
from pandas.io.common import (
11+
_get_handle,
12+
get_filepath_or_buffer as _get_filepath_or_buffer,
13+
)
914

10-
def to_pickle(obj, path, compression="infer", protocol=pickle.HIGHEST_PROTOCOL):
15+
16+
def to_pickle(
17+
obj: Any,
18+
filepath_or_buffer: FilePathOrBuffer,
19+
compression: Optional[str] = "infer",
20+
protocol: int = pickle.HIGHEST_PROTOCOL,
21+
):
1122
"""
1223
Pickle (serialize) object to file.
1324
@@ -16,10 +27,12 @@ def to_pickle(obj, path, compression="infer", protocol=pickle.HIGHEST_PROTOCOL):
1627
obj : any object
1728
Any python object.
1829
path : str
19-
File path where the pickled object will be stored.
30+
File path, URL, or buffer where the pickled object will be stored.
2031
compression : {'infer', 'gzip', 'bz2', 'zip', 'xz', None}, default 'infer'
21-
A string representing the compression to use in the output file. By
22-
default, infers from the file extension in specified path.
32+
If 'infer' and 'path_or_url' is path-like, then detect compression from
33+
the following extensions: '.gz', '.bz2', '.zip', or '.xz' (otherwise no
34+
compression) If 'infer' and 'path_or_url' is not path-like, then use
35+
None (= no decompression).
2336
protocol : int
2437
Int which indicates which protocol should be used by the pickler,
2538
default HIGHEST_PROTOCOL (see [1], paragraph 12.1.2). The possible
@@ -63,8 +76,12 @@ def to_pickle(obj, path, compression="infer", protocol=pickle.HIGHEST_PROTOCOL):
6376
>>> import os
6477
>>> os.remove("./dummy.pkl")
6578
"""
66-
path = _stringify_path(path)
67-
f, fh = _get_handle(path, "wb", compression=compression, is_text=False)
79+
fp_or_buf, _, compression, should_close = _get_filepath_or_buffer(
80+
filepath_or_buffer, compression=compression, mode="wb"
81+
)
82+
if not isinstance(fp_or_buf, str) and compression == "infer":
83+
compression = None
84+
f, fh = _get_handle(fp_or_buf, "wb", compression=compression, is_text=False)
6885
if protocol < 0:
6986
protocol = pickle.HIGHEST_PROTOCOL
7087
try:
@@ -73,9 +90,16 @@ def to_pickle(obj, path, compression="infer", protocol=pickle.HIGHEST_PROTOCOL):
7390
f.close()
7491
for _f in fh:
7592
_f.close()
93+
if should_close:
94+
try:
95+
fp_or_buf.close()
96+
except ValueError:
97+
pass
7698

7799

78-
def read_pickle(path, compression="infer"):
100+
def read_pickle(
101+
filepath_or_buffer: FilePathOrBuffer, compression: Optional[str] = "infer"
102+
):
79103
"""
80104
Load pickled pandas object (or any object) from file.
81105
@@ -86,13 +110,13 @@ def read_pickle(path, compression="infer"):
86110
87111
Parameters
88112
----------
89-
path : str
90-
File path where the pickled object will be loaded.
113+
filepath_or_buffer : str
114+
File path, URL, or buffer where the pickled object will be loaded from.
91115
compression : {'infer', 'gzip', 'bz2', 'zip', 'xz', None}, default 'infer'
92-
For on-the-fly decompression of on-disk data. If 'infer', then use
93-
gzip, bz2, xz or zip if path ends in '.gz', '.bz2', '.xz',
94-
or '.zip' respectively, and no decompression otherwise.
95-
Set to None for no decompression.
116+
If 'infer' and 'path_or_url' is path-like, then detect compression from
117+
the following extensions: '.gz', '.bz2', '.zip', or '.xz' (otherwise no
118+
compression) If 'infer' and 'path_or_url' is not path-like, then use
119+
None (= no decompression).
96120
97121
Returns
98122
-------
@@ -134,8 +158,12 @@ def read_pickle(path, compression="infer"):
134158
>>> import os
135159
>>> os.remove("./dummy.pkl")
136160
"""
137-
path = _stringify_path(path)
138-
f, fh = _get_handle(path, "rb", compression=compression, is_text=False)
161+
fp_or_buf, _, compression, should_close = _get_filepath_or_buffer(
162+
filepath_or_buffer, compression=compression
163+
)
164+
if not isinstance(fp_or_buf, str) and compression == "infer":
165+
compression = None
166+
f, fh = _get_handle(fp_or_buf, "rb", compression=compression, is_text=False)
139167

140168
# 1) try standard library Pickle
141169
# 2) try pickle_compat (older pandas version) to handle subclass changes
@@ -159,3 +187,8 @@ def read_pickle(path, compression="infer"):
159187
f.close()
160188
for _f in fh:
161189
_f.close()
190+
if should_close:
191+
try:
192+
fp_or_buf.close()
193+
except ValueError:
194+
pass

0 commit comments

Comments
 (0)