Skip to content

Commit

Permalink
Merge pull request #196 from python/master
Browse files Browse the repository at this point in the history
Sync Fork from Upstream Repo
  • Loading branch information
sthagen committed Jan 21, 2020
2 parents 343362a + 59e2d26 commit 5f08b9d
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 152 deletions.
12 changes: 9 additions & 3 deletions Lib/gzip.py
Expand Up @@ -209,7 +209,7 @@ def __init__(self, filename=None, mode=None,
self.fileobj = fileobj

if self.mode == WRITE:
self._write_gzip_header()
self._write_gzip_header(compresslevel)

@property
def filename(self):
Expand All @@ -236,7 +236,7 @@ def _init_write(self, filename):
self.bufsize = 0
self.offset = 0 # Current file offset for seek(), tell(), etc

def _write_gzip_header(self):
def _write_gzip_header(self, compresslevel):
self.fileobj.write(b'\037\213') # magic header
self.fileobj.write(b'\010') # compression method
try:
Expand All @@ -257,7 +257,13 @@ def _write_gzip_header(self):
if mtime is None:
mtime = time.time()
write32u(self.fileobj, int(mtime))
self.fileobj.write(b'\002')
if compresslevel == _COMPRESS_LEVEL_BEST:
xfl = b'\002'
elif compresslevel == _COMPRESS_LEVEL_FAST:
xfl = b'\004'
else:
xfl = b'\000'
self.fileobj.write(xfl)
self.fileobj.write(b'\377')
if fname:
self.fileobj.write(fname + b'\000')
Expand Down
20 changes: 20 additions & 0 deletions Lib/test/test_gzip.py
Expand Up @@ -358,6 +358,26 @@ def test_metadata(self):
isizeBytes = fRead.read(4)
self.assertEqual(isizeBytes, struct.pack('<i', len(data1)))

def test_compresslevel_metadata(self):
# see RFC 1952: http://www.faqs.org/rfcs/rfc1952.html
# specifically, discussion of XFL in section 2.3.1
cases = [
('fast', 1, b'\x04'),
('best', 9, b'\x02'),
('tradeoff', 6, b'\x00'),
]
xflOffset = 8

for (name, level, expectedXflByte) in cases:
with self.subTest(name):
fWrite = gzip.GzipFile(self.filename, 'w', compresslevel=level)
with fWrite:
fWrite.write(data1)
with open(self.filename, 'rb') as fRead:
fRead.seek(xflOffset)
xflByte = fRead.read(1)
self.assertEqual(xflByte, expectedXflByte)

def test_with_open(self):
# GzipFile supports the context management protocol
with gzip.GzipFile(self.filename, "wb") as f:
Expand Down
296 changes: 148 additions & 148 deletions Lib/test/test_math.py
Expand Up @@ -1746,19 +1746,139 @@ def _naive_prod(iterable, start=1):
self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
decimal.Decimal)

# Custom assertions.
def testPerm(self):
perm = math.perm
factorial = math.factorial
# Test if factorial definition is satisfied
for n in range(100):
for k in range(n + 1):
self.assertEqual(perm(n, k),
factorial(n) // factorial(n - k))

def assertIsNaN(self, value):
if not math.isnan(value):
self.fail("Expected a NaN, got {!r}.".format(value))
# Test for Pascal's identity
for n in range(1, 100):
for k in range(1, n):
self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))

def assertEqualSign(self, x, y):
"""Similar to assertEqual(), but compare also the sign.
# Test corner cases
for n in range(1, 100):
self.assertEqual(perm(n, 0), 1)
self.assertEqual(perm(n, 1), n)
self.assertEqual(perm(n, n), factorial(n))

Function useful to compare signed zeros.
"""
self.assertEqual(x, y)
self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))
# Test one argument form
for n in range(20):
self.assertEqual(perm(n), factorial(n))
self.assertEqual(perm(n, None), factorial(n))

# Raises TypeError if any argument is non-integer or argument count is
# not 1 or 2
self.assertRaises(TypeError, perm, 10, 1.0)
self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
self.assertRaises(TypeError, perm, 10, "1")
self.assertRaises(TypeError, perm, 10.0, 1)
self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
self.assertRaises(TypeError, perm, "10", 1)

self.assertRaises(TypeError, perm)
self.assertRaises(TypeError, perm, 10, 1, 3)
self.assertRaises(TypeError, perm)

# Raises Value error if not k or n are negative numbers
self.assertRaises(ValueError, perm, -1, 1)
self.assertRaises(ValueError, perm, -2**1000, 1)
self.assertRaises(ValueError, perm, 1, -1)
self.assertRaises(ValueError, perm, 1, -2**1000)

