Skip to content

Commit

Permalink
remove newbitarray_from_pickle(), see #206 and #207
Browse files Browse the repository at this point in the history
  • Loading branch information
ilanschnell committed Aug 10, 2024
1 parent 72f22fb commit 2ea74e0
Show file tree
Hide file tree
Showing 3 changed files with 2 additions and 91 deletions.
52 changes: 0 additions & 52 deletions bitarray/_bitarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -3572,51 +3572,6 @@ newbitarray_from_index(PyTypeObject *type, PyObject *index,
return (PyObject *) res;
}

/* Return a new bitarray from pickle bytes (created by .__reduce__()).
The head byte specifies the number of pad bits, the remaining bytes
consist of the buffer itself. As the bit-endianness must be known,
we pass this function the actual argument endian_str (and not just
endian, which would default to the default bit-endianness). This way,
we can raise an exception when the endian argument was not provided to
bitarray(). Also, we only call this function with a non-empty PyBytes
object.
*/
static PyObject *
newbitarray_from_pickle(PyTypeObject *type, PyObject *bytes, char *endian_str)
{
bitarrayobject *res;
Py_ssize_t nbytes;
char *str;
unsigned char head;
int endian;

if (endian_str == NULL) {
PyErr_SetString(PyExc_ValueError, "endianness missing for pickle");
return NULL;
}
endian = endian_from_string(endian_str);
assert(endian >= 0); /* endian_str was checked before */

assert(PyBytes_Check(bytes));
nbytes = PyBytes_GET_SIZE(bytes);
assert(nbytes > 0); /* verified in bitarray_new() */
str = PyBytes_AS_STRING(bytes);
head = *str;
assert((head & 0xf8) == 0); /* verified in bitarray_new() */

if (nbytes == 1 && head)
return PyErr_Format(PyExc_ValueError,
"invalid pickle header byte: 0x%02x", head);

res = newbitarrayobject(type,
8 * (nbytes - 1) - ((Py_ssize_t) head),
endian);
if (res == NULL)
return NULL;
memcpy(res->ob_item, str + 1, (size_t) nbytes - 1);
return (PyObject *) res;
}

/* As of bitarray version 2.9.0, "bitarray(nbits)" will initialize all items
to 0 (previously, the buffer was be uninitialized).
However, for speed, one might want to create an uninitialized bitarray.
Expand Down Expand Up @@ -3664,13 +3619,6 @@ bitarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return newbitarray_from_index(type, initial, endian,
buffer == Py_None);

/* bytes (for pickling) - to be removed, see #206 */
if (PyBytes_Check(initial) && PyBytes_GET_SIZE(initial) > 0) {
char head = *PyBytes_AS_STRING(initial);
if ((head & 0xf8) == 0)
return newbitarray_from_pickle(type, initial, endian_str);
}

/* bitarray: use its endianness (when endian argument missing) */
if (bitarray_Check(initial) && endian_str == NULL)
endian = ((bitarrayobject *) initial)->endian;
Expand Down
Binary file removed bitarray/test_150.pickle
Binary file not shown.
41 changes: 2 additions & 39 deletions bitarray/test_bitarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,46 +471,11 @@ def test_string01_whitespace(self):
a = bitarray(' 0\n1\r0\t1\v0 ')
self.assertEqual(a, bitarray('01010'))

def test_rawbytes(self): # representation used for pickling
for blob, endian, s in [
(b'\x00', 'little', ''),
(b'\x07\x01', 'little', '1'),
(b'\x07\x80', 'big', '1'),
(b'\x03\xff', 'big', '11111'),
(b'\x00\x0f', 'little', '11110000'),
(b'\x00\xf0', 'big', '11110000'),
(b'\x02\x87\xda', 'big', '10000111 110110')
]:
a = bitarray(blob, endian)
self.assertEqual(a, bitarray(s))
self.assertEqual(a.endian(), endian)
self.check_obj(a)

def test_rawbytes_invalid(self):
msg3 = ("cannot extend bitarray with 'bytes', "
"use .pack() or .frombytes() instead")
# no bytes will cause TypeError
self.assertRaisesMessage(TypeError, msg3, bitarray, b'')

for blob in b'\x00', b'\x07\x80':
self.assertRaisesMessage(ValueError,
"endianness missing for pickle",
bitarray, blob)

for i in range(1, 8):
b = bytes(bytearray([i]))
# this error is raised in newbitarray_from_pickle()
self.assertRaises(ValueError, bitarray, b, 'big')
# Python 2: PyErr_Format() seems to handle "0x%02x"
# incorrectly. E.g. instead of "0x01", I get "0x1"
self.assertRaisesMessage(ValueError,
"invalid pickle header byte: 0x%02x" % b[0],
bitarray, b, 'big')

for i in range(8, 256):
b = bytes(bytearray([i]))
# we don't allow bitarrays being created from bytes
self.assertRaises(TypeError, bitarray, b)
for blob in b'', b'\x00', b'\x07\x80', b'\xff':
self.assertRaisesMessage(TypeError, msg3, bitarray, blob)

def test_bitarray_simple(self):
for n in range(10):
Expand Down Expand Up @@ -1910,8 +1875,6 @@ def check_file(self, fn):
self.check_obj(f)

def test_load(self):
# test data file was created using bitarray 1.5.0 / Python 3.5.5
self.check_file('test_150.pickle')
# using bitarray 2.8.1 / Python 3.5.5 (_bitarray_reconstructor)
self.check_file('test_281.pickle')

Expand Down

0 comments on commit 2ea74e0

Please sign in to comment.