Skip to content

Commit 03020cf

Browse files
committed
Issue #28227: gzip now supports pathlib
Patch by Ethan Furman.
1 parent 8e9045d commit 03020cf

File tree

4 files changed

+32
-1
lines changed

4 files changed

+32
-1
lines changed

Doc/library/gzip.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ The module defines the following items:
5656
.. versionchanged:: 3.4
5757
Added support for the ``'x'``, ``'xb'`` and ``'xt'`` modes.
5858

59+
.. versionchanged:: 3.6
60+
Accepts a :term:`path-like object`.
5961

6062
.. class:: GzipFile(filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None)
6163

@@ -151,6 +153,9 @@ The module defines the following items:
151153
The :meth:`~io.BufferedIOBase.read` method now accepts an argument of
152154
``None``.
153155

156+
.. versionchanged:: 3.6
157+
Accepts a :term:`path-like object`.
158+
154159

155160
.. function:: compress(data, compresslevel=9)
156161

Lib/gzip.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def open(filename, mode="rb", compresslevel=9,
4949
raise ValueError("Argument 'newline' not supported in binary mode")
5050

5151
gz_mode = mode.replace("t", "")
52-
if isinstance(filename, (str, bytes)):
52+
if isinstance(filename, (str, bytes, os.PathLike)):
5353
binary_file = GzipFile(filename, gz_mode, compresslevel)
5454
elif hasattr(filename, "read") or hasattr(filename, "write"):
5555
binary_file = GzipFile(None, gz_mode, compresslevel, filename)
@@ -165,6 +165,8 @@ def __init__(self, filename=None, mode=None,
165165
filename = getattr(fileobj, 'name', '')
166166
if not isinstance(filename, (str, bytes)):
167167
filename = ''
168+
else:
169+
filename = os.fspath(filename)
168170
if mode is None:
169171
mode = getattr(fileobj, 'mode', 'rb')
170172

Lib/test/test_gzip.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from test import support
66
from test.support import bigmemtest, _4G
77
import os
8+
import pathlib
89
import io
910
import struct
1011
import array
@@ -67,6 +68,18 @@ def test_write(self):
6768
# Test multiple close() calls.
6869
f.close()
6970

71+
def test_write_read_with_pathlike_file(self):
72+
filename = pathlib.Path(self.filename)
73+
with gzip.GzipFile(filename, 'w') as f:
74+
f.write(data1 * 50)
75+
self.assertIsInstance(f.name, str)
76+
with gzip.GzipFile(filename, 'a') as f:
77+
f.write(data1)
78+
with gzip.GzipFile(filename) as f:
79+
d = f.read()
80+
self.assertEqual(d, data1 * 51)
81+
self.assertIsInstance(f.name, str)
82+
7083
# The following test_write_xy methods test that write accepts
7184
# the corresponding bytes-like object type as input
7285
# and that the data written equals bytes(xy) in all cases.
@@ -521,6 +534,15 @@ def test_binary_modes(self):
521534
file_data = gzip.decompress(f.read())
522535
self.assertEqual(file_data, uncompressed)
523536

537+
def test_pathlike_file(self):
538+
filename = pathlib.Path(self.filename)
539+
with gzip.open(filename, "wb") as f:
540+
f.write(data1 * 50)
541+
with gzip.open(filename, "ab") as f:
542+
f.write(data1)
543+
with gzip.open(filename) as f:
544+
self.assertEqual(f.read(), data1 * 51)
545+
524546
def test_implicit_binary_modes(self):
525547
# Test implicit binary modes (no "b" or "t" in mode string).
526548
uncompressed = data1 * 50

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ Core and Builtins
4646
Library
4747
-------
4848

49+
- Issue #28227: gzip now supports pathlib. Patch by Ethan Furman.
50+
4951
- Issue #27358: Optimized merging var-keyword arguments and improved error
5052
message when pass a non-mapping as a var-keyword argument.
5153

0 commit comments

Comments
 (0)