Skip to content

Commit 710941c

Browse files
authored
Update bz2.py from 3.13.5 (#6055)
1 parent 2d65c7f commit 710941c

File tree

3 files changed

+211
-14
lines changed

3 files changed

+211
-14
lines changed

Lib/bz2.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from _bz2 import BZ2Compressor, BZ2Decompressor
1818

1919

20-
_MODE_CLOSED = 0
20+
# Value 0 no longer used
2121
_MODE_READ = 1
2222
# Value 2 no longer used
2323
_MODE_WRITE = 3
@@ -54,7 +54,7 @@ def __init__(self, filename, mode="r", *, compresslevel=9):
5454
"""
5555
self._fp = None
5656
self._closefp = False
57-
self._mode = _MODE_CLOSED
57+
self._mode = None
5858

5959
if not (1 <= compresslevel <= 9):
6060
raise ValueError("compresslevel must be between 1 and 9")
@@ -100,7 +100,7 @@ def close(self):
100100
May be called more than once without error. Once the file is
101101
closed, any other operation on it will raise a ValueError.
102102
"""
103-
if self._mode == _MODE_CLOSED:
103+
if self.closed:
104104
return
105105
try:
106106
if self._mode == _MODE_READ:
@@ -115,13 +115,21 @@ def close(self):
115115
finally:
116116
self._fp = None
117117
self._closefp = False
118-
self._mode = _MODE_CLOSED
119118
self._buffer = None
120119

121120
@property
122121
def closed(self):
123122
"""True if this file is closed."""
124-
return self._mode == _MODE_CLOSED
123+
return self._fp is None
124+
125+
@property
126+
def name(self):
127+
self._check_not_closed()
128+
return self._fp.name
129+
130+
@property
131+
def mode(self):
132+
return 'wb' if self._mode == _MODE_WRITE else 'rb'
125133

126134
def fileno(self):
127135
"""Return the file descriptor for the underlying file."""

Lib/lzma.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def __init__(self, filename=None, mode="r", *,
128128

129129
if self._mode == _MODE_READ:
130130
raw = _compression.DecompressReader(self._fp, LZMADecompressor,
131-
trailing_error=LZMAError, format=format, filters=filters)
131+
trailing_error=LZMAError, format=format, filters=filters)
132132
self._buffer = io.BufferedReader(raw)
133133

134134
def close(self):

Lib/test/test_bz2.py

Lines changed: 197 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@
33

44
import array
55
import unittest
6+
import io
67
from io import BytesIO, DEFAULT_BUFFER_SIZE
78
import os
89
import pickle
910
import glob
1011
import tempfile
11-
import pathlib
1212
import random
1313
import shutil
1414
import subprocess
1515
import threading
1616
from test.support import import_helper
1717
from test.support import threading_helper
18-
from test.support.os_helper import unlink
18+
from test.support.os_helper import unlink, FakePath
1919
import _compression
2020
import sys
2121

@@ -476,7 +476,6 @@ def testReadlinesNoNewline(self):
476476
self.assertEqual(xlines, [b'Test'])
477477

478478
def testContextProtocol(self):
479-
f = None
480479
with BZ2File(self.filename, "wb") as f:
481480
f.write(b"xxx")
482481
f = BZ2File(self.filename, "rb")
@@ -537,26 +536,210 @@ def testMultiStreamOrdering(self):
537536
with BZ2File(self.filename) as bz2f:
538537
self.assertEqual(bz2f.read(), data1 + data2)
539538

539+
def testOpenFilename(self):
540+
with BZ2File(self.filename, "wb") as f:
541+
f.write(b'content')
542+
self.assertEqual(f.name, self.filename)
543+
self.assertIsInstance(f.fileno(), int)
544+
self.assertEqual(f.mode, 'wb')
545+
self.assertIs(f.readable(), False)
546+
self.assertIs(f.writable(), True)
547+
self.assertIs(f.seekable(), False)
548+
self.assertIs(f.closed, False)
549+
self.assertIs(f.closed, True)
550+
with self.assertRaises(ValueError):
551+
f.name
552+
self.assertRaises(ValueError, f.fileno)
553+
self.assertEqual(f.mode, 'wb')
554+
self.assertRaises(ValueError, f.readable)
555+
self.assertRaises(ValueError, f.writable)
556+
self.assertRaises(ValueError, f.seekable)
557+
558+
with BZ2File(self.filename, "ab") as f:
559+
f.write(b'appendix')
560+
self.assertEqual(f.name, self.filename)
561+
self.assertIsInstance(f.fileno(), int)
562+
self.assertEqual(f.mode, 'wb')
563+
self.assertIs(f.readable(), False)
564+
self.assertIs(f.writable(), True)
565+
self.assertIs(f.seekable(), False)
566+
self.assertIs(f.closed, False)
567+
self.assertIs(f.closed, True)
568+
with self.assertRaises(ValueError):
569+
f.name
570+
self.assertRaises(ValueError, f.fileno)
571+
self.assertEqual(f.mode, 'wb')
572+
self.assertRaises(ValueError, f.readable)
573+
self.assertRaises(ValueError, f.writable)
574+
self.assertRaises(ValueError, f.seekable)
575+
576+
with BZ2File(self.filename, 'rb') as f:
577+
self.assertEqual(f.read(), b'contentappendix')
578+
self.assertEqual(f.name, self.filename)
579+
self.assertIsInstance(f.fileno(), int)
580+
self.assertEqual(f.mode, 'rb')
581+
self.assertIs(f.readable(), True)
582+
self.assertIs(f.writable(), False)
583+
self.assertIs(f.seekable(), True)
584+
self.assertIs(f.closed, False)
585+
self.assertIs(f.closed, True)
586+
with self.assertRaises(ValueError):
587+
f.name
588+
self.assertRaises(ValueError, f.fileno)
589+
self.assertEqual(f.mode, 'rb')
590+
self.assertRaises(ValueError, f.readable)
591+
self.assertRaises(ValueError, f.writable)
592+
self.assertRaises(ValueError, f.seekable)
593+
594+
def testOpenFileWithName(self):
595+
with open(self.filename, 'wb') as raw:
596+
with BZ2File(raw, 'wb') as f:
597+
f.write(b'content')
598+
self.assertEqual(f.name, raw.name)
599+
self.assertEqual(f.fileno(), raw.fileno())
600+
self.assertEqual(f.mode, 'wb')
601+
self.assertIs(f.readable(), False)
602+
self.assertIs(f.writable(), True)
603+
self.assertIs(f.seekable(), False)
604+
self.assertIs(f.closed, False)
605+
self.assertIs(f.closed, True)
606+
with self.assertRaises(ValueError):
607+
f.name
608+
self.assertRaises(ValueError, f.fileno)
609+
self.assertEqual(f.mode, 'wb')
610+
self.assertRaises(ValueError, f.readable)
611+
self.assertRaises(ValueError, f.writable)
612+
self.assertRaises(ValueError, f.seekable)
613+
614+
with open(self.filename, 'ab') as raw:
615+
with BZ2File(raw, 'ab') as f:
616+
f.write(b'appendix')
617+
self.assertEqual(f.name, raw.name)
618+
self.assertEqual(f.fileno(), raw.fileno())
619+
self.assertEqual(f.mode, 'wb')
620+
self.assertIs(f.readable(), False)
621+
self.assertIs(f.writable(), True)
622+
self.assertIs(f.seekable(), False)
623+
self.assertIs(f.closed, False)
624+
self.assertIs(f.closed, True)
625+
with self.assertRaises(ValueError):
626+
f.name
627+
self.assertRaises(ValueError, f.fileno)
628+
self.assertEqual(f.mode, 'wb')
629+
self.assertRaises(ValueError, f.readable)
630+
self.assertRaises(ValueError, f.writable)
631+
self.assertRaises(ValueError, f.seekable)
632+
633+
with open(self.filename, 'rb') as raw:
634+
with BZ2File(raw, 'rb') as f:
635+
self.assertEqual(f.read(), b'contentappendix')
636+
self.assertEqual(f.name, raw.name)
637+
self.assertEqual(f.fileno(), raw.fileno())
638+
self.assertEqual(f.mode, 'rb')
639+
self.assertIs(f.readable(), True)
640+
self.assertIs(f.writable(), False)
641+
self.assertIs(f.seekable(), True)
642+
self.assertIs(f.closed, False)
643+
self.assertIs(f.closed, True)
644+
with self.assertRaises(ValueError):
645+
f.name
646+
self.assertRaises(ValueError, f.fileno)
647+
self.assertEqual(f.mode, 'rb')
648+
self.assertRaises(ValueError, f.readable)
649+
self.assertRaises(ValueError, f.writable)
650+
self.assertRaises(ValueError, f.seekable)
651+
652+
def testOpenFileWithoutName(self):
653+
bio = BytesIO()
654+
with BZ2File(bio, 'wb') as f:
655+
f.write(b'content')
656+
with self.assertRaises(AttributeError):
657+
f.name
658+
self.assertRaises(io.UnsupportedOperation, f.fileno)
659+
self.assertEqual(f.mode, 'wb')
660+
with self.assertRaises(ValueError):
661+
f.name
662+
self.assertRaises(ValueError, f.fileno)
663+
664+
with BZ2File(bio, 'ab') as f:
665+
f.write(b'appendix')
666+
with self.assertRaises(AttributeError):
667+
f.name
668+
self.assertRaises(io.UnsupportedOperation, f.fileno)
669+
self.assertEqual(f.mode, 'wb')
670+
with self.assertRaises(ValueError):
671+
f.name
672+
self.assertRaises(ValueError, f.fileno)
673+
674+
bio.seek(0)
675+
with BZ2File(bio, 'rb') as f:
676+
self.assertEqual(f.read(), b'contentappendix')
677+
with self.assertRaises(AttributeError):
678+
f.name
679+
self.assertRaises(io.UnsupportedOperation, f.fileno)
680+
self.assertEqual(f.mode, 'rb')
681+
with self.assertRaises(ValueError):
682+
f.name
683+
self.assertRaises(ValueError, f.fileno)
684+
685+
def testOpenFileWithIntName(self):
686+
fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
687+
with open(fd, 'wb') as raw:
688+
with BZ2File(raw, 'wb') as f:
689+
f.write(b'content')
690+
self.assertEqual(f.name, raw.name)
691+
self.assertEqual(f.fileno(), raw.fileno())
692+
self.assertEqual(f.mode, 'wb')
693+
with self.assertRaises(ValueError):
694+
f.name
695+
self.assertRaises(ValueError, f.fileno)
696+
697+
fd = os.open(self.filename, os.O_WRONLY | os.O_CREAT | os.O_APPEND)
698+
with open(fd, 'ab') as raw:
699+
with BZ2File(raw, 'ab') as f:
700+
f.write(b'appendix')
701+
self.assertEqual(f.name, raw.name)
702+
self.assertEqual(f.fileno(), raw.fileno())
703+
self.assertEqual(f.mode, 'wb')
704+
with self.assertRaises(ValueError):
705+
f.name
706+
self.assertRaises(ValueError, f.fileno)
707+
708+
fd = os.open(self.filename, os.O_RDONLY)
709+
with open(fd, 'rb') as raw:
710+
with BZ2File(raw, 'rb') as f:
711+
self.assertEqual(f.read(), b'contentappendix')
712+
self.assertEqual(f.name, raw.name)
713+
self.assertEqual(f.fileno(), raw.fileno())
714+
self.assertEqual(f.mode, 'rb')
715+
with self.assertRaises(ValueError):
716+
f.name
717+
self.assertRaises(ValueError, f.fileno)
718+
540719
def testOpenBytesFilename(self):
541720
str_filename = self.filename
542-
try:
543-
bytes_filename = str_filename.encode("ascii")
544-
except UnicodeEncodeError:
545-
self.skipTest("Temporary file name needs to be ASCII")
721+
bytes_filename = os.fsencode(str_filename)
546722
with BZ2File(bytes_filename, "wb") as f:
547723
f.write(self.DATA)
724+
self.assertEqual(f.name, bytes_filename)
548725
with BZ2File(bytes_filename, "rb") as f:
549726
self.assertEqual(f.read(), self.DATA)
727+
self.assertEqual(f.name, bytes_filename)
550728
# Sanity check that we are actually operating on the right file.
551729
with BZ2File(str_filename, "rb") as f:
552730
self.assertEqual(f.read(), self.DATA)
731+
self.assertEqual(f.name, str_filename)
553732

733+
# TODO: RUSTPYTHON
734+
@unittest.expectedFailure
554735
def testOpenPathLikeFilename(self):
555-
filename = pathlib.Path(self.filename)
736+
filename = FakePath(self.filename)
556737
with BZ2File(filename, "wb") as f:
557738
f.write(self.DATA)
739+
self.assertEqual(f.name, self.filename)
558740
with BZ2File(filename, "rb") as f:
559741
self.assertEqual(f.read(), self.DATA)
742+
self.assertEqual(f.name, self.filename)
560743

561744
def testDecompressLimited(self):
562745
"""Decompressed data buffering should be limited"""
@@ -577,6 +760,9 @@ def testReadBytesIO(self):
577760
with BZ2File(bio) as bz2f:
578761
self.assertRaises(TypeError, bz2f.read, float())
579762
self.assertEqual(bz2f.read(), self.TEXT)
763+
with self.assertRaises(AttributeError):
764+
bz2.name
765+
self.assertEqual(bz2f.mode, 'rb')
580766
self.assertFalse(bio.closed)
581767

582768
def testPeekBytesIO(self):
@@ -592,6 +778,9 @@ def testWriteBytesIO(self):
592778
with BZ2File(bio, "w") as bz2f:
593779
self.assertRaises(TypeError, bz2f.write)
594780
bz2f.write(self.TEXT)
781+
with self.assertRaises(AttributeError):
782+
bz2.name
783+
self.assertEqual(bz2f.mode, 'wb')
595784
self.assertEqual(ext_decompress(bio.getvalue()), self.TEXT)
596785
self.assertFalse(bio.closed)
597786

0 commit comments

Comments
 (0)