# Returns zero if k is greater than n
self.assertEqual(perm(1, 2), 0)
self.assertEqual(perm(1, 2**1000), 0)

n = 2**1000
self.assertEqual(perm(n, 0), 1)
self.assertEqual(perm(n, 1), n)
self.assertEqual(perm(n, 2), n * (n-1))
if support.check_impl_detail(cpython=True):
self.assertRaises(OverflowError, perm, n, n)

for n, k in (True, True), (True, False), (False, False):
self.assertEqual(perm(n, k), 1)
self.assertIs(type(perm(n, k)), int)
self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
for k in range(3):
self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)

def testComb(self):
comb = math.comb
factorial = math.factorial
# Test if factorial definition is satisfied
for n in range(100):
for k in range(n + 1):
self.assertEqual(comb(n, k), factorial(n)
// (factorial(k) * factorial(n - k)))

# Test for Pascal's identity
for n in range(1, 100):
for k in range(1, n):
self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))

# Test corner cases
for n in range(100):
self.assertEqual(comb(n, 0), 1)
self.assertEqual(comb(n, n), 1)

for n in range(1, 100):
self.assertEqual(comb(n, 1), n)
self.assertEqual(comb(n, n - 1), n)

# Test Symmetry
for n in range(100):
for k in range(n // 2):
self.assertEqual(comb(n, k), comb(n, n - k))

# Raises TypeError if any argument is non-integer or argument count is
# not 2
self.assertRaises(TypeError, comb, 10, 1.0)
self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
self.assertRaises(TypeError, comb, 10, "1")
self.assertRaises(TypeError, comb, 10.0, 1)
self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
self.assertRaises(TypeError, comb, "10", 1)

self.assertRaises(TypeError, comb, 10)
self.assertRaises(TypeError, comb, 10, 1, 3)
self.assertRaises(TypeError, comb)

# Raises Value error if not k or n are negative numbers
self.assertRaises(ValueError, comb, -1, 1)
self.assertRaises(ValueError, comb, -2**1000, 1)
self.assertRaises(ValueError, comb, 1, -1)
self.assertRaises(ValueError, comb, 1, -2**1000)

# Returns zero if k is greater than n
self.assertEqual(comb(1, 2), 0)
self.assertEqual(comb(1, 2**1000), 0)

n = 2**1000
self.assertEqual(comb(n, 0), 1)
self.assertEqual(comb(n, 1), n)
self.assertEqual(comb(n, 2), n * (n-1) // 2)
self.assertEqual(comb(n, n), 1)
self.assertEqual(comb(n, n-1), n)
self.assertEqual(comb(n, n-2), n * (n-1) // 2)
if support.check_impl_detail(cpython=True):
self.assertRaises(OverflowError, comb, n, n//2)

for n, k in (True, True), (True, False), (False, False):
self.assertEqual(comb(n, k), 1)
self.assertIs(type(comb(n, k)), int)
self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
for k in range(3):
self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)

@requires_IEEE_754
def test_nextafter(self):
Expand Down Expand Up @@ -1802,9 +1922,9 @@ def test_nextafter(self):
self.assertEqual(math.nextafter(-largest_normal, -INF), -INF)

# NaN
self.assertTrue(math.isnan(math.nextafter(NAN, 1.0)))
self.assertTrue(math.isnan(math.nextafter(1.0, NAN)))
self.assertTrue(math.isnan(math.nextafter(NAN, NAN)))
self.assertIsNaN(math.nextafter(NAN, 1.0))
self.assertIsNaN(math.nextafter(1.0, NAN))
self.assertIsNaN(math.nextafter(NAN, NAN))

@requires_IEEE_754
def test_ulp(self):
Expand All @@ -1822,13 +1942,27 @@ def test_ulp(self):

# special cases
self.assertEqual(math.ulp(INF), INF)
self.assertTrue(math.isnan(math.ulp(math.nan)))
self.assertIsNaN(math.ulp(math.nan))

# negative number: ulp(-x) == ulp(x)
for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF):
with self.subTest(x=x):
self.assertEqual(math.ulp(-x), math.ulp(x))

# Custom assertions.

def assertIsNaN(self, value):
if not math.isnan(value):
self.fail("Expected a NaN, got {!r}.".format(value))

def assertEqualSign(self, x, y):
"""Similar to assertEqual(), but compare also the sign with copysign().
Function useful to compare signed zeros.
"""
self.assertEqual(x, y)
self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))


class IsCloseTests(unittest.TestCase):
isclose = math.isclose # subclasses should override this
Expand Down Expand Up @@ -1952,140 +2086,6 @@ def test_fractions(self):
self.assertAllClose(fraction_examples, rel_tol=1e-8)
self.assertAllNotClose(fraction_examples, rel_tol=1e-9)

