arxify's picture
Upload folder using huggingface_hub
ba2f5d6
raw
history blame contribute delete
161 kB
"""
Tests for bitarray
Author: Ilan Schnell
"""
from __future__ import absolute_import
import re
import os
import sys
import platform
import unittest
import shutil
import tempfile
from random import randint
# imports needed inside tests
import array
import copy
import itertools
import mmap
import pickle
import shelve
import weakref
is_py3k = bool(sys.version_info[0] == 3)
pyodide = bool(platform.machine() == 'wasm32')
if is_py3k:
from io import BytesIO
else:
from cStringIO import StringIO as BytesIO # type: ignore
range = xrange # type: ignore
from bitarray import (bitarray, frozenbitarray, bits2bytes, decodetree,
get_default_endian, _set_default_endian,
_sysinfo, __version__)
def skipIf(condition):
"Skip a test if the condition is true."
if condition:
return lambda f: None
return lambda f: f
SYSINFO = _sysinfo()
DEBUG = SYSINFO[6]
def buffer_info(a, key=None):
fields = (
"address", # 0. address of byte buffer
"size", # 1. buffer size in bytes
"endian", # 2. bit endianness
"padding", # 3. number of pad bits
"allocated", # 4. allocated memory
"readonly", # 5. memory is read-only
"imported", # 6. buffer is imported
"exports", # 7. number of buffer exports
)
info = a.buffer_info()
res = dict(zip(fields, info))
return res if key is None else res[key]
# avoid importing from bitarray.util
def zeros(n, endian=None):
a = bitarray(n, endian or get_default_endian())
a.setall(0)
return a
def urandom(n, endian=None):
a = bitarray(0, endian or get_default_endian())
a.frombytes(os.urandom(bits2bytes(n)))
del a[n:]
return a
tests = [] # type: list
class Util(object):
@staticmethod
def random_endian():
return ['little', 'big'][randint(0, 1)]
@staticmethod
def randombitarrays(start=0):
for n in list(range(start, 25)) + [randint(1000, 2000)]:
a = bitarray(endian=['little', 'big'][randint(0, 1)])
a.frombytes(os.urandom(bits2bytes(n)))
del a[n:]
yield a
def randomlists(self):
for a in self.randombitarrays():
yield a.tolist()
@staticmethod
def rndsliceidx(length):
if randint(0, 1):
return None
else:
return randint(-length - 5, length + 5)
@staticmethod
def other_endian(endian):
t = {'little': 'big',
'big': 'little'}
return t[endian]
@staticmethod
def calc_slicelength(s, length):
assert isinstance(s, slice)
start, stop, step = s.indices(length)
assert step < 0 or (start >= 0 and stop >= 0)
assert step > 0 or (start >= -1 and stop >= -1)
# This implementation works because Python's floor division (a // b)
# always rounds to the lowest integer, even when a or b are negative.
res1 = (stop - start + (1 if step < 0 else -1)) // step + 1
if res1 < 0:
res1 = 0
# The above implementation is not used in C.
# In C's a / b, if either a or b is negative, the result depends on
# the compiler. Therefore, we use the implementation below (where
# both a and b are always positive).
res2 = 0
if step < 0:
if stop < start:
res2 = (start - stop - 1) // (-step) + 1
else:
if start < stop:
res2 = (stop - start - 1) // step + 1
assert res1 == res2
return res1
def check_obj(self, a):
self.assertIsInstance(a, bitarray)
ptr, size, endian, unused, alloc, readonly, buf, exports = \
a.buffer_info()
self.assertEqual(size, bits2bytes(len(a)))
self.assertEqual(unused, 8 * size - len(a))
self.assertTrue(0 <= unused < 8)
self.assertEqual(endian, a.endian())
self.assertTrue(endian in ('little', 'big'))
if buf:
# imported buffer implies that no extra memory is allocated
self.assertEqual(alloc, 0)
# an imported buffer will always have a multiple of 8 bits
self.assertEqual(len(a) % 8, 0)
self.assertEqual(len(a), 8 * size)
self.assertEqual(unused, 0)
else:
# the allocated memory is always larger than the buffer size
self.assertTrue(alloc >= size)
if ptr == 0:
# the buffer being a NULL pointer implies that the buffer size
# and the allocated memory size are 0
self.assertEqual(size, 0)
self.assertEqual(alloc, 0)
if type(a).__name__ == 'frozenbitarray':
# frozenbitarray have read-only memory
self.assertEqual(readonly, 1)
elif not buf:
# otherwise, unless the buffer is imported, it is writable
self.assertEqual(readonly, 0)
def assertEQUAL(self, a, b):
self.assertEqual(a, b)
self.assertEqual(a.endian(), b.endian())
def assertIsType(self, a, b):
self.assertEqual(type(a).__name__, b)
self.assertEqual(
repr(type(a)), "<%s 'bitarray.%s'>" %
('class' if is_py3k or b == 'frozenbitarray' else 'type', b))
def assertBitEqual(self, x, y):
for z in x, y:
self.assertEqual('01'[z], repr(z))
self.assertEqual(x, y)
def assertStopIteration(self, it):
self.assertRaises(StopIteration, next, it)
def assertRaisesMessage(self, excClass, msg, callable, *args, **kwargs):
try:
callable(*args, **kwargs)
raise AssertionError("%s not raised" % excClass.__name__)
except excClass as e:
if msg != str(e):
raise AssertionError("message: %s\n got: %s" % (msg, e))
# ---------------------------------------------------------------------------
class TestsModuleFunctions(unittest.TestCase, Util):
def test_version_string(self):
# the version string is not a function, but test it here anyway
self.assertIsInstance(__version__, str)
def test_sysinfo(self):
info = _sysinfo()
self.assertIsInstance(info, tuple)
for x in info:
self.assertIsInstance(x, int)
def test_set_default_endian(self):
self.assertRaises(TypeError, _set_default_endian, 0)
self.assertRaises(TypeError, _set_default_endian, 'little', 0)
self.assertRaises(ValueError, _set_default_endian, 'foo')
for default_endian in 'big', 'little', u'big', u'little':
_set_default_endian(default_endian)
a = bitarray()
self.assertEqual(a.endian(), default_endian)
for x in None, 0, 64, '10111', [1, 0]:
a = bitarray(x)
self.assertEqual(a.endian(), default_endian)
for endian in 'big', 'little':
a = bitarray(endian=endian)
self.assertEqual(a.endian(), endian)
# make sure that calling _set_default_endian wrong does not
# change the default endianness
self.assertRaises(ValueError, _set_default_endian, 'foobar')
self.assertEqual(bitarray().endian(), default_endian)
def test_get_default_endian(self):
# takes no arguments
self.assertRaises(TypeError, get_default_endian, 'big')
for default_endian in 'big', 'little':
_set_default_endian(default_endian)
endian = get_default_endian()
self.assertEqual(endian, default_endian)
self.assertIsInstance(endian, str)
def test_bits2bytes(self):
for arg in 'foo', [], None, {}, 187.0, -4.0:
self.assertRaises(TypeError, bits2bytes, arg)
self.assertRaises(TypeError, bits2bytes)
self.assertRaises(TypeError, bits2bytes, 1, 2)
self.assertRaises(ValueError, bits2bytes, -1)
self.assertRaises(ValueError, bits2bytes, -924)
self.assertEqual(bits2bytes(0), 0)
for n in range(1, 100):
m = bits2bytes(n)
self.assertEqual(m, (n - 1) // 8 + 1)
self.assertIsInstance(m, int)
for n, m in [(0, 0), (1, 1), (2, 1), (7, 1), (8, 1), (9, 2),
(10, 2), (15, 2), (16, 2), (64, 8), (65, 9),
(2**31, 2**28), (2**32, 2**29), (2**34, 2**31),
(2**34+793, 2**31+100), (2**35-8, 2**32-1),
(2**62, 2**59), (2**63-8, 2**60-1)]:
self.assertEqual(bits2bytes(n), m)
tests.append(TestsModuleFunctions)
# ---------------------------------------------------------------------------
class CreateObjectTests(unittest.TestCase, Util):
def test_noInitializer(self):
a = bitarray()
self.assertEqual(len(a), 0)
self.assertEqual(a.tolist(), [])
self.assertIsType(a, 'bitarray')
self.check_obj(a)
def test_endian(self):
a = bitarray(endian='little')
a.frombytes(b'ABC')
self.assertEqual(a.endian(), 'little')
self.assertIsInstance(a.endian(), str)
self.check_obj(a)
b = bitarray(endian='big')
b.frombytes(b'ABC')
self.assertEqual(b.endian(), 'big')
self.assertIsInstance(a.endian(), str)
self.check_obj(b)
self.assertNotEqual(a, b)
self.assertEqual(a.tobytes(), b.tobytes())
def test_endian_default(self):
_set_default_endian('big')
a_big = bitarray()
_set_default_endian('little')
a_little = bitarray()
_set_default_endian('big')
self.assertEqual(a_big.endian(), 'big')
self.assertEqual(a_little.endian(), 'little')
def test_endian_wrong(self):
self.assertRaises(TypeError, bitarray, endian=0)
self.assertRaises(ValueError, bitarray, endian='')
self.assertRaisesMessage(
ValueError,
"bit endianness must be either 'little' or 'big', not 'foo'",
bitarray, endian='foo')
self.assertRaisesMessage(TypeError,
"'ellipsis' object is not iterable",
bitarray, Ellipsis)
def test_buffer(self):
# buffer requires no initial argument
self.assertRaises(TypeError, bitarray, 5, buffer=b'DATA\0')
for endian in 'big', 'little':
a = bitarray(buffer=b'', endian=endian)
self.assertEQUAL(a, bitarray(0, endian))
_set_default_endian(endian)
a = bitarray(buffer=b'A')
self.assertEqual(a.endian(), endian)
self.assertEqual(len(a), 8)
a = bitarray(buffer=b'\xf0', endian='little')
self.assertRaises(TypeError, a.clear)
self.assertRaises(TypeError, a.__setitem__, 3, 1)
self.assertEQUAL(a, bitarray('00001111', 'little'))
self.check_obj(a)
# positinal arguments
a = bitarray(None, 'big', bytearray([15]))
self.assertEQUAL(a, bitarray('00001111', 'big'))
a = bitarray(None, 'little', None)
self.assertEQUAL(a, bitarray(0, 'little'))
def test_integers(self):
for n in range(50):
a = bitarray(n)
self.assertEqual(len(a), n)
self.check_obj(a)
a = bitarray(int(n))
self.assertEqual(len(a), n)
self.check_obj(a)
if not is_py3k:
a = bitarray(long(29))
self.assertEqual(len(a), 29)
self.assertRaises(ValueError, bitarray, -1)
self.assertRaises(ValueError, bitarray, -924)
def test_list(self):
lst = [0, 1, False, True]
a = bitarray(lst)
self.assertEqual(a, bitarray('0101'))
self.check_obj(a)
if not is_py3k:
a = bitarray([long(1), long(0)])
self.assertEqual(a, bitarray('10'))
self.assertRaises(ValueError, bitarray, [0, 1, 2])
self.assertRaises(TypeError, bitarray, [0, 1, None])
for n in range(50):
lst = [bool(randint(0, 1)) for d in range(n)]
a = bitarray(lst)
self.assertEqual(a.tolist(), lst)
self.check_obj(a)
def test_tuple(self):
tup = (0, True, False, 1)
a = bitarray(tup)
self.assertEqual(a, bitarray('0101'))
self.check_obj(a)
self.assertRaises(ValueError, bitarray, (0, 1, 2))
self.assertRaises(TypeError, bitarray, (0, 1, None))
for n in range(50):
lst = [bool(randint(0, 1)) for d in range(n)]
a = bitarray(tuple(lst))
self.assertEqual(a.tolist(), lst)
self.check_obj(a)
def test_iter1(self):
for n in range(50):
lst = [bool(randint(0, 1)) for d in range(n)]
a = bitarray(iter(lst))
self.assertEqual(a.tolist(), lst)
self.check_obj(a)
def test_iter2(self):
for lst in self.randomlists():
def foo():
for x in lst:
yield x
a = bitarray(foo())
self.assertEqual(a, bitarray(lst))
self.check_obj(a)
def test_iter3(self):
a = bitarray(itertools.repeat(False, 10))
self.assertEqual(a, zeros(10))
a = bitarray(itertools.repeat(1, 10))
self.assertEqual(a, bitarray(10 * '1'))
def test_range(self):
self.assertEqual(bitarray(range(2)), bitarray('01'))
self.assertRaises(ValueError, bitarray, range(0, 3))
def test_string01(self):
for s in ('0010111', u'0010111', '0010 111', u'0010 111',
'0010_111', u'0010_111'):
a = bitarray(s)
self.assertEqual(a.tolist(), [0, 0, 1, 0, 1, 1, 1])
self.check_obj(a)
for n in range(50):
lst = [bool(randint(0, 1)) for d in range(n)]
s = ''.join([['0', '1'][x] for x in lst])
a = bitarray(s)
self.assertEqual(a.tolist(), lst)
self.check_obj(a)
self.assertRaises(ValueError, bitarray, '01021')
self.assertRaises(UnicodeEncodeError, bitarray, u'1\u26050')
def test_string01_whitespace(self):
whitespace = ' \n\r\t\v'
a = bitarray(whitespace)
self.assertEqual(a, bitarray())
# For Python 2 (where strings are bytes), we are in the lucky
# position that none of the valid characters ('\t'=9, '\n'=10,
# '\v'=11, '\r'=13, ' '=32, '0'=48 and '1'=49) are valid header
# bytes for deserialization 0..7, 16..23. Therefore a string of
# '0's and '1'a can start with any whitespace character, as well
# as '0' or '1' obviously.
for c in whitespace:
a = bitarray(c + '1101110001')
self.assertEqual(a, bitarray('1101110001'))
a = bitarray(' 0\n1\r0\t1\v0 ')
self.assertEqual(a, bitarray('01010'))
def test_rawbytes(self):
self.assertEqual(bitarray(b'\x00').endian(), 'little')
self.assertEqual(bitarray(b'\x10').endian(), 'big')
# this representation is used for pickling
for s, r in [(b'\x00', ''), (b'\x07\xff', '1'), (b'\x03\xff', '11111'),
(b'\x01\x87\xda', '10000111 1101101')]:
self.assertEqual(bitarray(s, endian='big'), bitarray(r))
self.assertEQUAL(bitarray(b'\x12\x0f', 'little'),
bitarray('111100', 'little'))
self.assertEQUAL(bitarray(b'\x02\x0f', 'big'),
bitarray('000011', 'big'))
for a, s in [
(bitarray(0, 'little'), b'\x00'),
(bitarray(0, 'big'), b'\x10'),
(bitarray('1', 'little'), b'\x07\x01'),
(bitarray('1', 'big'), b'\x17\x80'),
(bitarray('11110000', 'little'), b'\x00\x0f'),
(bitarray('11110000', 'big'), b'\x10\xf0'),
]:
self.assertEQUAL(bitarray(s), a)
def test_rawbytes_invalid(self):
for s in b'\x01', b'\x04', b'\x07', b'\x11', b'\x15', b'\x17':
# this error is raised in newbitarray_from_pickle() (C function)
self.assertRaises(ValueError, bitarray, s)
# Python 2: PyErr_Format() seems to handle "0x%02x"
# incorrectly. E.g. instead of "0x01", I get "0x1"
if is_py3k:
msg = "invalid header byte: 0x%02x" % s[0]
self.assertRaisesMessage(ValueError, msg, bitarray, s)
a = bitarray(s + b'\x00')
head = s[0] if is_py3k else ord(s[0])
endian, unused = divmod(head, 16)
self.assertEqual(a.endian(), ['little', 'big'][endian])
self.assertEqual(len(a), 8 - unused)
self.assertFalse(a.any())
s = b'\x21'
if is_py3k:
# on Python 3, we don't allow bitarrays being created from bytes
error = TypeError
msg = ("cannot extend bitarray with 'bytes', use .pack() or "
".frombytes() instead")
else:
# on Python 2, we have an invalid character in the string
error = ValueError
msg = ("expected '0' or '1' (or whitespace, or underscore), "
"got '!' (0x21)")
self.assertRaisesMessage(error, msg, bitarray, s)
def test_bitarray_simple(self):
for n in range(10):
a = bitarray(n)
b = bitarray(a)
self.assertFalse(a is b)
self.assertEQUAL(a, b)
def test_bitarray_endian(self):
# Test creating a new bitarray with different endianness from an
# existing bitarray.
for endian in 'little', 'big':
a = bitarray(endian=endian)
b = bitarray(a)
self.assertFalse(a is b)
self.assertEQUAL(a, b)
endian2 = self.other_endian(endian)
b = bitarray(a, endian2)
self.assertEqual(b.endian(), endian2)
self.assertEqual(a, b)
for a in self.randombitarrays():
endian2 = self.other_endian(a.endian())
b = bitarray(a, endian2)
self.assertEqual(a, b)
self.assertEqual(b.endian(), endian2)
self.assertNotEqual(a.endian(), b.endian())
def test_bitarray_endianness(self):
a = bitarray('11100001', endian='little')
b = bitarray(a, endian='big')
self.assertEqual(a, b)
self.assertNotEqual(a.tobytes(), b.tobytes())
b.bytereverse()
self.assertNotEqual(a, b)
self.assertEqual(a.tobytes(), b.tobytes())
c = bitarray('11100001', endian='big')
self.assertEqual(a, c)
def test_frozenbitarray(self):
a = bitarray(frozenbitarray())
self.assertEQUAL(a, bitarray())
self.assertIsType(a, 'bitarray')
for endian in 'little', 'big':
a = bitarray(frozenbitarray('011', endian=endian))
self.assertEQUAL(a, bitarray('011', endian))
self.assertIsType(a, 'bitarray')
def test_create_empty(self):
for x in (None, 0, '', list(), tuple(), set(), dict(), u'',
bitarray(), frozenbitarray()):
a = bitarray(x)
self.assertEqual(len(a), 0)
self.assertEQUAL(a, bitarray())
if is_py3k:
self.assertRaises(TypeError, bitarray, b'')
else:
self.assertEqual(bitarray(b''), bitarray())
def test_wrong_args(self):
# wrong types
for x in False, True, Ellipsis, slice(0), 0.0, 0 + 0j:
self.assertRaises(TypeError, bitarray, x)
if is_py3k:
self.assertRaises(TypeError, bitarray, b'10')
else:
self.assertEQUAL(bitarray(b'10'), bitarray('10'))
# wrong values
for x in -1, 'A':
self.assertRaises(ValueError, bitarray, x)
# test second (endian) argument
self.assertRaises(TypeError, bitarray, 0, None)
self.assertRaises(TypeError, bitarray, 0, 0)
self.assertRaises(ValueError, bitarray, 0, 'foo')
# too many args
self.assertRaises(TypeError, bitarray, 0, 'big', 0)
def test_weakref(self):
a = bitarray('0100')
b = weakref.proxy(a)
self.assertEqual(b.to01(), a.to01())
a = None
self.assertRaises(ReferenceError, len, b)
tests.append(CreateObjectTests)
# ---------------------------------------------------------------------------
class ToObjectsTests(unittest.TestCase, Util):
def test_numeric(self):
a = bitarray()
self.assertRaises(Exception, int, a)
self.assertRaises(Exception, float, a)
self.assertRaises(Exception, complex, a)
def test_list(self):
for a in self.randombitarrays():
self.assertEqual(list(a), a.tolist())
def test_tuple(self):
for a in self.randombitarrays():
self.assertEqual(tuple(a), tuple(a.tolist()))
tests.append(ToObjectsTests)
# ---------------------------------------------------------------------------
class MetaDataTests(unittest.TestCase):
def test_buffer_info(self):
a = bitarray(13, endian='little')
self.assertEqual(a.buffer_info()[1:4], (2, 'little', 3))
info = a.buffer_info()
self.assertIsInstance(info, tuple)
self.assertEqual(len(info), 8)
for i, item in enumerate(info):
if i == 2:
self.assertIsInstance(item, str)
continue
self.assertIsInstance(item, int)
def test_endian(self):
for endian in 'big', 'little':
a = bitarray(endian=endian)
self.assertEqual(a.endian(), endian)
def test_len(self):
for n in range(100):
a = bitarray(n)
self.assertEqual(len(a), n)
tests.append(MetaDataTests)
# ---------------------------------------------------------------------------
class InternalTests(unittest.TestCase, Util):
# Internal functionality exposed for the purpose of testing.
# This class will only be part of the test suite in debug mode.
def test_shift_r8_empty(self):
a = bitarray()
a._shift_r8(0, 0, 3)
self.assertEqual(a, bitarray())
a = urandom(80)
for i in range(11):
b = a.copy()
a._shift_r8(i, i, 5)
self.assertEqual(a, b)
def test_shift_r8_explicit(self):
x = bitarray('11000100 11111111 11100111 11111111 00001000')
y = bitarray('11000100 00000111 11111111 00111111 00001000')
x._shift_r8(1, 4, 5)
self.assertEqual(x, y)
x = bitarray('11000100 11110')
y = bitarray('00011000 10011')
x._shift_r8(0, 2, 3)
self.assertEqual(x, y)
def test_shift_r8_random_bytes(self):
for N in range(100):
a = randint(0, N)
b = randint(a, N)
n = randint(0, 7)
x = urandom(8 * N, self.random_endian())
y = x.copy()
x._shift_r8(a, b, n)
y[8 * a : 8 * b] >>= n
self.assertEQUAL(x, y)
self.assertEqual(len(x), 8 * N)
def test_copy_n_explicit(self):
x = bitarray('11000100 11110')
# ^^^^ ^
y = bitarray('0101110001')
# ^^^^^
x._copy_n(4, y, 1, 5)
self.assertEqual(x, bitarray('11001011 11110'))
# ^^^^ ^
x = bitarray('10110111 101', 'little')
y = x.copy()
x._copy_n(3, x, 3, 7) # copy region of x onto x
self.assertEqual(x, y)
x._copy_n(3, bitarray(x, 'big'), 3, 7) # as before but other endian
self.assertEqual(x, y)
x._copy_n(5, bitarray(), 0, 0) # copy empty bitarray onto x
self.assertEqual(x, y)
def test_copy_n_example(self):
# example givin in bitarray/copy_n.txt
y = bitarray(
'00101110 11111001 01011101 11001011 10110000 01011110 011')
x = bitarray(
'01011101 11100101 01110101 01011001 01110100 10001010 01111011')
x._copy_n(21, y, 6, 31)
self.assertEqual(x, bitarray(
'01011101 11100101 01110101 11110010 10111011 10010111 01101011'))
def check_copy_n(self, N, M, a, b, n):
x = urandom(N, self.random_endian())
x_lst = x.tolist()
y = x if M < 0 else urandom(M, self.random_endian())
x_lst[a:a + n] = y.tolist()[b:b + n]
x._copy_n(a, y, b, n)
self.assertEqual(x, bitarray(x_lst))
self.assertEqual(len(x), N)
self.check_obj(x)
def test_copy_n_range(self):
for a in range(8):
for b in range(8):
for n in range(90):
self.check_copy_n(100, -1, a, b, n)
self.check_copy_n(100, 100, a, b, n)
def test_copy_n_random_self(self):
for N in range(500):
n = randint(0, N)
a = randint(0, N - n)
b = randint(0, N - n)
self.check_copy_n(N, -1, a, b, n)
def test_copy_n_random_other(self):
for N in range(500):
M = randint(0, 5 + 2 * N)
n = randint(0, min(N, M))
a = randint(0, N - n)
b = randint(0, M - n)
self.check_copy_n(N, M, a, b, n)
@staticmethod
def getslice(a, start, slicelength):
# this is the Python eqivalent of __getitem__ for slices with step=1
b = bitarray(slicelength, a.endian())
b._copy_n(0, a, start, slicelength)
return b
def test_getslice(self):
for a in self.randombitarrays():
a_lst = a.tolist()
n = len(a)
i = randint(0, n)
j = randint(i, n)
b = self.getslice(a, i, j - i)
self.assertEqual(b.tolist(), a_lst[i:j])
self.assertEQUAL(b, a[i:j])
def check_overlap(self, a, b, res):
r1 = a._overlap(b)
r2 = b._overlap(a)
self.assertIsInstance(r1, bool)
self.assertTrue(r1 == r2 == res)
self.check_obj(a)
self.check_obj(b)
def test_overlap_empty(self):
a = bitarray()
self.check_overlap(a, a, False)
b = bitarray()
self.check_overlap(a, b, False)
def test_overlap_distinct(self):
for a in self.randombitarrays():
# buffers overlaps with itself, unless buffer is NULL
self.check_overlap(a, a, bool(a))
b = a.copy()
self.check_overlap(a, b, False)
def test_overlap_shared(self):
a = bitarray(64)
b = bitarray(buffer=a)
self.check_overlap(b, a, True)
c = bitarray(buffer=memoryview(a)[2:4])
self.check_overlap(c, a, True)
d = bitarray(buffer=memoryview(a)[5:])
self.check_overlap(d, c, False)
self.check_overlap(d, b, True)
e = bitarray(buffer=memoryview(a)[3:3])
self.check_overlap(e, c, False)
self.check_overlap(e, d, False)
def test_overlap_shared_random(self):
n = 100 # buffer size in bytes
a = bitarray(8 * n)
for _ in range(1000):
i1 = randint(0, n)
j1 = randint(0, n)
if j1 < i1:
continue
i2 = randint(0, n)
j2 = randint(0, n)
if j2 < i2:
continue
b1 = bitarray(buffer=memoryview(a)[i1:j1])
b2 = bitarray(buffer=memoryview(a)[i2:j2])
x1 = zeros(n)
x2 = zeros(n)
x1[i1:j1] = 1
x2[i2:j2] = 1
self.check_overlap(b1, b2, (x1 & x2).any())
if DEBUG:
tests.append(InternalTests)
# ---------------------------------------------------------------------------
class SliceTests(unittest.TestCase, Util):
def test_getitem_1(self):
a = bitarray()
self.assertRaises(IndexError, a.__getitem__, 0)
a.append(True)
self.assertBitEqual(a[0], 1)
self.assertBitEqual(a[-1], 1)
self.assertRaises(IndexError, a.__getitem__, 1)
self.assertRaises(IndexError, a.__getitem__, -2)
a.append(False)
self.assertBitEqual(a[1], 0)
self.assertBitEqual(a[-1], 0)
self.assertRaises(IndexError, a.__getitem__, 2)
self.assertRaises(IndexError, a.__getitem__, -3)
self.assertRaises(TypeError, a.__getitem__, 1.5)
self.assertRaises(TypeError, a.__getitem__, None)
self.assertRaises(TypeError, a.__getitem__, 'A')
def test_getitem_2(self):
a = bitarray('1100010')
for i, b in enumerate(a):
self.assertBitEqual(a[i], b)
self.assertBitEqual(a[i - 7], b)
self.assertRaises(IndexError, a.__getitem__, 7)
self.assertRaises(IndexError, a.__getitem__, -8)
def test_getslice(self):
a = bitarray('01001111 00001')
self.assertEQUAL(a[:], a)
self.assertFalse(a[:] is a)
self.assertEQUAL(a[13:2:-3], bitarray('1010'))
self.assertEQUAL(a[2:-1:4], bitarray('010'))
self.assertEQUAL(a[::2], bitarray('0011001'))
self.assertEQUAL(a[8:], bitarray('00001'))
self.assertEQUAL(a[7:], bitarray('100001'))
self.assertEQUAL(a[:8], bitarray('01001111'))
self.assertEQUAL(a[::-1], bitarray('10000111 10010'))
self.assertEQUAL(a[:8:-1], bitarray('1000'))
self.assertRaises(ValueError, a.__getitem__, slice(None, None, 0))
self.assertRaises(TypeError, a.__getitem__, (1, 2))
def test_getslice_random(self):
for a in self.randombitarrays(start=1):
aa = a.tolist()
la = len(a)
for _ in range(10):
step = self.rndsliceidx(la) or None
s = slice(self.rndsliceidx(la), self.rndsliceidx(la), step)
self.assertEQUAL(a[s], bitarray(aa[s], endian=a.endian()))
def test_getslice_random2(self):
n = randint(1000, 2000)
a = urandom(n, self.random_endian())
sa = a.to01()
for _ in range(50):
i = randint(0, n)
j = randint(i, n)
b = a[i:j]
self.assertEqual(b.to01(), sa[i:j])
self.assertEqual(len(b), j - i)
self.assertEqual(b.endian(), a.endian())
def test_setitem_simple(self):
a = bitarray('0')
a[0] = 1
self.assertEqual(a, bitarray('1'))
a = bitarray(2)
a[0] = 0
a[1] = 1
self.assertEqual(a, bitarray('01'))
a[-1] = 0
a[-2] = 1
self.assertEqual(a, bitarray('10'))
self.assertRaises(ValueError, a.__setitem__, 0, -1)
self.assertRaises(TypeError, a.__setitem__, 1, None)
self.assertRaises(IndexError, a.__setitem__, 2, True)
self.assertRaises(IndexError, a.__setitem__, -3, False)
self.assertRaises(TypeError, a.__setitem__, 1.5, 1) # see issue 114
self.assertRaises(TypeError, a.__setitem__, None, 0)
self.assertRaises(TypeError, a.__setitem__, 'a', True)
self.assertEqual(a, bitarray('10'))
def test_setitem_random(self):
for a in self.randombitarrays(start=1):
i = randint(0, len(a) - 1)
aa = a.tolist()
val = bool(randint(0, 1))
a[i] = val
aa[i] = val
self.assertEqual(a.tolist(), aa)
self.check_obj(a)
def test_setslice_simple(self):
for a in self.randombitarrays(start=1):
la = len(a)
b = bitarray(la)
b[0:la] = bitarray(a)
self.assertEqual(a, b)
self.assertFalse(a is b)
b = bitarray(la)
b[:] = bitarray(a)
self.assertEqual(a, b)
self.assertFalse(a is b)
b = bitarray(la)
b[::-1] = bitarray(a)
self.assertEqual(a.tolist()[::-1], b.tolist())
def test_setslice_random(self):
for a in self.randombitarrays(start=1):
la = len(a)
for _ in range(10):
step = self.rndsliceidx(la) or None
s = slice(self.rndsliceidx(la), self.rndsliceidx(la), step)
lb = (randint(0, 10) if step is None else
self.calc_slicelength(s, la))
b = bitarray(lb)
c = bitarray(a)
c[s] = b
self.check_obj(c)
cc = a.tolist()
cc[s] = b.tolist()
self.assertEqual(c, bitarray(cc))
def test_setslice_self_random(self):
for a in self.randombitarrays():
for step in -1, 1:
s = slice(None, None, step)
aa = a.tolist()
a[s] = a
aa[s] = aa
self.assertEqual(a, bitarray(aa))
def test_setslice_special(self):
for n in 0, 1, 10, 87:
a = urandom(n)
for m in 0, 1, 10, 99:
x = urandom(m)
b = a.copy()
b[n:n] = x # insert at end - extend
self.assertEqual(b, a + x)
self.assertEqual(len(b), len(a) + len(x))
b[0:0] = x # insert at 0 - prepend
self.assertEqual(b, x + a + x)
self.check_obj(b)
self.assertEqual(len(b), len(a) + 2 * len(x))
def test_setslice_range(self):
# tests C function insert_n()
for endian in 'big', 'little':
for n in range(500):
a = urandom(n, endian)
p = randint(0, n)
m = randint(0, 500)
x = urandom(m, self.random_endian())
b = a.copy()
b[p:p] = x
self.assertEQUAL(b, a[:p] + x + a[p:])
self.assertEqual(len(b), len(a) + m)
self.check_obj(b)
def test_setslice_resize(self):
N, M = 200, 300
for endian in 'big', 'little':
for n in 0, randint(0, N), N:
a = urandom(n, endian)
for p1 in 0, randint(0, n), n:
for p2 in 0, randint(0, p1), p1, randint(0, n), n:
for m in 0, randint(0, M), M:
x = urandom(m, self.random_endian())
b = a.copy()
b[p1:p2] = x
b_lst = a.tolist()
b_lst[p1:p2] = x.tolist()
self.assertEqual(b.tolist(), b_lst)
if p1 <= p2:
self.assertEQUAL(b, a[:p1] + x + a[p2:])
self.assertEqual(len(b), n + p1 - p2 + len(x))
else:
self.assertEqual(b, a[:p1] + x + a[p1:])
self.assertEqual(len(b), n + len(x))
self.check_obj(b)
def test_setslice_self(self):
a = bitarray('1100111')
a[::-1] = a
self.assertEqual(a, bitarray('1110011'))
a[4:] = a
self.assertEqual(a, bitarray('11101110011'))
a[:-5] = a
self.assertEqual(a, bitarray('1110111001110011'))
a = bitarray('01001')
a[:-1] = a
self.assertEqual(a, bitarray('010011'))
a[2::] = a
self.assertEqual(a, bitarray('01010011'))
a[2:-2:1] = a
self.assertEqual(a, bitarray('010101001111'))
a = bitarray('011')
a[2:2] = a
self.assertEqual(a, bitarray('010111'))
a[:] = a
self.assertEqual(a, bitarray('010111'))
def test_setslice_self_shared_buffer(self):
# This is a special case. We have two bitarrays which share the
# same buffer, and then do a slice assignment. The bitarray is
# copied onto itself in reverse order. So we need to make a copy
# in setslice_bitarray(). However, since a and b are two distinct
# objects, it is not enough to check for self == other, but rather
# self->ob_item == other->ob_item.
a = bitarray('11100000')
b = bitarray(buffer=a)
b[::-1] = a
self.assertEqual(a, b)
self.assertEqual(a, bitarray('00000111'))
def test_setslice_self_shared_buffer_2(self):
# This is an even more special case. We have a bitarrays which
# shares part of anothers bitarray buffer. So in setslice_bitarray(),
# we need to make a copy of other if:
#
# self->ob_item <= other->ob_item <= self->ob_item + Py_SIZE(self)
#
# In words: Is the other buffer inside the self buffer (which inclues
# the previous case)
a = bitarray('11111111 11000000 00000000')
b = bitarray(buffer=memoryview(a)[1:2])
self.assertEqual(b, bitarray('11000000'))
a[15:7:-1] = b
self.assertEqual(a, bitarray('11111111 00000011 00000000'))
def test_setslice_self_shared_buffer_3(self):
# Requires to check for (in setslice_bitarray()):
#
# other->ob_item <= self->ob_item <= other->ob_item + Py_SIZE(other)
#
a = bitarray('11111111 11000000 00000000')
b = bitarray(buffer=memoryview(a)[:2])
c = bitarray(buffer=memoryview(a)[1:])
self.assertEqual(b, bitarray('11111111 11000000'))
self.assertEqual(c, bitarray('11000000 00000000'))
c[::-1] = b
self.assertEqual(c, bitarray('00000011 11111111'))
self.assertEqual(a, bitarray('11111111 00000011 11111111'))
def test_setslice_bitarray(self):
a = bitarray('11111111 1111')
a[2:6] = bitarray('0010')
self.assertEqual(a, bitarray('11001011 1111'))
a.setall(0)
a[::2] = bitarray('111001')
self.assertEqual(a, bitarray('10101000 0010'))
a.setall(0)
a[3:] = bitarray('111')
self.assertEqual(a, bitarray('000111'))
a = bitarray(12)
a.setall(0)
a[1:11:2] = bitarray('11101')
self.assertEqual(a, bitarray('01010100 0100'))
a.setall(0)
a[5:2] = bitarray('111') # make sure inserts before 5 (not 2)
self.assertEqual(a, bitarray('00000111 0000000'))
a = bitarray(12)
a.setall(0)
a[:-6:-1] = bitarray('10111')
self.assertEqual(a, bitarray('00000001 1101'))
def test_setslice_bitarray_2(self):
a = bitarray('1111')
a[3:3] = bitarray('000') # insert
self.assertEqual(a, bitarray('1110001'))
a[2:5] = bitarray() # remove
self.assertEqual(a, bitarray('1101'))
a = bitarray('1111')
a[1:3] = bitarray('0000')
self.assertEqual(a, bitarray('100001'))
a[:] = bitarray('010') # replace all values
self.assertEqual(a, bitarray('010'))
# assign slice to bitarray with different length
a = bitarray('111111')
a[3:4] = bitarray('00')
self.assertEqual(a, bitarray('1110011'))
a[2:5] = bitarray('0') # remove
self.assertEqual(a, bitarray('11011'))
def test_setslice_bitarray_random_same_length(self):
for endian in 'little', 'big':
for _ in range(100):
n = randint(0, 200)
a = urandom(n, endian)
lst_a = a.tolist()
b = urandom(randint(0, n), self.random_endian())
lst_b = b.tolist()
i = randint(0, n - len(b))
j = i + len(b)
self.assertEqual(j - i, len(b))
a[i:j] = b
lst_a[i:j] = lst_b
self.assertEqual(a.tolist(), lst_a)
# a didn't change length
self.assertEqual(len(a), n)
self.assertEqual(a.endian(), endian)
self.check_obj(a)
def test_setslice_bitarray_random_step_1(self):
for _ in range(50):
n = randint(0, 300)
a = urandom(n, self.random_endian())
lst_a = a.tolist()
b = urandom(randint(0, 100), self.random_endian())
lst_b = b.tolist()
s = slice(self.rndsliceidx(n), self.rndsliceidx(n), None)
a[s] = b
lst_a[s] = lst_b
self.assertEqual(a.tolist(), lst_a)
self.check_obj(a)
def test_setslice_bitarray_random(self):
for _ in range(100):
n = randint(0, 50)
a = urandom(n, self.random_endian())
lst_a = a.tolist()
b = urandom(randint(0, 50), self.random_endian())
lst_b = b.tolist()
s = slice(self.rndsliceidx(n), self.rndsliceidx(n),
randint(-3, 3) or None)
try:
a[s] = b
except ValueError:
a = None
try:
lst_a[s] = lst_b
except ValueError:
lst_a = None
if a is None:
self.assertTrue(lst_a is None)
else:
self.assertEqual(a.tolist(), lst_a)
self.check_obj(a)
def test_setslice_bool_explicit(self):
a = bitarray('11111111')
a[::2] = False
self.assertEqual(a, bitarray('01010101'))
a[4::] = True # ^^^^
self.assertEqual(a, bitarray('01011111'))
a[-2:] = False # ^^
self.assertEqual(a, bitarray('01011100'))
a[:2:] = True # ^^
self.assertEqual(a, bitarray('11011100'))
a[:] = True # ^^^^^^^^
self.assertEqual(a, bitarray('11111111'))
a[2:5] = False # ^^^
self.assertEqual(a, bitarray('11000111'))
a[1::3] = False # ^ ^ ^
self.assertEqual(a, bitarray('10000110'))
a[1:6:2] = True # ^ ^ ^
self.assertEqual(a, bitarray('11010110'))
a[3:3] = False # zero slicelength
self.assertEqual(a, bitarray('11010110'))
a[:] = False # ^^^^^^^^
self.assertEqual(a, bitarray('00000000'))
a[-2:2:-1] = 1 # ^^^^
self.assertEqual(a, bitarray('00011110'))
def test_setslice_bool_simple(self):
for _ in range(100):
N = randint(100, 2000)
s = slice(randint(0, 20), randint(N - 20, N), randint(1, 20))
a = zeros(N)
a[s] = 1
b = zeros(N)
for i in range(s.start, s.stop, s.step):
b[i] = 1
self.assertEqual(a, b)
def test_setslice_bool_range(self):
N = 200
a = bitarray(N, self.random_endian())
b = bitarray(N)
for step in range(-N - 1, N):
if step == 0:
continue
v = randint(0, 1)
a.setall(not v)
a[::step] = v
b.setall(not v)
for i in range(0, N, abs(step)):
b[i] = v
if step < 0:
b.reverse()
self.assertEqual(a, b)
def test_setslice_bool_random(self):
N = 100
a = bitarray(N)
for _ in range(100):
a.setall(0)
aa = a.tolist()
step = self.rndsliceidx(N) or None
s = slice(self.rndsliceidx(N), self.rndsliceidx(N), step)
a[s] = 1
aa[s] = self.calc_slicelength(s, N) * [1]
self.assertEqual(a.tolist(), aa)
def test_setslice_bool_random2(self):
for a in self.randombitarrays():
n = len(a)
aa = a.tolist()
step = self.rndsliceidx(n) or None
s = slice(self.rndsliceidx(n), self.rndsliceidx(n), step)
v = randint(0, 1)
a[s] = v
aa[s] = self.calc_slicelength(s, n) * [v]
self.assertEqual(a.tolist(), aa)
def test_setslice_to_int(self):
a = bitarray('11111111')
a[::2] = 0 # ^ ^ ^ ^
self.assertEqual(a, bitarray('01010101'))
a[4::] = 1 # ^^^^
self.assertEqual(a, bitarray('01011111'))
a.__setitem__(slice(-2, None, None), 0)
self.assertEqual(a, bitarray('01011100'))
self.assertRaises(ValueError, a.__setitem__, slice(None, None, 2), 3)
self.assertRaises(ValueError, a.__setitem__, slice(None, 2, None), -1)
# a[:2:] = '0'
self.assertRaises(TypeError, a.__setitem__, slice(None, 2, None), '0')
def test_setslice_to_invalid(self):
a = bitarray('11111111')
s = slice(2, 6, None)
self.assertRaises(TypeError, a.__setitem__, s, 1.2)
self.assertRaises(TypeError, a.__setitem__, s, None)
self.assertRaises(TypeError, a.__setitem__, s, "0110")
a[s] = False
self.assertEqual(a, bitarray('11000011'))
# step != 1 and slicelen != length of assigned bitarray
self.assertRaisesMessage(
ValueError,
"attempt to assign sequence of size 3 to extended slice of size 4",
a.__setitem__, slice(None, None, 2), bitarray('000'))
self.assertRaisesMessage(
ValueError,
"attempt to assign sequence of size 3 to extended slice of size 2",
a.__setitem__, slice(None, None, 4), bitarray('000'))
self.assertRaisesMessage(
ValueError,
"attempt to assign sequence of size 7 to extended slice of size 8",
a.__setitem__, slice(None, None, -1), bitarray('0001000'))
self.assertEqual(a, bitarray('11000011'))
def test_delitem_simple(self):
a = bitarray('100110')
del a[1]
self.assertEqual(len(a), 5)
del a[3], a[-2]
self.assertEqual(a, bitarray('100'))
self.assertRaises(IndexError, a.__delitem__, 3)
self.assertRaises(IndexError, a.__delitem__, -4)
def test_delitem_random(self):
for a in self.randombitarrays(start=1):
n = len(a)
b = a.copy()
i = randint(0, n - 1)
del b[i]
self.assertEQUAL(b, a[:i] + a[i + 1:])
self.assertEqual(len(b), n - 1)
self.check_obj(b)
def test_delslice_explicit(self):
a = bitarray('10101100 10110')
del a[3:9] # ^^^^^ ^
self.assertEqual(a, bitarray('1010110'))
del a[::3] # ^ ^ ^
self.assertEqual(a, bitarray('0111'))
a = bitarray('10101100 101101111')
del a[5:-3:3] # ^ ^ ^
self.assertEqual(a, bitarray('1010100 0101111'))
a = bitarray('10101100 1011011')
del a[:-9:-2] # ^ ^ ^ ^
self.assertEqual(a, bitarray('10101100 011'))
del a[3:3] # zero slicelength
self.assertEqual(a, bitarray('10101100 011'))
self.assertRaises(ValueError, a.__delitem__, slice(None, None, 0))
self.assertEqual(len(a), 11)
del a[:]
self.assertEqual(a, bitarray())
def test_delslice_special(self):
for n in 0, 1, 10, 73:
a = urandom(n)
b = a.copy()
del b[:0]
del b[n:]
self.assertEqual(b, a)
del b[10:] # delete at end
self.assertEqual(b, a[:10])
del b[:] # clear
self.assertEqual(len(b), 0)
self.check_obj(b)
def test_delslice_random(self):
for a in self.randombitarrays():
la = len(a)
for _ in range(10):
step = self.rndsliceidx(la) or None
s = slice(self.rndsliceidx(la), self.rndsliceidx(la), step)
c = a.copy()
del c[s]
self.check_obj(c)
c_lst = a.tolist()
del c_lst[s]
self.assertEQUAL(c, bitarray(c_lst, endian=c.endian()))
def test_delslice_range(self):
# tests C function delete_n()
for n in range(500):
a = urandom(n, self.random_endian())
p = randint(0, n)
m = randint(0, 500)
b = a.copy()
del b[p:p + m]
self.assertEQUAL(b, a[:p] + a[p + m:])
self.check_obj(b)
def test_delslice_range_step(self):
N = 200
for step in range(-N - 1, N):
if step == 0:
continue
a = urandom(N, self.random_endian())
lst = a.tolist()
del a[::step]
del lst[::step]
self.assertEqual(a.tolist(), lst)
tests.append(SliceTests)
# ---------------------------------------------------------------------------
class MiscTests(unittest.TestCase, Util):
def test_instancecheck(self):
a = bitarray('011')
self.assertIsInstance(a, bitarray)
self.assertFalse(isinstance(a, str))
def test_booleanness(self):
self.assertEqual(bool(bitarray('')), False)
self.assertEqual(bool(bitarray('0')), True)
self.assertEqual(bool(bitarray('1')), True)
def test_to01(self):
a = bitarray()
self.assertEqual(a.to01(), '')
self.assertIsInstance(a.to01(), str)
a = bitarray('101')
self.assertEqual(a.to01(), '101')
self.assertIsInstance(a.to01(), str)
def test_iterate(self):
for lst in self.randomlists():
acc = []
for b in bitarray(lst):
acc.append(b)
self.assertEqual(acc, lst)
def test_iter1(self):
it = iter(bitarray('011'))
self.assertIsType(it, 'bitarrayiterator')
self.assertBitEqual(next(it), 0)
self.assertBitEqual(next(it), 1)
self.assertBitEqual(next(it), 1)
self.assertStopIteration(it)
def test_iter2(self):
for a in self.randombitarrays():
aa = a.tolist()
self.assertEqual(list(a), aa)
self.assertEqual(list(iter(a)), aa)
def test_assignment(self):
a = bitarray('00110111001')
a[1:3] = a[7:9]
a[-1:] = a[:1]
b = bitarray('01010111000')
self.assertEqual(a, b)
def test_subclassing(self):
class ExaggeratingBitarray(bitarray):
def __new__(cls, data, offset):
return bitarray.__new__(cls, data)
def __init__(self, data, offset):
self.offset = offset
def __getitem__(self, i):
return bitarray.__getitem__(self, i - self.offset)
for a in self.randombitarrays():
b = ExaggeratingBitarray(a, 1234)
for i in range(len(a)):
self.assertEqual(a[i], b[i + 1234])
def test_endianness1(self):
a = bitarray(endian='little')
a.frombytes(b'\x01')
self.assertEqual(a.to01(), '10000000')
b = bitarray(endian='little')
b.frombytes(b'\x80')
self.assertEqual(b.to01(), '00000001')
c = bitarray(endian='big')
c.frombytes(b'\x80')
self.assertEqual(c.to01(), '10000000')
d = bitarray(endian='big')
d.frombytes(b'\x01')
self.assertEqual(d.to01(), '00000001')
self.assertEqual(a, c)
self.assertEqual(b, d)
def test_endianness2(self):
a = bitarray(8, endian='little')
a.setall(False)
a[0] = True
self.assertEqual(a.tobytes(), b'\x01')
a[1] = True
self.assertEqual(a.tobytes(), b'\x03')
a.frombytes(b' ')
self.assertEqual(a.tobytes(), b'\x03 ')
self.assertEqual(a.to01(), '1100000000000100')
def test_endianness3(self):
a = bitarray(8, endian='big')
a.setall(False)
a[7] = True
self.assertEqual(a.tobytes(), b'\x01')
a[6] = True
self.assertEqual(a.tobytes(), b'\x03')
a.frombytes(b' ')
self.assertEqual(a.tobytes(), b'\x03 ')
self.assertEqual(a.to01(), '0000001100100000')
def test_endianness4(self):
a = bitarray('00100000', endian='big')
self.assertEqual(a.tobytes(), b' ')
b = bitarray('00000100', endian='little')
self.assertEqual(b.tobytes(), b' ')
self.assertNotEqual(a, b)
def test_pickle(self):
for a in self.randombitarrays():
b = pickle.loads(pickle.dumps(a))
self.assertFalse(b is a)
self.assertEQUAL(a, b)
def test_overflow(self):
a = bitarray(1)
for i in -7, -1, 0, 1:
n = 2 ** 63 + i
self.assertRaises(OverflowError, a.__imul__, n)
self.assertRaises(OverflowError, bitarray, n)
a = bitarray(2 ** 10)
self.assertRaises(OverflowError, a.__imul__, 2 ** 53)
if SYSINFO[0] == 8:
return
a = bitarray(10 ** 6)
self.assertRaises(OverflowError, a.__imul__, 17180)
for i in -7, -1, 0, 1:
self.assertRaises(OverflowError, bitarray, 2 ** 31 + i)
try:
a = bitarray(2 ** 31 - 8);
except MemoryError:
return
self.assertRaises(OverflowError, bitarray.append, a, True)
def test_unicode_create(self):
a = bitarray(u'')
self.assertEqual(a, bitarray())
a = bitarray(u'111001')
self.assertEqual(a, bitarray('111001'))
def test_unhashable(self):
a = bitarray()
self.assertRaises(TypeError, hash, a)
self.assertRaises(TypeError, dict, [(a, 'foo')])
tests.append(MiscTests)
# ---------------------------------------------------------------------------
class RichCompareTests(unittest.TestCase, Util):
def test_wrong_types(self):
a = bitarray()
for x in None, 7, 'A':
self.assertEqual(a.__eq__(x), NotImplemented)
self.assertEqual(a.__ne__(x), NotImplemented)
self.assertEqual(a.__ge__(x), NotImplemented)
self.assertEqual(a.__gt__(x), NotImplemented)
self.assertEqual(a.__le__(x), NotImplemented)
self.assertEqual(a.__lt__(x), NotImplemented)
def test_explicit(self):
for sa, sb, res in [
('', '', '101010'),
('0', '0', '101010'),
('1', '1', '101010'),
('0', '', '011100'),
('1', '', '011100'),
('1', '0', '011100'),
('11', '10', '011100'),
('01', '00', '011100'),
('0', '1', '010011'),
('', '0', '010011'),
('', '1', '010011'),
]:
a = bitarray(sa, self.random_endian())
b = bitarray(sb, self.random_endian())
self.assertEqual(a == b, int(res[0]))
self.assertEqual(a != b, int(res[1]))
self.assertEqual(a >= b, int(res[2]))
self.assertEqual(a > b, int(res[3]))
self.assertEqual(a <= b, int(res[4]))
self.assertEqual(a < b, int(res[5]))
def test_eq_ne(self):
for _ in range(10):
self.assertTrue(bitarray(0, self.random_endian()) ==
bitarray(0, self.random_endian()))
self.assertFalse(bitarray(0, self.random_endian()) !=
bitarray(0, self.random_endian()))
for n in range(1, 20):
a = bitarray(n, self.random_endian())
a.setall(1)
b = bitarray(a, self.random_endian())
self.assertTrue(a == b)
self.assertFalse(a != b)
b[n - 1] = 0
self.assertTrue(a != b)
self.assertFalse(a == b)
def test_eq_ne_random(self):
for a in self.randombitarrays(start=1):
b = bitarray(a, self.random_endian())
self.assertTrue(a == b)
self.assertFalse(a != b)
b.invert(randint(0, len(a) - 1))
self.assertTrue(a != b)
self.assertFalse(a == b)
def check(self, a, b, c, d):
self.assertEqual(a == b, c == d)
self.assertEqual(a != b, c != d)
self.assertEqual(a <= b, c <= d)
self.assertEqual(a < b, c < d)
self.assertEqual(a >= b, c >= d)
self.assertEqual(a > b, c > d)
def test_invert_random_element(self):
for a in self.randombitarrays(start=1):
n = len(a)
b = bitarray(a, self.random_endian())
i = randint(0, n - 1)
b.invert(i)
self.check(a, b, a[i], b[i])
def test_size(self):
for _ in range(100):
a = zeros(randint(1, 20), self.random_endian())
b = zeros(randint(1, 20), self.random_endian())
self.check(a, b, len(a), len(b))
def test_random(self):
for a in self.randombitarrays():
aa = a.tolist()
if randint(0, 1):
a = frozenbitarray(a)
for b in self.randombitarrays():
bb = b.tolist()
if randint(0, 1):
b = frozenbitarray(b)
self.check(a, b, aa, bb)
self.check(a, b, aa, bb)
tests.append(RichCompareTests)
# ---------------------------------------------------------------------------
class SpecialMethodTests(unittest.TestCase, Util):
def test_all(self):
a = bitarray()
self.assertTrue(a.all())
for s, r in ('0', False), ('1', True), ('01', False):
self.assertTrue(bitarray(s).all() is r)
for a in self.randombitarrays():
self.assertTrue(a.all() is all(a))
N = randint(1000, 2000)
a = bitarray(N)
a.setall(1)
self.assertTrue(a.all())
a[N - 1] = 0
self.assertFalse(a.all())
def test_any(self):
a = bitarray()
self.assertFalse(a.any())
for s, r in ('0', False), ('1', True), ('01', True):
self.assertTrue(bitarray(s).any() is r)
for a in self.randombitarrays():
self.assertTrue(a.any() is any(a))
N = randint(1000, 2000)
a = bitarray(N)
a.setall(0)
self.assertFalse(a.any())
a[N - 1] = 1
self.assertTrue(a.any())
def test_repr(self):
r = repr(bitarray())
self.assertEqual(r, "bitarray()")
self.assertIsInstance(r, str)
r = repr(bitarray('10111'))
self.assertEqual(r, "bitarray('10111')")
self.assertIsInstance(r, str)
for a in self.randombitarrays():
b = eval(repr(a))
self.assertFalse(b is a)
self.assertEqual(a, b)
self.check_obj(b)
def test_copy(self):
for a in self.randombitarrays():
b = a.copy()
self.assertFalse(b is a)
self.assertEQUAL(a, b)
b = copy.copy(a)
self.assertFalse(b is a)
self.assertEQUAL(a, b)
b = copy.deepcopy(a)
self.assertFalse(b is a)
self.assertEQUAL(a, b)
def assertReallyEqual(self, a, b):
# assertEqual first, because it will have a good message if the
# assertion fails.
self.assertEqual(a, b)
self.assertEqual(b, a)
self.assertTrue(a == b)
self.assertTrue(b == a)
self.assertFalse(a != b)
self.assertFalse(b != a)
if not is_py3k:
self.assertEqual(0, cmp(a, b))
self.assertEqual(0, cmp(b, a))
def assertReallyNotEqual(self, a, b):
# assertNotEqual first, because it will have a good message if the
# assertion fails.
self.assertNotEqual(a, b)
self.assertNotEqual(b, a)
self.assertFalse(a == b)
self.assertFalse(b == a)
self.assertTrue(a != b)
self.assertTrue(b != a)
if not is_py3k:
self.assertNotEqual(0, cmp(a, b))
self.assertNotEqual(0, cmp(b, a))
def test_equality(self):
self.assertReallyEqual(bitarray(''), bitarray(''))
self.assertReallyEqual(bitarray('0'), bitarray('0'))
self.assertReallyEqual(bitarray('1'), bitarray('1'))
def test_not_equality(self):
self.assertReallyNotEqual(bitarray(''), bitarray('1'))
self.assertReallyNotEqual(bitarray(''), bitarray('0'))
self.assertReallyNotEqual(bitarray('0'), bitarray('1'))
def test_equality_random(self):
for a in self.randombitarrays(start=1):
b = a.copy()
self.assertReallyEqual(a, b)
n = len(a)
b.invert(n - 1) # flip last bit
self.assertReallyNotEqual(a, b)
def test_sizeof(self):
a = bitarray()
size = sys.getsizeof(a)
self.assertEqual(size, a.__sizeof__())
self.assertIsInstance(size, int if is_py3k else (int, long))
self.assertTrue(size < 200)
a = bitarray(8000)
self.assertTrue(sys.getsizeof(a) > 1000)
tests.append(SpecialMethodTests)
# ---------------------------------------------------------------------------
class SequenceMethodsTests(unittest.TestCase, Util):
def test_concat(self):
a = bitarray('001')
b = a + bitarray('110')
self.assertEQUAL(b, bitarray('001110'))
b = a + [0, 1, True]
self.assertEQUAL(b, bitarray('001011'))
b = a + '100'
self.assertEQUAL(b, bitarray('001100'))
b = a + (1, 0, True)
self.assertEQUAL(b, bitarray('001101'))
self.assertRaises(ValueError, a.__add__, (0, 1, 2))
self.assertEQUAL(a, bitarray('001'))
self.assertRaises(TypeError, a.__add__, 42)
if is_py3k:
self.assertRaises(TypeError, a.__add__, b'1101')
else:
self.assertEqual(a + b'10', bitarray('00110'))
for a in self.randombitarrays():
aa = a.copy()
for b in self.randombitarrays():
bb = b.copy()
c = a + b
self.assertEqual(c, bitarray(a.tolist() + b.tolist()))
self.assertEqual(c.endian(), a.endian())
self.check_obj(c)
self.assertEQUAL(a, aa)
self.assertEQUAL(b, bb)
def test_inplace_concat(self):
a = bitarray('001')
a += bitarray('110')
self.assertEqual(a, bitarray('001110'))
a += [0, 1, True]
self.assertEqual(a, bitarray('001110011'))
a += '100'
self.assertEqual(a, bitarray('001110011100'))
a += (1, 0, True)
self.assertEqual(a, bitarray('001110011100101'))
a = bitarray('110')
self.assertRaises(ValueError, a.__iadd__, [0, 1, 2])
self.assertEqual(a, bitarray('110'))
self.assertRaises(TypeError, a.__iadd__, 42)
b = b'101'
if is_py3k:
self.assertRaises(TypeError, a.__iadd__, b)
else:
a += b
self.assertEqual(a, bitarray('110101'))
for a in self.randombitarrays():
for b in self.randombitarrays():
c = bitarray(a)
d = c
d += b
self.assertEqual(d, a + b)
self.assertTrue(c is d)
self.assertEQUAL(c, d)
self.assertEqual(d.endian(), a.endian())
self.check_obj(d)
def test_repeat_explicit(self):
for m, s, r in [
( 0, '', ''),
( 0, '1001111', ''),
(-1, '100110', ''),
(11, '', ''),
( 1, '110', '110'),
( 2, '01', '0101'),
( 5, '1', '11111'),
]:
a = bitarray(s)
self.assertEqual(a * m, bitarray(r))
self.assertEqual(m * a, bitarray(r))
c = a.copy()
c *= m
self.assertEqual(c, bitarray(r))
def test_repeat_wrong_args(self):
a = bitarray()
self.assertRaises(TypeError, a.__mul__, None)
self.assertRaises(TypeError, a.__mul__, 2.0)
self.assertRaises(TypeError, a.__imul__, None)
self.assertRaises(TypeError, a.__imul__, 3.0)
def test_repeat_random(self):
for a in self.randombitarrays():
b = a.copy()
for m in list(range(-3, 5)) + [randint(100, 200)]:
res = bitarray(m * a.to01(), endian=a.endian())
self.assertEqual(len(res), len(a) * max(0, m))
c = a * m
self.assertEQUAL(c, res)
c = m * a
self.assertEQUAL(c, res)
c = a.copy()
c *= m
self.assertEQUAL(c, res)
self.check_obj(c)
self.assertEQUAL(a, b)
def test_contains_simple(self):
a = bitarray()
self.assertFalse(False in a)
self.assertFalse(True in a)
self.assertTrue(bitarray() in a)
a.append(True)
self.assertTrue(True in a)
self.assertFalse(False in a)
a = bitarray([False])
self.assertTrue(False in a)
self.assertFalse(True in a)
a.append(True)
self.assertTrue(0 in a)
self.assertTrue(1 in a)
if not is_py3k:
self.assertTrue(long(0) in a)
self.assertTrue(long(1) in a)
def test_contains_errors(self):
a = bitarray()
self.assertEqual(a.__contains__(1), False)
a.append(1)
self.assertEqual(a.__contains__(1), True)
a = bitarray('0011')
self.assertEqual(a.__contains__(bitarray('01')), True)
self.assertEqual(a.__contains__(bitarray('10')), False)
self.assertRaises(TypeError, a.__contains__, 'asdf')
self.assertRaises(ValueError, a.__contains__, 2)
self.assertRaises(ValueError, a.__contains__, -1)
if not is_py3k:
self.assertRaises(ValueError, a.__contains__, long(2))
def test_contains_range(self):
for n in range(2, 50):
a = bitarray(n)
a.setall(0)
self.assertTrue(False in a)
self.assertFalse(True in a)
a[randint(0, n - 1)] = 1
self.assertTrue(True in a)
self.assertTrue(False in a)
a.setall(1)
self.assertTrue(True in a)
self.assertFalse(False in a)
a[randint(0, n - 1)] = 0
self.assertTrue(True in a)
self.assertTrue(False in a)
def test_contains_explicit(self):
a = bitarray('011010000001')
for s, r in [('', True), # every bitarray contains an empty one
('1', True), ('11', True), ('111', False),
('011', True), ('0001', True), ('00011', False)]:
self.assertEqual(bitarray(s) in a, r)
tests.append(SequenceMethodsTests)
# ---------------------------------------------------------------------------
class NumberTests(unittest.TestCase, Util):
def test_misc(self):
for a in self.randombitarrays():
b = ~a
c = a & b
self.assertEqual(c.any(), False)
self.assertEqual(a, a ^ c)
d = a ^ b
self.assertEqual(d.all(), True)
b &= d
self.assertEqual(~b, a)
def test_bool(self):
a = bitarray()
self.assertTrue(bool(a) is False)
a.append(0)
self.assertTrue(bool(a) is True)
a.append(1)
self.assertTrue(bool(a) is True)
def test_size_error(self):
a = bitarray('11001')
b = bitarray('100111')
self.assertRaises(ValueError, lambda: a & b)
self.assertRaises(ValueError, lambda: a | b)
self.assertRaises(ValueError, lambda: a ^ b)
for x in (a.__and__, a.__or__, a.__xor__,
a.__iand__, a.__ior__, a.__ixor__):
self.assertRaises(ValueError, x, b)
def test_endianness_error(self):
a = bitarray('11001', 'big')
b = bitarray('10011', 'little')
self.assertRaises(ValueError, lambda: a & b)
self.assertRaises(ValueError, lambda: a | b)
self.assertRaises(ValueError, lambda: a ^ b)
for x in (a.__and__, a.__or__, a.__xor__,
a.__iand__, a.__ior__, a.__ixor__):
self.assertRaises(ValueError, x, b)
def test_and(self):
a = bitarray('11001')
b = bitarray('10011')
c = a & b
self.assertEqual(c, bitarray('10001'))
self.check_obj(c)
self.assertRaises(TypeError, lambda: a & 1)
self.assertRaises(TypeError, lambda: 1 & a)
self.assertEqual(a, bitarray('11001'))
self.assertEqual(b, bitarray('10011'))
def test_or(self):
a = bitarray('11001')
b = bitarray('10011')
c = a | b
self.assertEqual(c, bitarray('11011'))
self.check_obj(c)
self.assertRaises(TypeError, lambda: a | 1)
self.assertRaises(TypeError, lambda: 1 | a)
self.assertEqual(a, bitarray('11001'))
self.assertEqual(b, bitarray('10011'))
def test_xor(self):
a = bitarray('11001')
b = bitarray('10011')
c = a ^ b
self.assertEQUAL(c, bitarray('01010'))
self.check_obj(c)
self.assertRaises(TypeError, lambda: a ^ 1)
self.assertRaises(TypeError, lambda: 1 ^ a)
self.assertEqual(a, bitarray('11001'))
self.assertEqual(b, bitarray('10011'))
def test_iand(self):
a = bitarray('110010110')
b = bitarray('100110011')
a &= b
self.assertEqual(a, bitarray('100010010'))
self.assertEqual(b, bitarray('100110011'))
self.check_obj(a)
self.check_obj(b)
try:
a &= 1
except TypeError:
error = 1
self.assertEqual(error, 1)
def test_ior(self):
a = bitarray('110010110')
b = bitarray('100110011')
a |= b
self.assertEQUAL(a, bitarray('110110111'))
self.assertEQUAL(b, bitarray('100110011'))
try:
a |= 1
except TypeError:
error = 1
self.assertEqual(error, 1)
def test_ixor(self):
a = bitarray('110010110')
b = bitarray('100110011')
a ^= b
self.assertEQUAL(a, bitarray('010100101'))
self.assertEQUAL(b, bitarray('100110011'))
try:
a ^= 1
except TypeError:
error = 1
self.assertEqual(error, 1)
def test_bitwise_self(self):
for a in self.randombitarrays():
aa = a.copy()
self.assertEQUAL(a & a, aa)
self.assertEQUAL(a | a, aa)
self.assertEQUAL(a ^ a, zeros(len(aa), aa.endian()))
self.assertEQUAL(a, aa)
def test_bitwise_inplace_self(self):
for a in self.randombitarrays():
aa = a.copy()
a &= a
self.assertEQUAL(a, aa)
a |= a
self.assertEQUAL(a, aa)
a ^= a
self.assertEqual(a, zeros(len(aa), aa.endian()))
def test_invert(self):
a = bitarray('11011')
b = ~a
self.assertEQUAL(b, bitarray('00100'))
self.assertEQUAL(a, bitarray('11011'))
self.assertFalse(a is b)
self.check_obj(b)
for a in self.randombitarrays():
b = bitarray(a)
b.invert()
for i in range(len(a)):
self.assertEqual(b[i], not a[i])
self.check_obj(b)
self.assertEQUAL(~a, b)
@staticmethod
def shift(a, n, direction):
if n >= len(a):
return zeros(len(a), a.endian())
if direction == 'right':
return zeros(n, a.endian()) + a[:len(a)-n]
elif direction == 'left':
return a[n:] + zeros(n, a.endian())
else:
raise ValueError("invalid direction: %s" % direction)
def test_lshift(self):
a = bitarray('11011')
b = a << 2
self.assertEQUAL(b, bitarray('01100'))
self.assertRaises(TypeError, lambda: a << 1.2)
self.assertRaises(TypeError, a.__lshift__, 1.2)
self.assertRaises(ValueError, lambda: a << -1)
self.assertRaises(OverflowError, a.__lshift__, 2 ** 63)
for a in self.randombitarrays():
c = a.copy()
n = randint(0, len(a) + 3)
b = a << n
self.assertEqual(len(b), len(a))
self.assertEQUAL(b, self.shift(a, n, 'left'))
self.assertEQUAL(a, c)
def test_rshift(self):
a = bitarray('1101101')
b = a >> 1
self.assertEQUAL(b, bitarray('0110110'))
self.assertRaises(TypeError, lambda: a >> 1.2)
self.assertRaises(TypeError, a.__rshift__, 1.2)
self.assertRaises(ValueError, lambda: a >> -1)
for a in self.randombitarrays():
c = a.copy()
n = randint(0, len(a) + 3)
b = a >> n
self.assertEqual(len(b), len(a))
self.assertEQUAL(b, self.shift(a, n, 'right'))
self.assertEQUAL(a, c)
def test_ilshift(self):
a = bitarray('110110101')
a <<= 7
self.assertEQUAL(a, bitarray('010000000'))
self.assertRaises(TypeError, a.__ilshift__, 1.2)
self.assertRaises(ValueError, a.__ilshift__, -3)
for a in self.randombitarrays():
b = a.copy()
n = randint(0, len(a) + 3)
b <<= n
self.assertEqual(len(b), len(a))
self.assertEQUAL(b, self.shift(a, n, 'left'))
def test_irshift(self):
a = bitarray('110110111')
a >>= 3
self.assertEQUAL(a, bitarray('000110110'))
self.assertRaises(TypeError, a.__irshift__, 1.2)
self.assertRaises(ValueError, a.__irshift__, -4)
for a in self.randombitarrays():
b = a.copy()
n = randint(0, len(a) + 3)
b >>= n
self.assertEqual(len(b), len(a))
self.assertEQUAL(b, self.shift(a, n, 'right'))
def check_random(self, n, endian, n_shift, direction):
a = urandom(n, endian)
self.assertEqual(len(a), n)
b = a.copy()
if direction == 'left':
b <<= n_shift
else:
b >>= n_shift
self.assertEQUAL(b, self.shift(a, n_shift, direction))
def test_shift_range(self):
for endian in 'little', 'big':
for direction in 'left', 'right':
for n in range(0, 200):
self.check_random(n, endian, 1, direction)
self.check_random(n, endian, randint(0, n), direction)
for n_shift in range(0, 100):
self.check_random(100, endian, n_shift, direction)
def test_zero_shift(self):
for a in self.randombitarrays():
aa = a.copy()
self.assertEQUAL(a << 0, aa)
self.assertEQUAL(a >> 0, aa)
a <<= 0
self.assertEQUAL(a, aa)
a >>= 0
self.assertEQUAL(a, aa)
def test_len_or_larger_shift(self):
# ensure shifts with len(a) (or larger) result in all zero bitarrays
for a in self.randombitarrays():
c = a.copy()
z = zeros(len(a), a.endian())
n = randint(len(a), len(a) + 10)
self.assertEQUAL(a << n, z)
self.assertEQUAL(a >> n, z)
self.assertEQUAL(a, c)
a <<= n
self.assertEQUAL(a, z)
a = bitarray(c)
a >>= n
self.assertEQUAL(a, z)
def test_shift_example(self):
a = bitarray('0010011')
self.assertEqual(a << 3, bitarray('0011000'))
a >>= 4
self.assertEqual(a, bitarray('0000001'))
tests.append(NumberTests)
# ---------------------------------------------------------------------------
class ExtendTests(unittest.TestCase, Util):
def test_wrongArgs(self):
a = bitarray()
self.assertRaises(TypeError, a.extend)
self.assertRaises(TypeError, a.extend, None)
self.assertRaises(TypeError, a.extend, True)
self.assertRaises(TypeError, a.extend, 24)
self.assertRaises(TypeError, a.extend, 1.0)
def test_bitarray(self):
a = bitarray()
a.extend(bitarray())
self.assertEqual(a, bitarray())
a.extend(bitarray('110'))
self.assertEqual(a, bitarray('110'))
a.extend(bitarray('1110'))
self.assertEqual(a, bitarray('1101110'))
a = bitarray('00001111', endian='little')
a.extend(bitarray('00100111', endian='big'))
self.assertEqual(a, bitarray('00001111 00100111'))
def test_bitarray_random(self):
for a in self.randombitarrays():
sa = a.to01()
for b in self.randombitarrays():
bb = b.copy()
c = bitarray(a)
c.extend(b)
self.assertEqual(c.to01(), sa + bb.to01())
self.assertEqual(c.endian(), a.endian())
self.assertEqual(len(c), len(a) + len(b))
self.check_obj(c)
# ensure b hasn't changed
self.assertEQUAL(b, bb)
self.check_obj(b)
def test_list(self):
a = bitarray()
a.extend([])
self.assertEqual(a, bitarray())
a.extend([0, 1, True, False])
self.assertEqual(a, bitarray('0110'))
self.assertRaises(ValueError, a.extend, [0, 1, 2])
self.assertRaises(TypeError, a.extend, [0, 1, 'a'])
self.assertEqual(a, bitarray('0110'))
for a in self.randomlists():
for b in self.randomlists():
c = bitarray(a)
c.extend(b)
self.assertEqual(c.tolist(), a + b)
self.check_obj(c)
def test_tuple(self):
a = bitarray()
a.extend(tuple())
self.assertEqual(a, bitarray())
a.extend((0, 1, True, 0, False))
self.assertEqual(a, bitarray('01100'))
self.assertRaises(ValueError, a.extend, (0, 1, 2))
self.assertRaises(TypeError, a.extend, (0, 1, 'a'))
self.assertEqual(a, bitarray('01100'))
for a in self.randomlists():
for b in self.randomlists():
c = bitarray(a)
c.extend(tuple(b))
self.assertEqual(c.tolist(), a + b)
self.check_obj(c)
def test_generator_1(self):
def gen(lst):
for x in lst:
yield x
a = bitarray('0011')
a.extend(gen([0, 1, False, True, 0]))
self.assertEqual(a, bitarray('0011 01010'))
self.assertRaises(ValueError, a.extend, gen([0, 1, 2]))
self.assertRaises(TypeError, a.extend, gen([1, 0, None]))
self.assertEqual(a, bitarray('0011 01010'))
a = bytearray()
a.extend(gen([0, 1, 255]))
self.assertEqual(a, b'\x00\x01\xff')
self.assertRaises(ValueError, a.extend, gen([0, 1, 256]))
self.assertRaises(TypeError, a.extend, gen([1, 0, None]))
self.assertEqual(a, b'\x00\x01\xff')
for a in self.randomlists():
def foo():
for e in a:
yield e
b = bitarray()
b.extend(foo())
self.assertEqual(b.tolist(), a)
self.check_obj(b)
def test_generator_2(self):
def gen():
for i in range(10):
if i == 4:
raise KeyError
yield i % 2
a = bitarray()
self.assertRaises(KeyError, a.extend, gen())
self.assertEqual(a, bitarray('0101'))
a = []
self.assertRaises(KeyError, a.extend, gen())
self.assertEqual(a, [0, 1, 0, 1])
def test_iterator_1(self):
a = bitarray()
a.extend(iter([]))
self.assertEqual(a, bitarray())
a.extend(iter([1, 1, 0, True, False]))
self.assertEqual(a, bitarray('11010'))
self.assertRaises(ValueError, a.extend, iter([1, 1, 0, 0, 2]))
self.assertEqual(a, bitarray('11010'))
for a in self.randomlists():
for b in self.randomlists():
c = bitarray(a)
c.extend(iter(b))
self.assertEqual(c.tolist(), a + b)
self.check_obj(c)
def test_iterator_2(self):
a = bitarray()
a.extend(itertools.repeat(True, 23))
self.assertEqual(a, bitarray(23 * '1'))
self.check_obj(a)
def test_string01(self):
a = bitarray()
a.extend(str())
a.extend('')
self.assertEqual(a, bitarray())
a.extend('0110111')
self.assertEqual(a, bitarray('0110111'))
self.assertRaises(ValueError, a.extend, '0011201')
# ensure no bits got added after error was raised
self.assertEqual(a, bitarray('0110111'))
a = bitarray()
self.assertRaises(ValueError, a.extend, 1000 * '01' + '.')
self.assertEqual(a, bitarray())
for a in self.randomlists():
for b in self.randomlists():
c = bitarray(a)
c.extend(''.join(['0', '1'][x] for x in b))
self.assertEqual(c, bitarray(a + b))
self.check_obj(c)
def test_string01_whitespace(self):
a = bitarray()
a.extend('0 1\n0\r1\t0\v1_')
self.assertEqual(a, bitarray('010101'))
a += '_ 1\n0\r1\t0\v'
self.assertEqual(a, bitarray('010101 1010'))
self.check_obj(a)
def test_unicode(self):
a = bitarray()
a.extend(u'')
self.assertEqual(a, bitarray())
self.assertRaises(ValueError, a.extend, u'0011201')
# ensure no bits got added after error was raised
self.assertEqual(a, bitarray())
self.check_obj(a)
a = bitarray()
a.extend(u'001 011_')
self.assertEqual(a, bitarray('001011'))
self.assertRaises(UnicodeEncodeError, a.extend, u'1\u2605 0')
self.assertEqual(a, bitarray('001011'))
self.check_obj(a)
def test_bytes(self):
a = bitarray()
b = b'10110'
if is_py3k:
self.assertRaises(TypeError, a.extend, b)
else:
a.extend(b)
self.assertEqual(a, bitarray('10110'))
self.check_obj(a)
def test_self(self):
for s in '', '1', '110', '00110111':
a = bitarray(s)
a.extend(a)
self.assertEqual(a, bitarray(2 * s))
for a in self.randombitarrays():
endian = a.endian()
s = a.to01()
a.extend(a)
self.assertEqual(a.to01(), 2 * s)
self.assertEqual(a.endian(), endian)
self.assertEqual(len(a), 2 * len(s))
self.check_obj(a)
tests.append(ExtendTests)
# ---------------------------------------------------------------------------
class MethodTests(unittest.TestCase, Util):
def test_append_simple(self):
a = bitarray()
a.append(True)
a.append(False)
a.append(False)
self.assertEQUAL(a, bitarray('100'))
a.append(0)
a.append(1)
self.assertEQUAL(a, bitarray('10001'))
self.assertRaises(ValueError, a.append, 2)
self.assertRaises(TypeError, a.append, None)
self.assertRaises(TypeError, a.append, '')
self.assertEQUAL(a, bitarray('10001'))
self.check_obj(a)
def test_append_random(self):
for a in self.randombitarrays():
aa = a.tolist()
a.append(1)
self.assertEQUAL(a, bitarray(aa + [1], endian=a.endian()))
a.append(0)
self.assertEQUAL(a, bitarray(aa + [1, 0], endian=a.endian()))
self.check_obj(a)
def test_insert(self):
a = bitarray('111100')
a.insert(3, False)
self.assertEqual(a, bitarray('1110100'))
self.assertRaises(ValueError, a.insert, 0, 2)
self.assertRaises(TypeError, a.insert, 0, None)
self.assertRaises(TypeError, a.insert)
self.assertRaises(TypeError, a.insert, None)
self.assertEqual(a, bitarray('1110100'))
self.check_obj(a)
def test_insert_random(self):
for a in self.randombitarrays():
aa = a.tolist()
for _ in range(20):
item = randint(0, 1)
pos = randint(-len(a) - 2, len(a) + 2)
a.insert(pos, item)
aa.insert(pos, item)
self.assertEqual(a.tolist(), aa)
self.check_obj(a)
def test_fill_simple(self):
for endian in 'little', 'big':
a = bitarray(endian=endian)
self.assertEqual(a.fill(), 0)
self.assertEqual(len(a), 0)
a = bitarray('101', endian)
self.assertEqual(a.fill(), 5)
self.assertEqual(a, bitarray('10100000'))
self.assertEqual(a.fill(), 0)
self.assertEqual(a, bitarray('10100000'))
self.check_obj(a)
def test_fill_exported(self):
a = bitarray('11101')
b = bitarray(buffer=a)
v = memoryview(a)
self.assertEqual(a.fill(), 3)
self.assertEqual(a, b)
if is_py3k:
self.assertEqual(v.nbytes, 1)
def test_fill_random(self):
for a in self.randombitarrays():
b = a.copy()
res = b.fill()
self.assertTrue(0 <= res < 8)
self.assertEqual(b.endian(), a.endian())
self.check_obj(b)
if len(a) % 8 == 0:
self.assertEqual(b, a)
else:
self.assertEqual(len(b) % 8, 0)
self.assertNotEqual(b, a)
self.assertEqual(b[:len(a)], a)
self.assertEqual(b[len(a):], zeros(len(b) - len(a)))
def test_invert_simple(self):
a = bitarray()
a.invert()
self.assertEQUAL(a, bitarray())
self.check_obj(a)
a = bitarray('11011')
a.invert()
self.assertEQUAL(a, bitarray('00100'))
a.invert(2)
self.assertEQUAL(a, bitarray('00000'))
a.invert(-1)
self.assertEQUAL(a, bitarray('00001'))
def test_invert_errors(self):
a = bitarray(5)
self.assertRaises(IndexError, a.invert, 5)
self.assertRaises(IndexError, a.invert, -6)
self.assertRaises(TypeError, a.invert, "A")
self.assertRaises(TypeError, a.invert, 0, 1)
def test_invert_random(self):
for a in self.randombitarrays(start=1):
b = a.copy()
i = randint(0, len(a) - 1)
b.invert(i)
a[i] = not a[i]
self.assertEQUAL(a, b)
def test_sort_simple(self):
a = bitarray('1101000')
a.sort()
self.assertEqual(a, bitarray('0000111'))
self.check_obj(a)
a = bitarray('1101000')
a.sort(reverse=True)
self.assertEqual(a, bitarray('1110000'))
a.sort(reverse=False)
self.assertEqual(a, bitarray('0000111'))
a.sort(True)
self.assertEqual(a, bitarray('1110000'))
a.sort(False)
self.assertEqual(a, bitarray('0000111'))
self.assertRaises(TypeError, a.sort, 'A')
def test_sort_random(self):
for rev in False, True, 0, 1, 7, -1, -7, None:
for a in self.randombitarrays():
lst = a.tolist()
if rev is None:
lst.sort()
a.sort()
else:
lst.sort(reverse=rev)
a.sort(reverse=rev)
self.assertEqual(a, bitarray(lst))
self.check_obj(a)
def test_reverse_explicit(self):
for x, y in [('', ''), ('1', '1'), ('10', '01'), ('001', '100'),
('1110', '0111'), ('11100', '00111'),
('011000', '000110'), ('1101100', '0011011'),
('11110000', '00001111'),
('11111000011', '11000011111'),
('11011111 00100000 000111',
'111000 00000100 11111011')]:
a = bitarray(x)
a.reverse()
self.assertEQUAL(a, bitarray(y))
self.check_obj(a)
self.assertRaises(TypeError, bitarray().reverse, 42)
def test_reverse_random(self):
for a in self.randombitarrays():
b = a.copy()
a.reverse()
self.assertEQUAL(a, bitarray(reversed(b), endian=a.endian()))
self.assertEQUAL(a, b[::-1])
self.check_obj(a)
def test_tolist(self):
a = bitarray()
self.assertEqual(a.tolist(), [])
a = bitarray('110')
lst = a.tolist()
self.assertIsInstance(lst, list)
self.assertEqual(repr(lst), '[1, 1, 0]')
for lst in self.randomlists():
a = bitarray(lst)
self.assertEqual(a.tolist(), lst)
def test_remove(self):
a = bitarray('1010110')
for val, res in [(False, '110110'), (True, '10110'),
(1, '0110'), (1, '010'), (0, '10'),
(0, '1'), (1, '')]:
a.remove(val)
self.assertEQUAL(a, bitarray(res))
self.check_obj(a)
a = bitarray('0010011')
a.remove(1)
self.assertEQUAL(a, bitarray('000011'))
self.assertRaises(TypeError, a.remove, 'A')
self.assertRaises(ValueError, a.remove, 21)
def test_remove_errors(self):
a = bitarray()
for i in (True, False, 1, 0):
self.assertRaises(ValueError, a.remove, i)
a = bitarray(21)
a.setall(0)
self.assertRaises(ValueError, a.remove, 1)
a.setall(1)
self.assertRaises(ValueError, a.remove, 0)
def test_pop_simple(self):
for x, n, r, y in [('1', 0, 1, ''),
('0', -1, 0, ''),
('0011100', 3, 1, '001100')]:
a = bitarray(x)
self.assertTrue(a.pop(n) is r)
self.assertEqual(a, bitarray(y))
self.check_obj(a)
a = bitarray('01')
self.assertEqual(a.pop(), True)
self.assertEqual(a.pop(), False)
# pop from empty bitarray
self.assertRaises(IndexError, a.pop)
def test_pop_random_1(self):
for a in self.randombitarrays():
self.assertRaises(IndexError, a.pop, len(a))
self.assertRaises(IndexError, a.pop, -len(a) - 1)
if len(a) == 0:
continue
aa = a.tolist()
enda = a.endian()
self.assertEqual(a.pop(), aa[-1])
self.check_obj(a)
self.assertEqual(a.endian(), enda)
def test_pop_random_2(self):
for a in self.randombitarrays(start=1):
n = randint(-len(a), len(a)-1)
aa = a.tolist()
x = a.pop(n)
self.assertBitEqual(x, aa[n])
y = aa.pop(n)
self.assertEqual(a, bitarray(aa))
self.assertBitEqual(x, y)
self.check_obj(a)
def test_clear(self):
for a in self.randombitarrays():
endian = a.endian()
a.clear()
self.assertEqual(len(a), 0)
self.assertEqual(a.endian(), endian)
self.check_obj(a)
def test_setall(self):
a = bitarray(5)
a.setall(True)
self.assertRaises(ValueError, a.setall, -1)
self.assertRaises(TypeError, a.setall, None)
self.assertEQUAL(a, bitarray('11111'))
a.setall(0)
self.assertEQUAL(a, bitarray('00000'))
self.check_obj(a)
def test_setall_empty(self):
a = bitarray()
for v in 0, 1:
a.setall(v)
self.assertEqual(a, bitarray())
self.check_obj(a)
def test_setall_random(self):
for a in self.randombitarrays():
val = randint(0, 1)
a.setall(val)
self.assertEqual(a, bitarray(len(a) * [val]))
self.check_obj(a)
def test_bytereverse_explicit_all(self):
for x, y in [('', ''),
('11101101', '10110111'),
('00000001', '10000000'),
('11011111 00100000 00011111',
'11111011 00000100 11111000')]:
a = bitarray(x)
a.bytereverse()
self.assertEqual(a, bitarray(y))
def test_bytereverse_explicit_range(self):
a = bitarray('11100000 00000011 00111111 11111000')
a.bytereverse(0, 1) # reverse byte 0
self.assertEqual(a, bitarray('00000111 00000011 00111111 11111000'))
a.bytereverse(1, -1) # reverse bytes 1 and 2
self.assertEqual(a, bitarray('00000111 11000000 11111100 11111000'))
a.bytereverse(2) # reverse bytes 2 till end of buffer
self.assertEqual(a, bitarray('00000111 11000000 00111111 00011111'))
a.bytereverse(-1) # reverse last byte
self.assertEqual(a, bitarray('00000111 11000000 00111111 11111000'))
a.bytereverse(3, 1) # start > stop (nothing to reverse)
self.assertEqual(a, bitarray('00000111 11000000 00111111 11111000'))
a.bytereverse(0, 4) # reverse all bytes
self.assertEqual(a, bitarray('11100000 00000011 11111100 00011111'))
a.bytereverse(-2) # last two bytes
self.assertEqual(a, bitarray('11100000 00000011 00111111 11111000'))
self.assertRaises(IndexError, a.bytereverse, -5)
self.assertRaises(IndexError, a.bytereverse, 0, -5)
self.assertRaises(IndexError, a.bytereverse, 5)
self.assertRaises(IndexError, a.bytereverse, 0, 5)
@skipIf(sys.version_info[0] == 2)
def test_bytereverse_part(self):
a = bitarray(5, 'big')
memoryview(a)[0] = 0x13 # 0001 0011
self.assertEqual(a, bitarray('0001 0'))
# the unused bits (011) are not treated as zeros
a.bytereverse()
self.assertEqual(a, bitarray('1100 1'))
a = bitarray(12, 'little')
memoryview(a)[1] = 0xd4 # .... .... 0010 1011
self.assertEqual(a[8:], bitarray('0010'))
# the unused bits (1011) are not treated as zeros
a.bytereverse(1)
self.assertEqual(a[8:], bitarray('1101'))
def test_bytereverse_byte(self):
for i in range(256):
a = bitarray()
a.frombytes(bytearray([i]))
self.assertEqual(len(a), 8)
b = a.copy()
b.bytereverse()
self.assertEqual(b, a[::-1])
a.reverse()
self.assertEqual(b, a)
self.check_obj(b)
def test_bytereverse_random(self):
t = bitarray(endian=self.random_endian())
t.frombytes(bytearray(range(256)))
t.bytereverse()
table = t.tobytes() # translation table
self.assertEqual(table[:9], b'\x00\x80\x40\xc0\x20\xa0\x60\xe0\x10')
for n in range(100):
a = urandom(8 * n, self.random_endian())
i = randint(0, n) # start
j = randint(0, n) # stop
b = a.copy()
memoryview(b)[i:j] = b.tobytes()[i:j].translate(table)
a.bytereverse(i, j)
self.assertEQUAL(a, b)
self.check_obj(a)
def test_bytereverse_endian(self):
for n in range(20):
a = urandom(8 * n, self.random_endian())
b = a.copy()
a.bytereverse()
a = bitarray(a, self.other_endian(a.endian()))
self.assertEqual(a.tobytes(), b.tobytes())
tests.append(MethodTests)
# ---------------------------------------------------------------------------
class CountTests(unittest.TestCase, Util):
def test_basic(self):
a = bitarray('10011')
self.assertEqual(a.count(), 3)
self.assertEqual(a.count(True), 3)
self.assertEqual(a.count(False), 2)
self.assertEqual(a.count(1), 3)
self.assertEqual(a.count(0), 2)
self.assertRaises(ValueError, a.count, 2)
self.assertRaises(ValueError, a.count, 1, 0, 5, 0)
self.assertRaises(TypeError, a.count, None)
self.assertRaises(TypeError, a.count, '')
self.assertRaises(TypeError, a.count, 'A')
self.assertRaises(TypeError, a.count, 1, 2.0)
self.assertRaises(TypeError, a.count, 1, 2, 4.0)
self.assertRaises(TypeError, a.count, 0, 'A')
self.assertRaises(TypeError, a.count, 0, 0, 'A')
def test_byte(self):
for i in range(256):
a = bitarray()
a.frombytes(bytearray([i]))
self.assertEqual(len(a), 8)
self.assertEqual(a.count(), bin(i)[2:].count('1'))
def test_whole_range(self):
for a in self.randombitarrays():
n = len(a)
s = a.to01()
for v in 0, 1:
ref = s.count(str(v))
self.assertEqual(a.count(v), ref)
self.assertEqual(a.count(v, n, -n - 1, -1), ref)
def test_zeros(self):
N = 37
a = zeros(N)
for i in range(N):
for j in range(i, N):
self.assertEqual(a.count(0, i, j), j - i)
for step in range(-N - 3, N + 3):
if step == 0:
continue
self.assertEqual(a.count(0, i, i, step), 0)
def test_slicelength(self):
for N in range(100):
step = randint(-N - 1, N)
if step == 0:
continue
a = bitarray(N, self.random_endian())
i = randint(-N - 1, N)
j = randint(-N - 1, N)
slicelength = self.calc_slicelength(slice(i, j, step), N)
self.assertEqual(len(a[i:j:step]), slicelength)
a.setall(0)
self.assertEqual(a.count(0, i, j, step), slicelength)
self.assertEqual(a.count(1, i, j, step), 0)
a[i:j:step] = 1
self.assertEqual(a.count(0), N - slicelength)
self.assertEqual(a.count(1), slicelength)
del a[i:j:step]
self.assertEqual(len(a), N - slicelength)
self.assertFalse(a.any())
def test_explicit(self):
a = bitarray('01001100 01110011 01')
self.assertEqual(a.count(), 9)
self.assertEqual(a.count(0, 12), 3)
self.assertEqual(a.count(1, 1, 18, 2), 6)
self.assertEqual(a.count(1, 0, 18, 3), 2)
self.assertEqual(a.count(1, 15, 4, -3), 2)
self.assertEqual(a.count(1, -5), 3)
self.assertEqual(a.count(1, 2, 17), 7)
self.assertEqual(a.count(1, 6, 11), 2)
self.assertEqual(a.count(0, 7, -3), 4)
self.assertEqual(a.count(1, 1, -1), 8)
self.assertEqual(a.count(1, 17, 14), 0)
def test_random(self):
for a in self.randombitarrays():
n = len(a)
i = randint(-n - 3, n + 3)
j = randint(-n - 3, n + 3)
for step in randint(-n - 3, -2), -1, 1, randint(2, n + 3):
for v in 0, 1:
self.assertEqual(a.count(v, i, j, step),
a[i:j:step].count(v))
tests.append(CountTests)
# ---------------------------------------------------------------------------
class IndexTests(unittest.TestCase, Util):
def test_simple(self):
a = bitarray()
for i in True, False, 1, 0:
self.assertEqual(a.find(i), -1)
self.assertRaises(ValueError, a.index, i)
a = zeros(100)
self.assertRaises(TypeError, a.find)
self.assertRaises(TypeError, a.find, 1, 'a')
self.assertRaises(TypeError, a.find, 1, 0, 'a')
self.assertRaises(TypeError, a.find, 1, 0, 100, 1)
self.assertRaises(ValueError, a.index, True)
self.assertRaises(TypeError, a.index)
self.assertRaises(TypeError, a.index, 1, 'a')
self.assertRaises(TypeError, a.index, 1, 0, 'a')
self.assertRaises(TypeError, a.index, 1, 0, 100, 1)
a[20] = a[27] = 1
for i in 1, True, bitarray('1'), bitarray('10'):
self.assertEqual(a.index(i), 20)
self.assertEqual(a.index(i, 21), 27)
self.assertEqual(a.index(i, 27), 27)
self.assertEqual(a.index(i, -73), 27)
self.assertRaises(ValueError, a.index, -1)
self.assertRaises(TypeError, a.index, None)
self.assertRaises(ValueError, a.index, 1, 5, 17)
self.assertRaises(ValueError, a.index, 1, 5, -83)
self.assertRaises(ValueError, a.index, 1, 21, 27)
self.assertRaises(ValueError, a.index, 1, 28)
self.assertEqual(a.index(0), 0)
self.assertEqual(a.find(0), 0)
def test_empty(self):
for a in self.randombitarrays():
# empty bitarray is always found at start index
sub = bitarray()
start = randint(0, len(a))
self.assertEqual(a.index(sub, start), start)
self.assertEqual(a.find(sub, start), start)
def test_200(self):
a = 200 * bitarray('1')
self.assertRaises(ValueError, a.index, False)
self.assertEqual(a.find(False), -1)
a[173] = a[187] = a[189] = 0
for i in 0, False, bitarray('0'), bitarray('01'):
self.assertEqual(a.index(i), 173)
self.assertEqual(a.find(i), 173)
self.assertEqual(a.index(True), 0)
self.assertEqual(a.find(True), 0)
s = bitarray('010')
self.assertEqual(a.index(s), 187)
self.assertEqual(a.find(s), 187)
def test_range(self):
n = 250
a = bitarray(n)
for m in range(n):
a.setall(0)
self.assertRaises(ValueError, a.index, 1)
self.assertEqual(a.find(1), -1)
a[m] = 1
self.assertEqual(a.index(1), m)
self.assertEqual(a.find(1), m)
a.setall(1)
self.assertRaises(ValueError, a.index, 0)
self.assertEqual(a.find(0), -1)
a[m] = 0
self.assertEqual(a.index(0), m)
self.assertEqual(a.find(0), m)
def test_explicit(self):
for endian in 'big', 'little':
a = bitarray('00001000 00000000 0010000', endian)
self.assertEqual(a.index(1), 4)
self.assertEqual(a.index(1, 1), 4)
self.assertEqual(a.index(0, 4), 5)
self.assertEqual(a.index(1, 5), 18)
self.assertEqual(a.index(1, -11), 18)
self.assertEqual(a.index(1, -50), 4)
self.assertRaises(ValueError, a.index, 1, 5, 18)
self.assertRaises(ValueError, a.index, 1, 19)
self.assertEqual(a.find(1), 4)
self.assertEqual(a.find(1, 1), 4)
self.assertEqual(a.find(0, 4), 5)
self.assertEqual(a.find(1, 5), 18)
self.assertEqual(a.find(1, -11), 18)
self.assertEqual(a.find(1, -50), 4)
self.assertEqual(a.find(1, 5, 18), -1)
self.assertEqual(a.find(1, 19), -1)
def test_explicit_2(self):
a = bitarray('10010101 11001111 1001011', self.random_endian())
s = bitarray('011', self.random_endian())
self.assertEqual(a.index(s, 15), 20)
self.assertEqual(a.index(s, -3), 20)
self.assertRaises(ValueError, a.index, s, 15, 22)
self.assertRaises(ValueError, a.index, s, 15, -1)
self.assertEqual(a.find(s, 15), 20)
self.assertEqual(a.find(s, -3), 20)
self.assertEqual(a.find(s, 15, 22), -1)
self.assertEqual(a.find(s, 15, -1), -1)
def test_random_start_stop(self):
n = 2000
a = zeros(n)
for _ in range(100):
a[randint(0, n - 1)] = 1
aa = a.tolist()
for _ in range(100):
start = randint(0, n)
stop = randint(0, n)
try: # reference from list
ref = aa.index(1, start, stop)
except ValueError:
ref = -1
res1 = a.find(1, start, stop)
self.assertEqual(res1, ref)
try:
res2 = a.index(1, start, stop)
except ValueError:
res2 = -1
self.assertEqual(res2, ref)
def test_random_2(self):
for n in range(1, 70):
a = bitarray(n)
i = randint(0, 1)
a.setall(i)
for _ in range(randint(1, 4)):
a.invert(randint(0, n - 1))
aa = a.tolist()
for _ in range(10):
start = randint(-10, n + 10)
stop = randint(-10, n + 10)
try:
res0 = aa.index(not i, start, stop)
except ValueError:
res0 = -1
res1 = a.find(not i, start, stop)
self.assertEqual(res1, res0)
try:
res2 = a.index(not i, start, stop)
except ValueError:
res2 = -1
self.assertEqual(res2, res0)
def test_random_3(self):
for a in self.randombitarrays():
aa = a.to01()
if a:
self.assertEqual(a.find(a), 0)
self.assertEqual(a.index(a), 0)
for sub in '0', '1', '01', '01', '11', '101', '1111', '00100':
b = bitarray(sub, self.random_endian())
self.assertEqual(a.find(b), aa.find(sub))
i = randint(-len(a) - 3, len(a) + 2)
j = randint(-len(a) - 3, len(a) + 2)
ref = aa.find(sub, i, j)
self.assertEqual(a.find(b, i, j), ref)
if ref == -1:
self.assertRaises(ValueError, a.index, b, i, j)
else:
self.assertEqual(a.index(b, i, j), ref)
tests.append(IndexTests)
# ---------------------------------------------------------------------------
class SearchTests(unittest.TestCase, Util):
def test_simple(self):
a = bitarray()
for s in 0, 1, False, True, bitarray('0'), bitarray('1'):
self.assertEqual(a.search(s), [])
a = bitarray('00100')
for s in 1, True, bitarray('1'), bitarray('10'):
self.assertEqual(a.search(s), [2])
a = 100 * bitarray('1')
self.assertEqual(a.search(0), [])
self.assertEqual(a.search(1), list(range(100)))
a = bitarray('10010101110011111001011')
for limit in range(10):
self.assertEqual(a.search(bitarray('011'), limit),
[6, 11, 20][:limit])
self.assertRaises(ValueError, a.search, bitarray())
self.assertRaises(TypeError, a.search, '010')
def test_itersearch(self):
a = bitarray('10011')
self.assertRaises(ValueError, a.itersearch, bitarray())
self.assertRaises(TypeError, a.itersearch, 1, 0)
self.assertRaises(TypeError, a.itersearch, '')
it = a.itersearch(1)
self.assertIsType(it, 'searchiterator')
self.assertEqual(next(it), 0)
self.assertEqual(next(it), 3)
self.assertEqual(next(it), 4)
self.assertStopIteration(it)
x = bitarray('11')
it = a.itersearch(x)
del a, x
self.assertEqual(next(it), 3)
def test_explicit_1(self):
a = bitarray('10011', self.random_endian())
for s, res in [('0', [1, 2]), ('1', [0, 3, 4]),
('01', [2]), ('11', [3]),
('000', []), ('1001', [0]),
('011', [2]), ('0011', [1]),
('10011', [0]), ('100111', [])]:
b = bitarray(s, self.random_endian())
self.assertEqual(a.search(b), res)
self.assertEqual(list(a.itersearch(b)), res)
def test_explicit_2(self):
a = bitarray('10010101 11001111 1001011')
for s, res in [('011', [6, 11, 20]),
('111', [7, 12, 13, 14]), # note the overlap
('1011', [5, 19]),
('100', [0, 9, 16])]:
b = bitarray(s)
self.assertEqual(a.search(b), res)
self.assertEqual(list(a.itersearch(b)), res)
def test_bool_random(self):
for a in self.randombitarrays():
b = a.copy()
b.setall(0)
for i in a.itersearch(1):
b[i] = 1
self.assertEQUAL(b, a)
b.setall(1)
for i in a.itersearch(0):
b[i] = 0
self.assertEQUAL(b, a)
s = set(a.search(0) + a.search(1))
self.assertEqual(len(s), len(a))
def test_random(self):
for a in self.randombitarrays():
if a:
self.assertEqual(a.search(a), [0])
self.assertEqual(list(a.itersearch(a)), [0])
for sub in '0', '1', '01', '01', '11', '101', '1101', '01100':
b = bitarray(sub, self.random_endian())
plst = [i for i in range(len(a)) if a[i:i + len(b)] == b]
self.assertEqual(a.search(b), plst)
for p in a.itersearch(b):
self.assertEqual(a[p:p + len(b)], b)
tests.append(SearchTests)
# ---------------------------------------------------------------------------
class BytesTests(unittest.TestCase, Util):
@staticmethod
def randombytes():
for n in range(1, 20):
yield os.urandom(n)
def test_frombytes_simple(self):
a = bitarray(endian='big')
a.frombytes(b'A')
self.assertEqual(a, bitarray('01000001'))
b = a
b.frombytes(b'BC')
self.assertEQUAL(b, bitarray('01000001 01000010 01000011',
endian='big'))
self.assertTrue(b is a)
def test_frombytes_types(self):
a = bitarray(endian='big')
a.frombytes(b'A') # bytes
self.assertEqual(a, bitarray('01000001'))
a.frombytes(bytearray([254])) # bytearray
self.assertEqual(a, bitarray('01000001 11111110'))
a.frombytes(memoryview(b'C')) # memoryview
self.assertEqual(a, bitarray('01000001 11111110 01000011'))
a.clear()
if is_py3k: # Python 2's array cannot be used as buffer
a.frombytes(array.array('B', [5, 255, 192]))
self.assertEqual(a, bitarray('00000101 11111111 11000000'))
self.check_obj(a)
for x in u'', 0, 1, False, True, None, []:
self.assertRaises(TypeError, a.frombytes, x)
def test_frombytes_bitarray(self):
for endian in 'little', 'big':
# endianness doesn't matter here as we're writting the buffer
# from bytes, and then getting the memoryview
b = bitarray(0, endian)
b.frombytes(b'ABC')
a = bitarray(0, 'big')
a.frombytes(bitarray(b))
self.assertEqual(a.endian(), 'big')
self.assertEqual(a, bitarray('01000001 01000010 01000011'))
self.check_obj(a)
def test_frombytes_self(self):
a = bitarray()
self.assertRaisesMessage(
BufferError,
"cannot resize bitarray that is exporting buffers",
a.frombytes, a)
def test_frombytes_empty(self):
for a in self.randombitarrays():
b = a.copy()
a.frombytes(b'')
a.frombytes(bytearray())
self.assertEQUAL(a, b)
self.assertFalse(a is b)
self.check_obj(a)
def test_frombytes_errors(self):
a = bitarray()
self.assertRaises(TypeError, a.frombytes)
self.assertRaises(TypeError, a.frombytes, b'', b'')
self.assertRaises(TypeError, a.frombytes, 1)
self.check_obj(a)
def test_frombytes_random(self):
for b in self.randombitarrays():
for s in self.randombytes():
a = bitarray(endian=b.endian())
a.frombytes(s)
c = b.copy()
b.frombytes(s)
self.assertEQUAL(b[-len(a):], a)
self.assertEQUAL(b[:-len(a)], c)
self.assertEQUAL(b, c + a)
self.check_obj(a)
def test_tobytes_empty(self):
a = bitarray()
self.assertEqual(a.tobytes(), b'')
def test_tobytes_endian(self):
for end in ('big', 'little'):
a = bitarray(endian=end)
a.frombytes(b'foo')
self.assertEqual(a.tobytes(), b'foo')
for s in self.randombytes():
a = bitarray(endian=end)
a.frombytes(s)
self.assertEqual(a.tobytes(), s)
self.check_obj(a)
def test_tobytes_explicit_ones(self):
for n, s in [(1, b'\x01'), (2, b'\x03'), (3, b'\x07'), (4, b'\x0f'),
(5, b'\x1f'), (6, b'\x3f'), (7, b'\x7f'), (8, b'\xff'),
(12, b'\xff\x0f'), (15, b'\xff\x7f'), (16, b'\xff\xff'),
(17, b'\xff\xff\x01'), (24, b'\xff\xff\xff')]:
a = bitarray(n, endian='little')
a.setall(1)
self.assertEqual(a.tobytes(), s)
def test_unpack_simple(self):
a = bitarray('01')
self.assertIsInstance(a.unpack(), bytes)
self.assertEqual(a.unpack(), b'\x00\x01')
self.assertEqual(a.unpack(b'A'), b'A\x01')
self.assertEqual(a.unpack(b'0', b'1'), b'01')
self.assertEqual(a.unpack(one=b'\xff'), b'\x00\xff')
self.assertEqual(a.unpack(zero=b'A'), b'A\x01')
self.assertEqual(a.unpack(one=b't', zero=b'f'), b'ft')
def test_unpack_random(self):
for a in self.randombitarrays():
self.assertEqual(a.unpack(b'0', b'1'),
a.to01().encode())
# round trip
b = bitarray()
b.pack(a.unpack())
self.assertEqual(b, a)
# round trip with invert
b = bitarray()
b.pack(a.unpack(b'\x01', b'\x00'))
b.invert()
self.assertEqual(b, a)
def test_unpack_errors(self):
a = bitarray('01')
self.assertRaises(TypeError, a.unpack, b'')
self.assertRaises(TypeError, a.unpack, b'0', b'')
self.assertRaises(TypeError, a.unpack, b'a', zero=b'b')
self.assertRaises(TypeError, a.unpack, foo=b'b')
self.assertRaises(TypeError, a.unpack, one=b'aa', zero=b'b')
if is_py3k:
self.assertRaises(TypeError, a.unpack, '0')
self.assertRaises(TypeError, a.unpack, one='a')
self.assertRaises(TypeError, a.unpack, b'0', '1')
def test_pack_simple(self):
for endian in 'little', 'big':
_set_default_endian(endian)
a = bitarray()
a.pack(bytes())
self.assertEQUAL(a, bitarray())
a.pack(b'\x00')
self.assertEQUAL(a, bitarray('0'))
a.pack(b'\xff')
self.assertEQUAL(a, bitarray('01'))
a.pack(b'\x01\x00\x7a')
self.assertEQUAL(a, bitarray('01101'))
a.pack(bytearray([0x01, 0x00, 0xff, 0xa7]))
self.assertEQUAL(a, bitarray('01101 1011'))
self.check_obj(a)
def test_pack_types(self):
a = bitarray()
a.pack(b'\0\x01') # bytes
self.assertEqual(a, bitarray('01'))
a.pack(bytearray([0, 2])) # bytearray
self.assertEqual(a, bitarray('01 01'))
a.pack(memoryview(b'\x02\0')) # memoryview
self.assertEqual(a, bitarray('01 01 10'))
if is_py3k: # Python 2's array cannot be used as buffer
a.pack(array.array('B', [0, 255, 192]))
self.assertEqual(a, bitarray('01 01 10 011'))
self.check_obj(a)
def test_pack_bitarray(self):
b = bitarray("00000000 00000001 10000000 11111111 00000000")
a = bitarray()
a.pack(bitarray(b))
self.assertEqual(a, bitarray('01110'))
self.check_obj(a)
def test_pack_self(self):
a = bitarray()
self.assertRaisesMessage(
BufferError,
"cannot resize bitarray that is exporting buffers",
a.pack, a)
def test_pack_allbytes(self):
a = bitarray()
a.pack(bytearray(range(256)))
self.assertEqual(a, bitarray('0' + 255 * '1'))
self.check_obj(a)
def test_pack_errors(self):
a = bitarray()
self.assertRaises(TypeError, a.pack, 0)
if is_py3k:
self.assertRaises(TypeError, a.pack, '1')
self.assertRaises(TypeError, a.pack, [1, 3])
tests.append(BytesTests)
# ---------------------------------------------------------------------------
class FileTests(unittest.TestCase, Util):
def setUp(self):
self.tmpdir = tempfile.mkdtemp()
self.tmpfname = os.path.join(self.tmpdir, 'testfile')
def tearDown(self):
shutil.rmtree(self.tmpdir)
def read_file(self):
with open(self.tmpfname, 'rb') as fi:
return fi.read()
def assertFileSize(self, size):
self.assertEqual(os.path.getsize(self.tmpfname), size)
def test_pickle(self):
d1 = {i: a for i, a in enumerate(self.randombitarrays())}
with open(self.tmpfname, 'wb') as fo:
pickle.dump(d1, fo)
with open(self.tmpfname, 'rb') as fi:
d2 = pickle.load(fi)
for key in d1.keys():
self.assertEQUAL(d1[key], d2[key])
@skipIf(sys.version_info[0] == 2)
def test_pickle_load(self):
# the test data file was created using bitarray 1.5.0 / Python 3.5.5
path = os.path.join(os.path.dirname(__file__), 'test_data.pickle')
with open(path, 'rb') as fi:
d = pickle.load(fi)
for i, (s, end) in enumerate([
('110', 'little'),
('011', 'big'),
('1110000001001000000000000000001', 'little'),
('0010011110000000000000000000001', 'big'),
]):
b = d['b%d' % i]
self.assertEqual(b.to01(), s)
self.assertEqual(b.endian(), end)
self.assertIsType(b, 'bitarray')
self.check_obj(b)
f = d['f%d' % i]
self.assertEqual(f.to01(), s)
self.assertEqual(f.endian(), end)
self.assertIsType(f, 'frozenbitarray')
self.check_obj(f)
@skipIf(pyodide) # pyodide has no dbm module
def test_shelve(self):
if hasattr(sys, 'gettotalrefcount'):
return
d1 = shelve.open(self.tmpfname)
stored = []
for a in self.randombitarrays():
key = str(len(a))
d1[key] = a
stored.append((key, a))
d1.close()
d2 = shelve.open(self.tmpfname)
for k, v in stored:
self.assertEQUAL(d2[k], v)
d2.close()
def test_fromfile_empty(self):
with open(self.tmpfname, 'wb') as fo:
pass
self.assertFileSize(0)
a = bitarray()
with open(self.tmpfname, 'rb') as fi:
a.fromfile(fi)
self.assertEqual(a, bitarray())
self.check_obj(a)
def test_fromfile_Foo(self):
with open(self.tmpfname, 'wb') as fo:
fo.write(b'Foo')
self.assertFileSize(3)
a = bitarray(endian='big')
with open(self.tmpfname, 'rb') as fi:
a.fromfile(fi)
self.assertEqual(a, bitarray('01000110 01101111 01101111'))
a = bitarray(endian='little')
with open(self.tmpfname, 'rb') as fi:
a.fromfile(fi)
self.assertEqual(a, bitarray('01100010 11110110 11110110'))
def test_fromfile_wrong_args(self):
a = bitarray()
self.assertRaises(TypeError, a.fromfile)
self.assertRaises(Exception, a.fromfile, 42)
self.assertRaises(Exception, a.fromfile, 'bar')
with open(self.tmpfname, 'wb') as fo:
pass
with open(self.tmpfname, 'rb') as fi:
self.assertRaises(TypeError, a.fromfile, fi, None)
def test_fromfile_erros(self):
with open(self.tmpfname, 'wb') as fo:
fo.write(b'0123456789')
self.assertFileSize(10)
a = bitarray()
with open(self.tmpfname, 'wb') as fi:
self.assertRaises(Exception, a.fromfile, fi)
if is_py3k:
with open(self.tmpfname, 'r') as fi:
self.assertRaises(TypeError, a.fromfile, fi)
def test_from_large_files(self):
for N in range(65534, 65538):
data = os.urandom(N)
with open(self.tmpfname, 'wb') as fo:
fo.write(data)
a = bitarray()
with open(self.tmpfname, 'rb') as fi:
a.fromfile(fi)
self.assertEqual(len(a), 8 * N)
self.assertEqual(buffer_info(a, 'size'), N)
self.assertEqual(a.tobytes(), data)
def test_fromfile_extend_existing(self):
with open(self.tmpfname, 'wb') as fo:
fo.write(b'Foo')
foo_le = '011000101111011011110110'
a = bitarray('1', endian='little')
with open(self.tmpfname, 'rb') as fi:
a.fromfile(fi)
self.assertEqual(a, bitarray('1' + foo_le))
for n in range(20):
a = bitarray(n, endian='little')
a.setall(1)
with open(self.tmpfname, 'rb') as fi:
a.fromfile(fi)
self.assertEqual(a, bitarray(n * '1' + foo_le))
def test_fromfile_n(self):
a = bitarray()
a.frombytes(b'ABCDEFGHIJ')
with open(self.tmpfname, 'wb') as fo:
a.tofile(fo)
self.assertFileSize(10)
with open(self.tmpfname, 'rb') as f:
a = bitarray()
a.fromfile(f, 0); self.assertEqual(a.tobytes(), b'')
a.fromfile(f, 1); self.assertEqual(a.tobytes(), b'A')
f.read(1) # skip B
a.fromfile(f, 1); self.assertEqual(a.tobytes(), b'AC')
a = bitarray()
a.fromfile(f, 2); self.assertEqual(a.tobytes(), b'DE')
a.fromfile(f, 1); self.assertEqual(a.tobytes(), b'DEF')
a.fromfile(f, 0); self.assertEqual(a.tobytes(), b'DEF')
a.fromfile(f); self.assertEqual(a.tobytes(), b'DEFGHIJ')
a.fromfile(f); self.assertEqual(a.tobytes(), b'DEFGHIJ')
self.check_obj(a)
a = bitarray()
with open(self.tmpfname, 'rb') as f:
f.read(1)
self.assertRaises(EOFError, a.fromfile, f, 10)
# check that although we received an EOFError, the bytes were read
self.assertEqual(a.tobytes(), b'BCDEFGHIJ')
a = bitarray()
with open(self.tmpfname, 'rb') as f:
# negative values - like ommiting the argument
a.fromfile(f, -1)
self.assertEqual(a.tobytes(), b'ABCDEFGHIJ')
self.assertRaises(EOFError, a.fromfile, f, 1)
def test_fromfile_BytesIO(self):
f = BytesIO(b'somedata')
a = bitarray()
a.fromfile(f, 4)
self.assertEqual(len(a), 32)
self.assertEqual(a.tobytes(), b'some')
a.fromfile(f)
self.assertEqual(len(a), 64)
self.assertEqual(a.tobytes(), b'somedata')
self.check_obj(a)
def test_tofile_empty(self):
a = bitarray()
with open(self.tmpfname, 'wb') as f:
a.tofile(f)
self.assertFileSize(0)
def test_tofile_Foo(self):
a = bitarray('0100011 001101111 01101111', endian='big')
b = a.copy()
with open(self.tmpfname, 'wb') as f:
a.tofile(f)
self.assertEQUAL(a, b)
self.assertFileSize(3)
self.assertEqual(self.read_file(), b'Foo')
def test_tofile_random(self):
for a in self.randombitarrays():
with open(self.tmpfname, 'wb') as fo:
a.tofile(fo)
n = bits2bytes(len(a))
self.assertFileSize(n)
raw = self.read_file()
self.assertEqual(len(raw), n)
self.assertEqual(raw, a.tobytes())
def test_tofile_errors(self):
n = 100
a = bitarray(8 * n)
self.assertRaises(TypeError, a.tofile)
with open(self.tmpfname, 'wb') as f:
a.tofile(f)
self.assertFileSize(n)
# write to closed file
self.assertRaises(ValueError, a.tofile, f)
if is_py3k:
with open(self.tmpfname, 'w') as f:
self.assertRaises(TypeError, a.tofile, f)
with open(self.tmpfname, 'rb') as f:
self.assertRaises(Exception, a.tofile, f)
def test_tofile_large(self):
n = 100 * 1000
a = bitarray(8 * n)
a.setall(0)
a[2::37] = 1
with open(self.tmpfname, 'wb') as f:
a.tofile(f)
self.assertFileSize(n)
raw = self.read_file()
self.assertEqual(len(raw), n)
self.assertEqual(raw, a.tobytes())
def test_tofile_ones(self):
for n in range(20):
a = n * bitarray('1', endian='little')
with open(self.tmpfname, 'wb') as fo:
a.tofile(fo)
raw = self.read_file()
self.assertEqual(len(raw), bits2bytes(len(a)))
# when we fill the unused bits in a, we can compare
a.fill()
b = bitarray(endian='little')
b.frombytes(raw)
self.assertEqual(a, b)
def test_tofile_BytesIO(self):
for n in list(range(10)) + list(range(65534, 65538)):
data = os.urandom(n)
a = bitarray(0, 'big')
a.frombytes(data)
self.assertEqual(len(a), 8 * n)
f = BytesIO()
a.tofile(f)
self.assertEqual(f.getvalue(), data)
@skipIf(sys.version_info[0] == 2)
def test_mmap(self):
with open(self.tmpfname, 'wb') as fo:
fo.write(1000 * b'\0')
with open(self.tmpfname, 'r+b') as f: # see issue #141
with mmap.mmap(f.fileno(), 0) as mapping:
a = bitarray(buffer=mapping, endian='little')
info = buffer_info(a)
self.assertFalse(info['readonly'])
self.assertTrue(info['imported'])
self.assertEqual(a, zeros(8000))
a[::2] = True
# not sure this is necessary, without 'del a', I get:
# BufferError: cannot close exported pointers exist
del a
self.assertEqual(self.read_file(), 1000 * b'\x55')
# pyodide hits emscripten mmap bug
@skipIf(sys.version_info[0] == 2 or pyodide)
def test_mmap_2(self):
with open(self.tmpfname, 'wb') as fo:
fo.write(1000 * b'\x22')
with open(self.tmpfname, 'r+b') as f:
a = bitarray(buffer=mmap.mmap(f.fileno(), 0), endian='little')
info = buffer_info(a)
self.assertFalse(info['readonly'])
self.assertTrue(info['imported'])
self.assertEqual(a, 1000 * bitarray('0100 0100'))
a[::4] = 1
self.assertEqual(self.read_file(), 1000 * b'\x33')
@skipIf(sys.version_info[0] == 2)
def test_mmap_readonly(self):
with open(self.tmpfname, 'wb') as fo:
fo.write(994 * b'\x89' + b'Veedon')
with open(self.tmpfname, 'rb') as fi: # readonly
m = mmap.mmap(fi.fileno(), 0, access=mmap.ACCESS_READ)
a = bitarray(buffer=m, endian='big')
info = buffer_info(a)
self.assertTrue(info['readonly'])
self.assertTrue(info['imported'])
self.assertRaisesMessage(TypeError,
"cannot modify read-only memory",
a.__setitem__, 0, 1)
self.assertEqual(a[:8 * 994], 994 * bitarray('1000 1001'))
self.assertEqual(a[8 * 994:].tobytes(), b'Veedon')
tests.append(FileTests)
# ----------------------------- Decode Tree ---------------------------------
alphabet_code = {
' ': bitarray('001'), '.': bitarray('0101010'),
'a': bitarray('0110'), 'b': bitarray('0001100'),
'c': bitarray('000011'), 'd': bitarray('01011'),
'e': bitarray('111'), 'f': bitarray('010100'),
'g': bitarray('101000'), 'h': bitarray('00000'),
'i': bitarray('1011'), 'j': bitarray('0111101111'),
'k': bitarray('00011010'), 'l': bitarray('01110'),
'm': bitarray('000111'), 'n': bitarray('1001'),
'o': bitarray('1000'), 'p': bitarray('101001'),
'q': bitarray('00001001101'), 'r': bitarray('1101'),
's': bitarray('1100'), 't': bitarray('0100'),
'u': bitarray('000100'), 'v': bitarray('0111100'),
'w': bitarray('011111'), 'x': bitarray('0000100011'),
'y': bitarray('101010'), 'z': bitarray('00011011110')
}
class DecodeTreeTests(unittest.TestCase, Util):
def test_create(self):
dt = decodetree(alphabet_code)
self.assertIsType(dt, 'decodetree')
self.assertIsInstance(dt, decodetree)
self.assertRaises(TypeError, decodetree, None)
self.assertRaises(TypeError, decodetree, 'foo')
d = dict(alphabet_code)
d['-'] = bitarray()
self.assertRaises(ValueError, decodetree, d)
def test_ambiguous_code(self):
for d in [
{'a': bitarray('0'), 'b': bitarray('0'), 'c': bitarray('1')},
{'a': bitarray('01'), 'b': bitarray('01'), 'c': bitarray('1')},
{'a': bitarray('0'), 'b': bitarray('01')},
{'a': bitarray('0'), 'b': bitarray('11'), 'c': bitarray('111')},
]:
self.assertRaises(ValueError, decodetree, d)
def test_sizeof(self):
dt = decodetree({'.': bitarray('1')})
self.assertTrue(0 < sys.getsizeof(dt) < 100)
dt = decodetree({'a': zeros(20)})
self.assertTrue(sys.getsizeof(dt) > 200)
def test_nodes(self):
for n in range(1, 20):
dt = decodetree({'a': zeros(n)})
self.assertEqual(dt.nodes(), n + 1)
self.assertFalse(dt.complete())
dt = decodetree({'I': bitarray('1'), 'l': bitarray('01'),
'a': bitarray('001'), 'n': bitarray('000')})
self.assertEqual(dt.nodes(), 7)
dt = decodetree(alphabet_code)
self.assertEqual(dt.nodes(), 70)
def test_complete(self):
dt = decodetree({'.': bitarray('1')})
self.assertIsInstance(dt.complete(), bool)
self.assertFalse(dt.complete())
dt = decodetree({'a': bitarray('0'),
'b': bitarray('1')})
self.assertTrue(dt.complete())
dt = decodetree({'a': bitarray('0'),
'b': bitarray('11')})
self.assertFalse(dt.complete())
dt = decodetree({'a': bitarray('0'),
'b': bitarray('11'),
'c': bitarray('10')})
self.assertTrue(dt.complete())
def test_todict(self):
t = decodetree(alphabet_code)
d = t.todict()
self.assertIsInstance(d, dict)
self.assertEqual(d, alphabet_code)
def test_decode(self):
t = decodetree(alphabet_code)
a = bitarray('1011 01110 0110 1001')
self.assertEqual(a.decode(t), ['i', 'l', 'a', 'n'])
self.assertEqual(''.join(a.iterdecode(t)), 'ilan')
a = bitarray()
self.assertEqual(a.decode(t), [])
self.assertEqual(''.join(a.iterdecode(t)), '')
self.check_obj(a)
def test_large(self):
d = {i: bitarray(bool((1 << j) & i) for j in range(10))
for i in range(1024)}
t = decodetree(d)
self.assertEqual(t.todict(), d)
self.assertEqual(t.nodes(), 2047)
self.assertTrue(sys.getsizeof(t) > 10000)
tests.append(DecodeTreeTests)
# ------------------ variable length encoding and decoding ------------------
class PrefixCodeTests(unittest.TestCase, Util):
def test_encode_string(self):
a = bitarray()
a.encode(alphabet_code, '')
self.assertEqual(a, bitarray())
a.encode(alphabet_code, 'a')
self.assertEqual(a, bitarray('0110'))
def test_encode_list(self):
a = bitarray()
a.encode(alphabet_code, [])
self.assertEqual(a, bitarray())
a.encode(alphabet_code, ['e'])
self.assertEqual(a, bitarray('111'))
def test_encode_iter(self):
a = bitarray()
d = {0: bitarray('0'), 1: bitarray('1')}
a.encode(d, iter([0, 1, 1, 0]))
self.assertEqual(a, bitarray('0110'))
def foo():
for c in 1, 1, 0, 0, 1, 1:
yield c
a.clear()
a.encode(d, foo())
a.encode(d, range(2))
self.assertEqual(a, bitarray('11001101'))
self.assertEqual(d, {0: bitarray('0'), 1: bitarray('1')})
def test_encode_symbol_not_in_code(self):
d = dict(alphabet_code)
a = bitarray()
a.encode(d, 'is')
self.assertEqual(a, bitarray('1011 1100'))
self.assertRaises(ValueError, a.encode, d, 'ilAn')
msg = "symbol not defined in prefix code"
if is_py3k:
msg += ": None"
self.assertRaisesMessage(ValueError, msg, a.encode, d, [None, 2])
def test_encode_not_iterable(self):
d = {'a': bitarray('0'), 'b': bitarray('1')}
a = bitarray()
a.encode(d, 'abba')
self.assertRaises(TypeError, a.encode, d, 42)
self.assertRaises(TypeError, a.encode, d, 1.3)
self.assertRaises(TypeError, a.encode, d, None)
self.assertEqual(a, bitarray('0110'))
def test_check_codedict_encode(self):
a = bitarray()
self.assertRaises(TypeError, a.encode, None, '')
self.assertRaises(ValueError, a.encode, {}, '')
self.assertRaises(TypeError, a.encode, {'a': 'b'}, 'a')
self.assertRaises(ValueError, a.encode, {'a': bitarray()}, 'a')
self.assertEqual(len(a), 0)
def test_check_codedict_decode(self):
a = bitarray('101')
self.assertRaises(TypeError, a.decode, 0)
self.assertRaises(ValueError, a.decode, {})
self.assertRaises(TypeError, a.decode, {'a': 42})
self.assertRaises(ValueError, a.decode, {'a': bitarray()})
self.assertEqual(a, bitarray('101'))
def test_check_codedict_iterdecode(self):
a = bitarray('1100101')
self.assertRaises(TypeError, a.iterdecode, 0)
self.assertRaises(ValueError, a.iterdecode, {})
self.assertRaises(TypeError, a.iterdecode, {'a': []})
self.assertRaises(ValueError, a.iterdecode, {'a': bitarray()})
self.assertEqual(a, bitarray('1100101'))
def test_decode_simple(self):
d = {'I': bitarray('1'), 'l': bitarray('01'),
'a': bitarray('001'), 'n': bitarray('000')}
dcopy = dict(d)
a = bitarray('101001000')
res = list("Ilan")
self.assertEqual(a.decode(d), res)
self.assertEqual(list(a.iterdecode(d)), res)
self.assertEqual(d, dcopy)
self.assertEqual(a, bitarray('101001000'))
def test_iterdecode_type(self):
a = bitarray('0110')
it = a.iterdecode(alphabet_code)
self.assertIsType(it, 'decodeiterator')
self.assertEqual(list(it), ['a'])
def test_iterdecode_remove(self):
d = {'I': bitarray('1'), 'l': bitarray('01'),
'a': bitarray('001'), 'n': bitarray('000')}
t = decodetree(d)
a = bitarray('101001000')
it = a.iterdecode(t)
del t # remove tree
self.assertEqual(''.join(it), "Ilan")
it = a.iterdecode(d)
del a
self.assertEqual(''.join(it), "Ilan")
def test_decode_empty(self):
d = {'a': bitarray('1')}
a = bitarray()
self.assertEqual(a.decode(d), [])
self.assertEqual(d, {'a': bitarray('1')})
# test decode iterator
self.assertEqual(list(a.iterdecode(d)), [])
self.assertEqual(d, {'a': bitarray('1')})
self.assertEqual(len(a), 0)
def test_decode_incomplete(self):
d = {'a': bitarray('0'), 'b': bitarray('111')}
a = bitarray('00011')
msg = "incomplete prefix code at position 3"
self.assertRaisesMessage(ValueError, msg, a.decode, d)
it = a.iterdecode(d)
self.assertIsType(it, 'decodeiterator')
self.assertRaisesMessage(ValueError, msg, list, it)
t = decodetree(d)
self.assertRaisesMessage(ValueError, msg, a.decode, t)
self.assertRaisesMessage(ValueError, msg, list, a.iterdecode(t))
self.assertEqual(a, bitarray('00011'))
self.assertEqual(d, {'a': bitarray('0'), 'b': bitarray('111')})
self.assertEqual(t.todict(), d)
def test_decode_incomplete_2(self):
a = bitarray()
a.encode(alphabet_code, "now we rise")
x = len(a)
a.extend('00')
msg = "incomplete prefix code at position %d" % x
self.assertRaisesMessage(ValueError, msg, a.decode, alphabet_code)
def test_decode_buggybitarray(self):
d = dict(alphabet_code)
# i s t
a = bitarray('1011 1100 0100 011110111001101001')
msg = "prefix code unrecognized in bitarray at position 12 .. 21"
self.assertRaisesMessage(ValueError, msg, a.decode, d)
self.assertRaisesMessage(ValueError, msg, list, a.iterdecode(d))
t = decodetree(d)
self.assertRaisesMessage(ValueError, msg, a.decode, t)
self.assertRaisesMessage(ValueError, msg, list, a.iterdecode(d))
self.check_obj(a)
self.assertEqual(t.todict(), d)
def test_iterdecode_no_term(self):
d = {'a': bitarray('0'), 'b': bitarray('111')}
a = bitarray('011')
it = a.iterdecode(d)
self.assertEqual(next(it), 'a')
self.assertRaisesMessage(ValueError,
"incomplete prefix code at position 1",
next, it)
self.assertEqual(a, bitarray('011'))
def test_iterdecode_buggybitarray(self):
d = {'a': bitarray('0')}
a = bitarray('1')
it = a.iterdecode(d)
self.assertRaises(ValueError, next, it)
self.assertEqual(a, bitarray('1'))
self.assertEqual(d, {'a': bitarray('0')})
def test_decode_buggybitarray2(self):
d = {'a': bitarray('00'), 'b': bitarray('01')}
a = bitarray('1')
self.assertRaises(ValueError, a.decode, d)
self.assertRaises(ValueError, next, a.iterdecode(d))
t = decodetree(d)
self.assertRaises(ValueError, a.decode, t)
self.assertRaises(ValueError, next, a.iterdecode(t))
self.assertEqual(a, bitarray('1'))
self.assertEqual(d, {'a': bitarray('00'), 'b': bitarray('01')})
self.assertEqual(t.todict(), d)
def test_decode_random(self):
pat1 = re.compile(r'incomplete prefix code.+\s(\d+)')
pat2 = re.compile(r'prefix code unrecognized.+\s(\d+)\s*\.\.\s*(\d+)')
t = decodetree(alphabet_code)
for a in self.randombitarrays():
try:
a.decode(t)
except ValueError as e:
msg = str(e)
m1 = pat1.match(msg)
m2 = pat2.match(msg)
self.assertFalse(m1 and m2)
if m1:
i = int(m1.group(1))
if m2:
i, j = int(m2.group(1)), int(m2.group(2))
self.assertFalse(a[i:j] in alphabet_code.values())
a[:i].decode(t)
def test_decode_ambiguous_code(self):
for d in [
{'a': bitarray('0'), 'b': bitarray('0'), 'c': bitarray('1')},
{'a': bitarray('01'), 'b': bitarray('01'), 'c': bitarray('1')},
{'a': bitarray('0'), 'b': bitarray('01')},
{'a': bitarray('0'), 'b': bitarray('11'), 'c': bitarray('111')},
]:
a = bitarray()
self.assertRaises(ValueError, a.decode, d)
self.assertRaises(ValueError, a.iterdecode, d)
self.check_obj(a)
def test_miscitems(self):
d = {None : bitarray('00'),
0 : bitarray('110'),
1 : bitarray('111'),
'' : bitarray('010'),
2 : bitarray('011')}
a = bitarray()
a.encode(d, [None, 0, 1, '', 2])
self.assertEqual(a, bitarray('00110111010011'))
self.assertEqual(a.decode(d), [None, 0, 1, '', 2])
# iterator
it = a.iterdecode(d)
self.assertEqual(next(it), None)
self.assertEqual(next(it), 0)
self.assertEqual(next(it), 1)
self.assertEqual(next(it), '')
self.assertEqual(next(it), 2)
self.assertStopIteration(it)
def test_quick_example(self):
a = bitarray()
message = 'the quick brown fox jumps over the lazy dog.'
a.encode(alphabet_code, message)
self.assertEqual(a, bitarray(
# t h e q u i c k
'0100 00000 111 001 00001001101 000100 1011 000011 00011010 001'
# b r o w n f o x
'0001100 1101 1000 011111 1001 001 010100 1000 0000100011 001'
# j u m p s o v e r
'0111101111 000100 000111 101001 1100 001 1000 0111100 111 1101'
# t h e l a z y
'001 0100 00000 111 001 01110 0110 00011011110 101010 001'
# d o g .
'01011 1000 101000 0101010'))
self.assertEqual(''.join(a.decode(alphabet_code)), message)
self.assertEqual(''.join(a.iterdecode(alphabet_code)), message)
t = decodetree(alphabet_code)
self.assertEqual(''.join(a.decode(t)), message)
self.assertEqual(''.join(a.iterdecode(t)), message)
self.check_obj(a)
tests.append(PrefixCodeTests)
# --------------------------- Buffer Import ---------------------------------
class BufferImportTests(unittest.TestCase, Util):
def test_bytes(self):
b = 100 * b'\0'
a = bitarray(buffer=b)
info = buffer_info(a)
self.assertFalse(info['allocated'])
self.assertTrue(info['readonly'])
self.assertTrue(info['imported'])
self.assertRaises(TypeError, a.setall, 1)
self.assertRaises(TypeError, a.clear)
self.assertEqual(a, zeros(800))
self.check_obj(a)
def test_bytearray(self):
b = bytearray(100 * [0])
a = bitarray(buffer=b, endian='little')
info = buffer_info(a)
self.assertFalse(info['allocated'])
self.assertFalse(info['readonly'])
self.assertTrue(info['imported'])
a[0] = 1
self.assertEqual(b[0], 1)
a[7] = 1
self.assertEqual(b[0], 129)
a[:] = 1
self.assertEqual(b, bytearray(100 * [255]))
self.assertRaises(BufferError, a.pop)
a[8:16] = bitarray('10000010', endian='big')
self.assertEqual(b, bytearray([255, 65] + 98 * [255]))
self.assertEqual(a.tobytes(), bytes(b))
for n in 7, 9:
self.assertRaises(BufferError, a.__setitem__, slice(8, 16),
bitarray(n))
b[1] = b[2] = 255
self.assertEqual(b, bytearray(100 * [255]))
self.assertEqual(a, 800 * bitarray('1'))
self.check_obj(a)
# Python 2's array cannot be used as buffer
@skipIf(sys.version_info[0] == 2)
def test_array(self):
a = array.array('B', [0, 255, 64])
b = bitarray(None, 'little', a)
self.assertEqual(b, bitarray('00000000 11111111 00000010'))
a[1] = 32
self.assertEqual(b, bitarray('00000000 00000100 00000010'))
b[3] = 1
self.assertEqual(a.tolist(), [8, 32, 64])
self.check_obj(b)
def test_bitarray(self):
a = urandom(10000)
b = bitarray(buffer=a)
# a and b are two distinct bitarrays that share the same buffer now
self.assertFalse(a is b)
a_info = buffer_info(a)
self.assertFalse(a_info['imported'])
self.assertEqual(a_info['exports'], 1)
b_info = buffer_info(b)
self.assertTrue(b_info['imported'])
self.assertEqual(b_info['exports'], 0)
# buffer address is the same!
self.assertEqual(a_info['address'],
b_info['address'])
self.assertFalse(a is b)
self.assertEqual(a, b)
b[437:461] = 0
self.assertEqual(a, b)
a[327:350] = 1
self.assertEqual(a, b)
b[101:1187] <<= 79
self.assertEqual(a, b)
a[100:9800:5] = 1
self.assertEqual(a, b)
self.assertRaisesMessage(
BufferError,
"cannot resize bitarray that is exporting buffers",
a.pop)
self.assertRaisesMessage(
BufferError,
"cannot resize imported buffer",
b.pop)
self.check_obj(a)
self.check_obj(b)
def test_bitarray_shared_sections(self):
a = urandom(0x2000)
b = bitarray(buffer=memoryview(a)[0x100:0x300])
self.assertEqual(buffer_info(b, 'address'),
buffer_info(a, 'address') + 0x100)
c = bitarray(buffer=memoryview(a)[0x200:0x800])
self.assertEqual(buffer_info(c, 'address'),
buffer_info(a, 'address') + 0x200)
self.assertEqual(a[8 * 0x100 : 8 * 0x300], b)
self.assertEqual(a[8 * 0x200 : 8 * 0x800], c)
a.setall(0)
b.setall(1)
c.setall(0)
d = bitarray(0x2000)
d.setall(0)
d[8 * 0x100 : 8 * 0x200] = 1
self.assertEqual(a, d)
def test_bitarray_range(self):
for n in range(100):
a = urandom(n, self.random_endian())
b = bitarray(buffer=a, endian=a.endian())
# an imported buffer will always have a multiple of 8 bits
self.assertEqual(len(b) % 8, 0)
self.assertEQUAL(b[:n], a)
self.check_obj(a)
self.check_obj(b)
def test_bitarray_chain(self):
a = urandom(64)
d = {0: a}
for n in range(1, 100):
d[n] = bitarray(buffer=d[n - 1])
self.assertEqual(d[99], a)
a.setall(0)
self.assertEqual(d[99], zeros(64))
a[:] = 1
self.assertTrue(d[99].all())
for c in d.values():
self.check_obj(c)
def test_frozenbitarray(self):
a = frozenbitarray('10011011 011')
self.assertTrue(buffer_info(a, 'readonly'))
self.check_obj(a)
b = bitarray(buffer=a)
self.assertTrue(buffer_info(b, 'readonly')) # also readonly
self.assertRaises(TypeError, b.__setitem__, 1, 0)
self.check_obj(b)
def test_invalid_buffer(self):
# these objects do not expose a buffer
for arg in (123, 1.23, Ellipsis, [1, 2, 3], (1, 2, 3), {1: 2},
set([1, 2, 3]),):
self.assertRaises(TypeError, bitarray, buffer=arg)
def test_del_import_object(self):
b = bytearray(100 * [0])
a = bitarray(buffer=b)
del b
self.assertEqual(a, zeros(800))
a.setall(1)
self.assertTrue(a.all())
self.check_obj(a)
def test_readonly_errors(self):
a = bitarray(buffer=b'A')
info = buffer_info(a)
self.assertTrue(info['readonly'])
self.assertTrue(info['imported'])
self.assertRaises(TypeError, a.append, True)
self.assertRaises(TypeError, a.bytereverse)
self.assertRaises(TypeError, a.clear)
self.assertRaises(TypeError, a.encode, {'a': bitarray('0')}, 'aa')
self.assertRaises(TypeError, a.extend, [0, 1, 0])
self.assertRaises(TypeError, a.fill)
self.assertRaises(TypeError, a.frombytes, b'')
self.assertRaises(TypeError, a.insert, 0, 1)
self.assertRaises(TypeError, a.invert)
self.assertRaises(TypeError, a.pack, b'\0\0\xff')
self.assertRaises(TypeError, a.pop)
self.assertRaises(TypeError, a.remove, 1)
self.assertRaises(TypeError, a.reverse)
self.assertRaises(TypeError, a.setall, 0)
self.assertRaises(TypeError, a.sort)
self.assertRaises(TypeError, a.__delitem__, 0)
self.assertRaises(TypeError, a.__delitem__, slice(None, None, 2))
self.assertRaises(TypeError, a.__setitem__, 0, 0)
self.assertRaises(TypeError, a.__iadd__, bitarray('010'))
self.assertRaises(TypeError, a.__ior__, bitarray('100'))
self.assertRaises(TypeError, a.__ixor__, bitarray('110'))
self.assertRaises(TypeError, a.__irshift__, 1)
self.assertRaises(TypeError, a.__ilshift__, 1)
self.check_obj(a)
def test_resize_errors(self):
a = bitarray(buffer=bytearray([123]))
info = buffer_info(a)
self.assertFalse(info['readonly'])
self.assertTrue(info['imported'])
self.assertRaises(BufferError, a.append, True)
self.assertRaises(BufferError, a.clear)
self.assertRaises(BufferError, a.encode, {'a': bitarray('0')}, 'aa')
self.assertRaises(BufferError, a.extend, [0, 1, 0])
self.assertRaises(BufferError, a.frombytes, b'a')
self.assertRaises(BufferError, a.insert, 0, 1)
self.assertRaises(BufferError, a.pack, b'\0\0\xff')
self.assertRaises(BufferError, a.pop)
self.assertRaises(BufferError, a.remove, 1)
self.assertRaises(BufferError, a.__delitem__, 0)
self.check_obj(a)
tests.append(BufferImportTests)
# --------------------------- Buffer Export ---------------------------------
class BufferExportTests(unittest.TestCase, Util):
def test_read_simple(self):
a = bitarray('01000001 01000010 01000011', endian='big')
v = memoryview(a)
self.assertFalse(v.readonly)
self.assertEqual(buffer_info(a, 'exports'), 1)
self.assertEqual(len(v), 3)
self.assertEqual(v[0], 65 if is_py3k else 'A')
self.assertEqual(v.tobytes(), b'ABC')
a[13] = 1
self.assertEqual(v.tobytes(), b'AFC')
w = memoryview(a) # a second buffer export
self.assertFalse(w.readonly)
self.assertEqual(buffer_info(a, 'exports'), 2)
self.check_obj(a)
def test_many_exports(self):
a = bitarray('01000111 01011111')
d = {} # put bitarrays in dict to key object around
for n in range(1, 20):
d[n] = bitarray(buffer=a)
self.assertEqual(buffer_info(a, 'exports'), n)
self.assertEqual(len(d[n]), 16)
self.check_obj(a)
def test_range(self):
for n in range(100):
a = bitarray(n)
v = memoryview(a)
self.assertEqual(len(v), bits2bytes(len(a)))
info = buffer_info(a)
self.assertFalse(info['readonly'])
self.assertFalse(info['imported'])
self.assertEqual(info['exports'], 1)
self.check_obj(a)
def test_read_random(self):
a = bitarray()
a.frombytes(os.urandom(100))
v = memoryview(a)
self.assertEqual(len(v), 100)
b = a[34 * 8 : 67 * 8]
self.assertEqual(v[34:67].tobytes(), b.tobytes())
self.assertEqual(v.tobytes(), a.tobytes())
self.check_obj(a)
def test_resize(self):
a = bitarray('011', endian='big')
v = memoryview(a)
self.assertFalse(v.readonly)
self.assertRaises(BufferError, a.append, 1)
self.assertRaises(BufferError, a.clear)
self.assertRaises(BufferError, a.encode, {'a': bitarray('0')}, 'aa')
self.assertRaises(BufferError, a.extend, '0')
self.assertRaises(BufferError, a.frombytes, b'\0')
self.assertRaises(BufferError, a.insert, 0, 1)
self.assertRaises(BufferError, a.pack, b'\0')
self.assertRaises(BufferError, a.pop)
self.assertRaises(BufferError, a.remove, 1)
self.assertRaises(BufferError, a.__delitem__, slice(0, 8))
a.fill()
self.assertEqual(v.tobytes(), a.tobytes())
self.check_obj(a)
def test_frozenbitarray(self):
a = frozenbitarray(40)
v = memoryview(a)
self.assertTrue(v.readonly)
self.assertEqual(len(v), 5)
self.assertEqual(v.tobytes(), a.tobytes())
self.check_obj(a)
def test_write(self):
a = bitarray(8000)
a.setall(0)
v = memoryview(a)
self.assertFalse(v.readonly)
v[500] = 255 if is_py3k else '\xff'
self.assertEqual(a[3999:4009], bitarray('0111111110'))
a[4003] = 0
self.assertEqual(a[3999:4009], bitarray('0111011110'))
v[301:304] = b'ABC'
self.assertEqual(a[300 * 8 : 305 * 8].tobytes(), b'\x00ABC\x00')
self.check_obj(a)
@skipIf(sys.version_info[0] == 2)
def test_write_py3(self):
a = bitarray(40)
a.setall(0)
m = memoryview(a)
v = m[1:4]
v[0] = 65
v[1] = 66
v[2] = 67
self.assertEqual(a.tobytes(), b'\x00ABC\x00')
self.check_obj(a)
tests.append(BufferExportTests)
# ---------------------------------------------------------------------------
class TestsFrozenbitarray(unittest.TestCase, Util):
def test_init(self):
a = frozenbitarray('110')
self.assertEqual(a, bitarray('110'))
self.assertEqual(a.to01(), '110')
self.assertIsInstance(a, bitarray)
self.assertIsType(a, 'frozenbitarray')
self.assertTrue(buffer_info(a, 'readonly'))
self.check_obj(a)
a = frozenbitarray(bitarray())
self.assertEQUAL(a, frozenbitarray())
self.assertIsType(a, 'frozenbitarray')
for endian in 'big', 'little':
a = frozenbitarray(0, endian)
self.assertEqual(a.endian(), endian)
self.assertIsType(a, 'frozenbitarray')
a = frozenbitarray(bitarray(0, endian))
self.assertEqual(a.endian(), endian)
self.assertIsType(a, 'frozenbitarray')
def test_methods(self):
# test a few methods which do not raise the TypeError
a = frozenbitarray('1101100')
self.assertEqual(a[2], 0)
self.assertEqual(a[:4].to01(), '1101')
self.assertEqual(a.count(), 4)
self.assertEqual(a.index(0), 2)
b = a.copy()
self.assertEqual(b, a)
self.assertIsType(b, 'frozenbitarray')
self.assertEqual(len(b), 7)
self.assertFalse(b.all())
self.assertTrue(b.any())
def test_init_from_bitarray(self):
for a in self.randombitarrays():
b = frozenbitarray(a)
self.assertFalse(b is a)
self.assertEQUAL(b, a)
c = frozenbitarray(b)
self.assertFalse(c is b)
self.assertEQUAL(c, b)
self.assertEqual(hash(c), hash(b))
def test_init_from_misc(self):
tup = 0, 1, 0, 1, 1, False, True
for obj in list(tup), tup, iter(tup), bitarray(tup):
a = frozenbitarray(obj)
self.assertEqual(a, bitarray(tup))
def test_repr(self):
a = frozenbitarray()
self.assertEqual(repr(a), "frozenbitarray()")
self.assertEqual(str(a), "frozenbitarray()")
a = frozenbitarray('10111')
self.assertEqual(repr(a), "frozenbitarray('10111')")
self.assertEqual(str(a), "frozenbitarray('10111')")
def test_immutable(self):
a = frozenbitarray('111')
self.assertRaises(TypeError, a.append, True)
self.assertRaises(TypeError, a.bytereverse)
self.assertRaises(TypeError, a.clear)
self.assertRaises(TypeError, a.encode, {'a': bitarray('0')}, 'aa')
self.assertRaises(TypeError, a.extend, [0, 1, 0])
self.assertRaises(TypeError, a.fill)
self.assertRaises(TypeError, a.frombytes, b'')
self.assertRaises(TypeError, a.insert, 0, 1)
self.assertRaises(TypeError, a.invert)
self.assertRaises(TypeError, a.pack, b'\0\0\xff')
self.assertRaises(TypeError, a.pop)
self.assertRaises(TypeError, a.remove, 1)
self.assertRaises(TypeError, a.reverse)
self.assertRaises(TypeError, a.setall, 0)
self.assertRaises(TypeError, a.sort)
self.assertRaises(TypeError, a.__delitem__, 0)
self.assertRaises(TypeError, a.__delitem__, slice(None, None, 2))
self.assertRaises(TypeError, a.__setitem__, 0, 0)
self.assertRaises(TypeError, a.__iadd__, bitarray('010'))
self.assertRaises(TypeError, a.__ior__, bitarray('100'))
self.assertRaises(TypeError, a.__ixor__, bitarray('110'))
self.assertRaises(TypeError, a.__irshift__, 1)
self.assertRaises(TypeError, a.__ilshift__, 1)
self.check_obj(a)
def test_freeze(self):
# not so much a test for frozenbitarray, but how it is initialized
a = bitarray(78)
self.assertFalse(buffer_info(a, 'readonly')) # not readonly
a._freeze()
self.assertTrue(buffer_info(a, 'readonly')) # readonly
def test_memoryview(self):
a = frozenbitarray('01000001 01000010', 'big')
v = memoryview(a)
self.assertEqual(v.tobytes(), b'AB')
self.assertRaises(TypeError, v.__setitem__, 0, 255)
def test_buffer_import_readonly(self):
b = bytes(bytearray([15, 95, 128]))
a = frozenbitarray(buffer=b, endian='big')
self.assertEQUAL(a, bitarray('00001111 01011111 10000000', 'big'))
info = buffer_info(a)
self.assertTrue(info['readonly'])
self.assertTrue(info['imported'])
def test_buffer_import_writable(self):
c = bytearray([15, 95])
self.assertRaisesMessage(
TypeError,
"cannot import writable buffer into frozenbitarray",
frozenbitarray, buffer=c)
def test_set(self):
a = frozenbitarray('1')
b = frozenbitarray('11')
c = frozenbitarray('01')
d = frozenbitarray('011')
s = set([a, b, c, d])
self.assertEqual(len(s), 4)
self.assertTrue(d in s)
self.assertFalse(frozenbitarray('0') in s)
def test_dictkey(self):
a = frozenbitarray('01')
b = frozenbitarray('1001')
d = {a: 123, b: 345}
self.assertEqual(d[frozenbitarray('01')], 123)
self.assertEqual(d[frozenbitarray(b)], 345)
def test_dictkey2(self): # taken slightly modified from issue #74
a1 = frozenbitarray([True, False])
a2 = frozenbitarray([False, False])
dct = {a1: "one", a2: "two"}
a3 = frozenbitarray([True, False])
self.assertEqual(a3, a1)
self.assertEqual(dct[a3], 'one')
def test_mix(self):
a = bitarray('110')
b = frozenbitarray('0011')
self.assertEqual(a + b, bitarray('1100011'))
a.extend(b)
self.assertEqual(a, bitarray('1100011'))
def test_hash_endianness_simple(self):
a = frozenbitarray('1', 'big')
b = frozenbitarray('1', 'little')
self.assertEqual(a, b)
self.assertEqual(hash(a), hash(b))
d = {a: 'value'}
self.assertEqual(d[b], 'value')
self.assertEqual(len(set([a, b])), 1)
def test_hash_endianness_random(self):
s = set()
n = 0
for a in self.randombitarrays():
a = frozenbitarray(a)
b = frozenbitarray(a, self.other_endian(a.endian()))
self.assertEqual(a, b)
self.assertNotEqual(a.endian(), b.endian())
self.assertEqual(hash(a), hash(b))
d = {a: 1, b: 2}
self.assertEqual(len(d), 1)
s.add(a)
s.add(b)
n += 1
self.assertEqual(len(s), n)
def test_pickle(self):
for a in self.randombitarrays():
f = frozenbitarray(a)
g = pickle.loads(pickle.dumps(f))
self.assertEqual(f, g)
self.assertEqual(f.endian(), g.endian())
self.assertTrue(str(g).startswith('frozenbitarray'))
self.check_obj(a)
tests.append(TestsFrozenbitarray)
# ---------------------------------------------------------------------------
def run(verbosity=1, repeat=1):
import bitarray.test_util as btu
tests.extend(btu.tests)
print('bitarray is installed in: %s' % os.path.dirname(__file__))
print('bitarray version: %s' % __version__)
print('sys.version: %s' % sys.version)
print('sys.prefix: %s' % sys.prefix)
print('pointer size: %d bit' % (8 * SYSINFO[0]))
print('sizeof(size_t): %d' % SYSINFO[1])
print('sizeof(bitarrayobject): %d' % SYSINFO[2])
print('PY_UINT64_T defined: %s' % SYSINFO[5])
print('USE_WORD_SHIFT: %s' % SYSINFO[7])
print('DEBUG: %s' % DEBUG)
suite = unittest.TestSuite()
for cls in tests:
for _ in range(repeat):
suite.addTest(unittest.makeSuite(cls))
runner = unittest.TextTestRunner(verbosity=verbosity)
return runner.run(suite)
if __name__ == '__main__':
run()