Skip to content

Commit

Permalink
Drop Python <3.7 support for tests; fully type hint tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jonded94 committed Aug 7, 2024
1 parent edacda4 commit d07a122
Showing 1 changed file with 38 additions and 42 deletions.
80 changes: 38 additions & 42 deletions test/test_crc32c.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@

import os
import struct
import sys
import unittest
import warnings

from typing import Any, Generator

try:
import crc32c
sw_mode = os.environ.get('CRC32C_SW_MODE')
Expand All @@ -34,57 +35,47 @@
elif sw_mode == 'force' and crc32c.hardware_based:
raise RuntimeError('"force" should force software support')
except ImportError:
crc32c = None
crc32c = None # type: ignore[assignment]


def ulonglong_as_bytes(x):
def ulonglong_as_bytes(x: int) -> bytes:
return struct.pack('<Q', x)
def uint_as_bytes(x):


def uint_as_bytes(x: int) -> bytes:
return struct.pack('<I', x)
def ushort_as_bytes(x):


def ushort_as_bytes(x: int) -> bytes:
return struct.pack('<H', x)
def uchar_as_bytes(c):


def uchar_as_bytes(c: int) -> bytes:
return struct.pack('<B', c)

def batched(x, size):

def batched(x: bytes, size: int) -> Generator[bytes, None, None]:
length = len(x)
for i in range(0, length, size):
yield x[i: min(i + size, length)]

if sys.version_info[0] == 2:
def as_individual_bytes(x):
return x
else:
def as_individual_bytes(x):
for b in x:
yield bytes([b])

class warning_catcher(object):
'''Encapsulates proper warning catch-all logic in python 2.7 and 3'''

def __init__(self):
self.catcher = warnings.catch_warnings(record=True)

def __enter__(self):
ret = self.catcher.__enter__()
if sys.version_info[0] == 2:
warnings.simplefilter("always")
return ret

def __exit__(self, *args):
self.catcher.__exit__(*args)
def as_individual_bytes(x: bytes) -> Generator[bytes, None, None]:
for b in x:
yield bytes([b])


@unittest.skipIf(crc32c is None, 'no crc32c support in this platform')
class TestMisc(unittest.TestCase):

def test_zero(self):
def test_zero(self) -> None:
self.assertEqual(0, crc32c.crc32c(b''))

def test_keyword(self):
def test_keyword(self) -> None:
self.assertEqual(10, crc32c.crc32c(b'', value=10))

def test_gil_behaviour(self):
def _test(data):
def test_gil_behaviour(self) -> None:
def _test(data: bytes) -> None:
expected = crc32c.crc32c(data)
self.assertEqual(crc32c.crc32c(data, gil_release_mode=-1), expected)
self.assertEqual(crc32c.crc32c(data, gil_release_mode=0), expected)
Expand All @@ -93,21 +84,22 @@ def _test(data):
_test(b'this_doesnt_release_the_gil_by_default')
_test(b'this_releases_the_gil_by_default' * 1024 * 1024)

def test_crc32_deprecated(self):
with warning_catcher() as warns:
def test_crc32_deprecated(self) -> None:
with warnings.catch_warnings(record=True) as warns:
crc32c.crc32(b'')
self.assertEqual(len(warns), 1)
with warning_catcher() as warns:
with warnings.catch_warnings(record=True) as warns:
crc32c.crc32c(b'')
self.assertEqual(len(warns), 0)


def test_msvc_examples(self):
def test_msvc_examples(self) -> None:
# Examples taken from MSVC's online examples.
# Values are not xor'd in the examples though, so we do it here
max32 = 0xffffffff
def assert_msvc_vals(b, crc, expected_crc):

def assert_msvc_vals(b: bytes, crc: int, expected_crc: int) -> None:
self.assertEqual(expected_crc ^ max32, crc32c.crc32c(b, crc ^ max32))

assert_msvc_vals(uchar_as_bytes(100), 1, 1412925310)
assert_msvc_vals(ushort_as_bytes(1000), 1, 3870914500)
assert_msvc_vals(uint_as_bytes(50000), 1, 971731851)
Expand All @@ -128,24 +120,28 @@ def assert_msvc_vals(b, crc, expected_crc):


class Crc32cChecks(object):
checksum: int
val: bytes

def assertEqual(self, a: Any, b: Any, msg: Any = None) -> None: ...

def test_all(self):
def test_all(self) -> None:
self.assertEqual(self.checksum, crc32c.crc32c(self.val))

def test_piece_by_piece(self):
def test_piece_by_piece(self) -> None:
c = 0
for x in as_individual_bytes(self.val):
c = crc32c.crc32c(x, c)
self.assertEqual(self.checksum, c)

def test_by_different_chunk_lenghts(self):
def test_by_different_chunk_lenghts(self) -> None:
for chunk_size in range(1, 33):
c = 0
for chunk in batched(self.val, chunk_size):
c = crc32c.crc32c(bytes(chunk), c)
self.assertEqual(self.checksum, c)

def test_by_different_memory_offsets(self):
def test_by_different_memory_offsets(self) -> None:
for offset in range(16):
val = memoryview(self.val)
c = crc32c.crc32c(val[0:offset])
Expand Down

0 comments on commit d07a122

Please sign in to comment.