def testPerm(self):
perm = math.perm
factorial = math.factorial
# Test if factorial definition is satisfied
for n in range(100):
for k in range(n + 1):
self.assertEqual(perm(n, k),
factorial(n) // factorial(n - k))

# Test for Pascal's identity
for n in range(1, 100):
for k in range(1, n):
self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))

# Test corner cases
for n in range(1, 100):
self.assertEqual(perm(n, 0), 1)
self.assertEqual(perm(n, 1), n)
self.assertEqual(perm(n, n), factorial(n))

# Test one argument form
for n in range(20):
self.assertEqual(perm(n), factorial(n))
self.assertEqual(perm(n, None), factorial(n))

# Raises TypeError if any argument is non-integer or argument count is
# not 1 or 2
self.assertRaises(TypeError, perm, 10, 1.0)
self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
self.assertRaises(TypeError, perm, 10, "1")
self.assertRaises(TypeError, perm, 10.0, 1)
self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
self.assertRaises(TypeError, perm, "10", 1)

self.assertRaises(TypeError, perm)
self.assertRaises(TypeError, perm, 10, 1, 3)
self.assertRaises(TypeError, perm)

# Raises Value error if not k or n are negative numbers
self.assertRaises(ValueError, perm, -1, 1)
self.assertRaises(ValueError, perm, -2**1000, 1)
self.assertRaises(ValueError, perm, 1, -1)
self.assertRaises(ValueError, perm, 1, -2**1000)

# Returns zero if k is greater than n
self.assertEqual(perm(1, 2), 0)
self.assertEqual(perm(1, 2**1000), 0)

n = 2**1000
self.assertEqual(perm(n, 0), 1)
self.assertEqual(perm(n, 1), n)
self.assertEqual(perm(n, 2), n * (n-1))
if support.check_impl_detail(cpython=True):
self.assertRaises(OverflowError, perm, n, n)

for n, k in (True, True), (True, False), (False, False):
self.assertEqual(perm(n, k), 1)
self.assertIs(type(perm(n, k)), int)
self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
for k in range(3):
self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)

def testComb(self):
comb = math.comb
factorial = math.factorial
# Test if factorial definition is satisfied
for n in range(100):
for k in range(n + 1):
self.assertEqual(comb(n, k), factorial(n)
// (factorial(k) * factorial(n - k)))

# Test for Pascal's identity
for n in range(1, 100):
for k in range(1, n):
self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))

# Test corner cases
for n in range(100):
self.assertEqual(comb(n, 0), 1)
self.assertEqual(comb(n, n), 1)

for n in range(1, 100):
self.assertEqual(comb(n, 1), n)
self.assertEqual(comb(n, n - 1), n)

# Test Symmetry
for n in range(100):
for k in range(n // 2):
self.assertEqual(comb(n, k), comb(n, n - k))

# Raises TypeError if any argument is non-integer or argument count is
# not 2
self.assertRaises(TypeError, comb, 10, 1.0)
self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
self.assertRaises(TypeError, comb, 10, "1")
self.assertRaises(TypeError, comb, 10.0, 1)
self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
self.assertRaises(TypeError, comb, "10", 1)

self.assertRaises(TypeError, comb, 10)
self.assertRaises(TypeError, comb, 10, 1, 3)
self.assertRaises(TypeError, comb)

# Raises Value error if not k or n are negative numbers
self.assertRaises(ValueError, comb, -1, 1)
self.assertRaises(ValueError, comb, -2**1000, 1)
self.assertRaises(ValueError, comb, 1, -1)
self.assertRaises(ValueError, comb, 1, -2**1000)

# Returns zero if k is greater than n
self.assertEqual(comb(1, 2), 0)
self.assertEqual(comb(1, 2**1000), 0)

n = 2**1000
self.assertEqual(comb(n, 0), 1)
self.assertEqual(comb(n, 1), n)
self.assertEqual(comb(n, 2), n * (n-1) // 2)
self.assertEqual(comb(n, n), 1)
self.assertEqual(comb(n, n-1), n)
self.assertEqual(comb(n, n-2), n * (n-1) // 2)
if support.check_impl_detail(cpython=True):
self.assertRaises(OverflowError, comb, n, n//2)

for n, k in (True, True), (True, False), (False, False):
self.assertEqual(comb(n, k), 1)
self.assertIs(type(comb(n, k)), int)
self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
for k in range(3):
self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)


def test_main():
from doctest import DocFileSuite
Expand Down
@@ -0,0 +1,2 @@
Write accurate compression level metadata in :mod:`gzip` archives, rather
than always signaling maximum compression.

0 comments on commit 5f08b9d

Please sign in to comment.