bitarray 3.12.2__tar.gz → 3.12.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bitarray-3.12.2 → bitarray-3.12.3}/PKG-INFO +12 -10
- {bitarray-3.12.2 → bitarray-3.12.3}/README.rst +11 -9
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/__init__.pyi +22 -20
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/_bitarray.c +66 -46
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/_util.c +69 -26
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/bitarray.h +32 -7
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/test_bitarray.py +134 -29
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/test_util.py +67 -4
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray.egg-info/PKG-INFO +12 -10
- {bitarray-3.12.2 → bitarray-3.12.3}/LICENSE +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/__init__.py +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/bitfields.py +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/py.typed +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/pythoncapi_compat.h +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/test_281.pickle +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/test_bitfields.py +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/test_free_threading.py +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/util.py +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray/util.pyi +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray.egg-info/SOURCES.txt +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray.egg-info/dependency_links.txt +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray.egg-info/not-zip-safe +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/bitarray.egg-info/top_level.txt +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/pyproject.toml +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/setup.cfg +0 -0
- {bitarray-3.12.2 → bitarray-3.12.3}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bitarray
|
|
3
|
-
Version: 3.12.
|
|
3
|
+
Version: 3.12.3
|
|
4
4
|
Summary: efficient arrays of booleans -- C extension
|
|
5
5
|
Home-page: https://github.com/ilanschnell/bitarray
|
|
6
6
|
Author: Ilan Schnell
|
|
@@ -57,6 +57,7 @@ Key features
|
|
|
57
57
|
their in-place versions ``&=``, ``|=``, ``^=``, ``<<=``, ``>>=``).
|
|
58
58
|
* `Free-threading support <https://github.com/ilanschnell/bitarray/blob/master/doc/free_threading.rst>`__
|
|
59
59
|
(for GIL-disabled CPython 3.14 and later)
|
|
60
|
+
* Written to `support all platforms supported by CPython and PyPy <https://github.com/ilanschnell/bitarray/blob/master/doc/platforms.rst>`__.
|
|
60
61
|
* Fast methods for encoding and decoding variable-length
|
|
61
62
|
`prefix codes <https://github.com/ilanschnell/bitarray/blob/master/doc/prefix_codes.rst>`__.
|
|
62
63
|
* Bitarray objects support the `buffer protocol <https://github.com/ilanschnell/bitarray/blob/master/doc/buffer.rst>`__
|
|
@@ -92,7 +93,7 @@ versions. Which means you can simply:
|
|
|
92
93
|
|
|
93
94
|
.. code-block:: shell-session
|
|
94
95
|
|
|
95
|
-
$ pip install bitarray
|
|
96
|
+
$ python -m pip install bitarray
|
|
96
97
|
|
|
97
98
|
Once you have installed the package, you may want to test it:
|
|
98
99
|
|
|
@@ -101,26 +102,27 @@ Once you have installed the package, you may want to test it:
|
|
|
101
102
|
$ python -c 'import bitarray; bitarray.test()'
|
|
102
103
|
bitarray is installed in: /Users/ilan/bitarray/bitarray
|
|
103
104
|
sys.prefix: /Users/ilan/miniforge
|
|
104
|
-
bitarray version: 3.12.
|
|
105
|
+
bitarray version: 3.12.3
|
|
106
|
+
platform.machine(): arm64
|
|
107
|
+
platform.platform(): macOS-14.3-arm64-arm-64bit-Mach-O
|
|
108
|
+
sys.platform: darwin
|
|
105
109
|
sys.version: 3.15.0 (main, Oct 9 2026) [Clang 21.1.8]
|
|
106
110
|
sys.abiflags: ''
|
|
107
111
|
sys._is_gil_enabled(): True
|
|
108
112
|
pointer size: 64 bit
|
|
109
|
-
sizeof(size_t): 8
|
|
110
|
-
sizeof(bitarrayobject): 80
|
|
111
113
|
HAVE_BUILTIN_BSWAP64: 1
|
|
112
114
|
default bit-endianness: big
|
|
113
115
|
machine byte-order: little
|
|
114
116
|
Py_GIL_DISABLED: 0
|
|
115
117
|
Py_DEBUG: 0
|
|
116
118
|
DEBUG: 0
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
.........................................................................
|
|
120
|
+
................................................s........................
|
|
119
121
|
......s.........................................................
|
|
120
122
|
----------------------------------------------------------------------
|
|
121
|
-
Ran
|
|
123
|
+
Ran 723 tests in 0.163s
|
|
122
124
|
|
|
123
|
-
OK (skipped=
|
|
125
|
+
OK (skipped=2)
|
|
124
126
|
|
|
125
127
|
The ``test()`` function is part of the API. It will return
|
|
126
128
|
a ``unittest.runner.TextTestResult`` object, such that one can verify that
|
|
@@ -312,7 +314,7 @@ and can therefore be used as a dictionary key:
|
|
|
312
314
|
Reference
|
|
313
315
|
=========
|
|
314
316
|
|
|
315
|
-
bitarray version: 3.12.
|
|
317
|
+
bitarray version: 3.12.3 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
|
|
316
318
|
|
|
317
319
|
In the following, ``item`` and ``value`` are usually a single bit -
|
|
318
320
|
an integer 0 or 1.
|
|
@@ -21,6 +21,7 @@ Key features
|
|
|
21
21
|
their in-place versions ``&=``, ``|=``, ``^=``, ``<<=``, ``>>=``).
|
|
22
22
|
* `Free-threading support <https://github.com/ilanschnell/bitarray/blob/master/doc/free_threading.rst>`__
|
|
23
23
|
(for GIL-disabled CPython 3.14 and later)
|
|
24
|
+
* Written to `support all platforms supported by CPython and PyPy <https://github.com/ilanschnell/bitarray/blob/master/doc/platforms.rst>`__.
|
|
24
25
|
* Fast methods for encoding and decoding variable-length
|
|
25
26
|
`prefix codes <https://github.com/ilanschnell/bitarray/blob/master/doc/prefix_codes.rst>`__.
|
|
26
27
|
* Bitarray objects support the `buffer protocol <https://github.com/ilanschnell/bitarray/blob/master/doc/buffer.rst>`__
|
|
@@ -56,7 +57,7 @@ versions. Which means you can simply:
|
|
|
56
57
|
|
|
57
58
|
.. code-block:: shell-session
|
|
58
59
|
|
|
59
|
-
$ pip install bitarray
|
|
60
|
+
$ python -m pip install bitarray
|
|
60
61
|
|
|
61
62
|
Once you have installed the package, you may want to test it:
|
|
62
63
|
|
|
@@ -65,26 +66,27 @@ Once you have installed the package, you may want to test it:
|
|
|
65
66
|
$ python -c 'import bitarray; bitarray.test()'
|
|
66
67
|
bitarray is installed in: /Users/ilan/bitarray/bitarray
|
|
67
68
|
sys.prefix: /Users/ilan/miniforge
|
|
68
|
-
bitarray version: 3.12.
|
|
69
|
+
bitarray version: 3.12.3
|
|
70
|
+
platform.machine(): arm64
|
|
71
|
+
platform.platform(): macOS-14.3-arm64-arm-64bit-Mach-O
|
|
72
|
+
sys.platform: darwin
|
|
69
73
|
sys.version: 3.15.0 (main, Oct 9 2026) [Clang 21.1.8]
|
|
70
74
|
sys.abiflags: ''
|
|
71
75
|
sys._is_gil_enabled(): True
|
|
72
76
|
pointer size: 64 bit
|
|
73
|
-
sizeof(size_t): 8
|
|
74
|
-
sizeof(bitarrayobject): 80
|
|
75
77
|
HAVE_BUILTIN_BSWAP64: 1
|
|
76
78
|
default bit-endianness: big
|
|
77
79
|
machine byte-order: little
|
|
78
80
|
Py_GIL_DISABLED: 0
|
|
79
81
|
Py_DEBUG: 0
|
|
80
82
|
DEBUG: 0
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
.........................................................................
|
|
84
|
+
................................................s........................
|
|
83
85
|
......s.........................................................
|
|
84
86
|
----------------------------------------------------------------------
|
|
85
|
-
Ran
|
|
87
|
+
Ran 723 tests in 0.163s
|
|
86
88
|
|
|
87
|
-
OK (skipped=
|
|
89
|
+
OK (skipped=2)
|
|
88
90
|
|
|
89
91
|
The ``test()`` function is part of the API. It will return
|
|
90
92
|
a ``unittest.runner.TextTestResult`` object, such that one can verify that
|
|
@@ -276,7 +278,7 @@ and can therefore be used as a dictionary key:
|
|
|
276
278
|
Reference
|
|
277
279
|
=========
|
|
278
280
|
|
|
279
|
-
bitarray version: 3.12.
|
|
281
|
+
bitarray version: 3.12.3 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
|
|
280
282
|
|
|
281
283
|
In the following, ``item`` and ``value`` are usually a single bit -
|
|
282
284
|
an integer 0 or 1.
|
|
@@ -6,9 +6,11 @@ from abc import ABCMeta
|
|
|
6
6
|
from collections.abc import Iterable, Iterator, Sequence
|
|
7
7
|
from unittest.runner import TextTestResult
|
|
8
8
|
|
|
9
|
-
from typing import Any, BinaryIO, Dict, Union, overload, NamedTuple
|
|
9
|
+
from typing import Any, BinaryIO, Dict, Union, overload, NamedTuple, TypeVar
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
_BitarrayT = TypeVar("_BitarrayT", bound="bitarray")
|
|
13
|
+
|
|
12
14
|
CodeDict = Dict[Any, bitarray]
|
|
13
15
|
# Python 3.12 has abc.Buffer which should be used instead
|
|
14
16
|
BytesLike = Union[bytes, bytearray]
|
|
@@ -52,7 +54,7 @@ class bitarray:
|
|
|
52
54
|
stop: int = ...) -> None: ...
|
|
53
55
|
|
|
54
56
|
def clear(self) -> None: ...
|
|
55
|
-
def copy(self) ->
|
|
57
|
+
def copy(self: _BitarrayT) -> _BitarrayT: ...
|
|
56
58
|
def count(self,
|
|
57
59
|
sub_bitarray: Union[bitarray, int] = ...,
|
|
58
60
|
start: int = ...,
|
|
@@ -111,8 +113,8 @@ class bitarray:
|
|
|
111
113
|
@overload
|
|
112
114
|
def __getitem__(self, i: int) -> int: ...
|
|
113
115
|
@overload
|
|
114
|
-
def __getitem__(self,
|
|
115
|
-
s: Union[slice, bitarray, Sequence]) ->
|
|
116
|
+
def __getitem__(self: _BitarrayT,
|
|
117
|
+
s: Union[slice, bitarray, Sequence]) -> _BitarrayT: ...
|
|
116
118
|
@overload
|
|
117
119
|
def __setitem__(self,
|
|
118
120
|
i: Union[int, slice, Sequence],
|
|
@@ -127,28 +129,28 @@ class bitarray:
|
|
|
127
129
|
def __buffer__(self, flags: int, /) -> memoryview: ...
|
|
128
130
|
def __release_buffer__(self, buffer: memoryview, /) -> None: ...
|
|
129
131
|
|
|
130
|
-
def __add__(self, other: bitarray) ->
|
|
131
|
-
def __iadd__(self, other: bitarray) ->
|
|
132
|
-
def __mul__(self, n: int) ->
|
|
133
|
-
def __imul__(self, n: int) ->
|
|
134
|
-
def __rmul__(self, n: int) ->
|
|
132
|
+
def __add__(self: _BitarrayT, other: bitarray) -> _BitarrayT: ...
|
|
133
|
+
def __iadd__(self: _BitarrayT, other: bitarray) -> _BitarrayT: ...
|
|
134
|
+
def __mul__(self: _BitarrayT, n: int) -> _BitarrayT: ...
|
|
135
|
+
def __imul__(self: _BitarrayT, n: int) -> _BitarrayT: ...
|
|
136
|
+
def __rmul__(self: _BitarrayT, n: int) -> _BitarrayT: ...
|
|
135
137
|
|
|
136
138
|
def __ge__(self, other: bitarray) -> bool: ...
|
|
137
139
|
def __gt__(self, other: bitarray) -> bool: ...
|
|
138
140
|
def __le__(self, other: bitarray) -> bool: ...
|
|
139
141
|
def __lt__(self, other: bitarray) -> bool: ...
|
|
140
142
|
|
|
141
|
-
def __and__(self, other: bitarray) ->
|
|
142
|
-
def __or__(self, other: bitarray) ->
|
|
143
|
-
def __xor__(self, other: bitarray) ->
|
|
144
|
-
def __iand__(self, other: bitarray) ->
|
|
145
|
-
def __ior__(self, other: bitarray) ->
|
|
146
|
-
def __ixor__(self, other: bitarray) ->
|
|
147
|
-
def __invert__(self) ->
|
|
148
|
-
def __lshift__(self, n: int) ->
|
|
149
|
-
def __rshift__(self, n: int) ->
|
|
150
|
-
def __ilshift__(self, n: int) ->
|
|
151
|
-
def __irshift__(self, n: int) ->
|
|
143
|
+
def __and__(self: _BitarrayT, other: bitarray) -> _BitarrayT: ...
|
|
144
|
+
def __or__(self: _BitarrayT, other: bitarray) -> _BitarrayT: ...
|
|
145
|
+
def __xor__(self: _BitarrayT, other: bitarray) -> _BitarrayT: ...
|
|
146
|
+
def __iand__(self: _BitarrayT, other: bitarray) -> _BitarrayT: ...
|
|
147
|
+
def __ior__(self: _BitarrayT, other: bitarray) -> _BitarrayT: ...
|
|
148
|
+
def __ixor__(self: _BitarrayT, other: bitarray) -> _BitarrayT: ...
|
|
149
|
+
def __invert__(self: _BitarrayT) -> _BitarrayT: ...
|
|
150
|
+
def __lshift__(self: _BitarrayT, n: int) -> _BitarrayT: ...
|
|
151
|
+
def __rshift__(self: _BitarrayT, n: int) -> _BitarrayT: ...
|
|
152
|
+
def __ilshift__(self: _BitarrayT, n: int) -> _BitarrayT: ...
|
|
153
|
+
def __irshift__(self: _BitarrayT, n: int) -> _BitarrayT: ...
|
|
152
154
|
|
|
153
155
|
# data descriptors
|
|
154
156
|
@property
|
|
@@ -224,16 +224,16 @@ bytereverse(char *p, Py_ssize_t n)
|
|
|
224
224
|
static void
|
|
225
225
|
shift_r8le(unsigned char *buff, Py_ssize_t n, int k)
|
|
226
226
|
{
|
|
227
|
-
Py_ssize_t w = 0;
|
|
227
|
+
Py_ssize_t w = 0, r = n;
|
|
228
228
|
|
|
229
229
|
#if HAVE_BUILTIN_BSWAP64 || PY_LITTLE_ENDIAN /* use shift word */
|
|
230
230
|
w = n / 8; /* number of words used for shifting */
|
|
231
|
-
n
|
|
231
|
+
r = n % 8; /* number of remaining bytes */
|
|
232
232
|
#endif
|
|
233
|
-
while (
|
|
234
|
-
Py_ssize_t i =
|
|
233
|
+
while (r--) { /* shift in byte-range(8 * w, n) */
|
|
234
|
+
Py_ssize_t i = r + 8 * w;
|
|
235
235
|
buff[i] <<= k; /* shift byte */
|
|
236
|
-
if (
|
|
236
|
+
if (r || w) /* add shifted next lower byte */
|
|
237
237
|
buff[i] |= buff[i - 1] >> (8 - k);
|
|
238
238
|
}
|
|
239
239
|
assert(w == 0 || ((uintptr_t) buff) % 8 == 0);
|
|
@@ -254,16 +254,16 @@ shift_r8le(unsigned char *buff, Py_ssize_t n, int k)
|
|
|
254
254
|
static void
|
|
255
255
|
shift_r8be(unsigned char *buff, Py_ssize_t n, int k)
|
|
256
256
|
{
|
|
257
|
-
Py_ssize_t w = 0;
|
|
257
|
+
Py_ssize_t w = 0, r = n;
|
|
258
258
|
|
|
259
259
|
#if HAVE_BUILTIN_BSWAP64 || PY_BIG_ENDIAN /* use shift word */
|
|
260
260
|
w = n / 8; /* number of words used for shifting */
|
|
261
|
-
n
|
|
261
|
+
r = n % 8; /* number of remaining bytes */
|
|
262
262
|
#endif
|
|
263
|
-
while (
|
|
264
|
-
Py_ssize_t i =
|
|
263
|
+
while (r--) { /* shift in byte-range(8 * w, n) */
|
|
264
|
+
Py_ssize_t i = r + 8 * w;
|
|
265
265
|
buff[i] >>= k; /* shift byte */
|
|
266
|
-
if (
|
|
266
|
+
if (r || w) /* add shifted next lower byte */
|
|
267
267
|
buff[i] |= buff[i - 1] << (8 - k);
|
|
268
268
|
}
|
|
269
269
|
assert(w == 0 || ((uintptr_t) buff) % 8 == 0);
|
|
@@ -285,7 +285,7 @@ shift_r8be(unsigned char *buff, Py_ssize_t n, int k)
|
|
|
285
285
|
static void
|
|
286
286
|
shift_r8(bitarrayobject *self, Py_ssize_t a, Py_ssize_t b, int k)
|
|
287
287
|
{
|
|
288
|
-
unsigned char *buff
|
|
288
|
+
unsigned char *buff;
|
|
289
289
|
Py_ssize_t n = b - a; /* number of bytes to be shifted */
|
|
290
290
|
Py_ssize_t s = 0; /* distance to next aligned pointer */
|
|
291
291
|
|
|
@@ -296,8 +296,11 @@ shift_r8(bitarrayobject *self, Py_ssize_t a, Py_ssize_t b, int k)
|
|
|
296
296
|
if (k == 0 || n <= 0)
|
|
297
297
|
return;
|
|
298
298
|
|
|
299
|
+
assert(Py_SIZE(self));
|
|
300
|
+
buff = (unsigned char *) self->ob_item + a;
|
|
301
|
+
|
|
299
302
|
if (n >= 8) {
|
|
300
|
-
s = to_aligned(
|
|
303
|
+
s = to_aligned(buff);
|
|
301
304
|
buff += s; /* align pointer for casting to (uint64_t *) */
|
|
302
305
|
n -= s;
|
|
303
306
|
}
|
|
@@ -464,14 +467,18 @@ invert_span(bitarrayobject *self, Py_ssize_t a, Py_ssize_t b)
|
|
|
464
467
|
assert(self->readonly == 0);
|
|
465
468
|
|
|
466
469
|
if (n >= 64) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
+
uint64_t *words;
|
|
471
|
+
Py_ssize_t p1, p2, w;
|
|
472
|
+
|
|
473
|
+
w = aligned_words(self->ob_item, BYTES(a), b / 8, &p1, &p2);
|
|
474
|
+
|
|
475
|
+
invert_span(self, a, 8 * p1);
|
|
476
|
+
|
|
477
|
+
words = w ? (uint64_t *) (self->ob_item + p1) : NULL;
|
|
478
|
+
for (i = 0; i < w; i++)
|
|
479
|
+
words[i] = ~words[i];
|
|
470
480
|
|
|
471
|
-
invert_span(self,
|
|
472
|
-
for (i = wa; i < wb; i++)
|
|
473
|
-
wbuff[i] = ~wbuff[i];
|
|
474
|
-
invert_span(self, 64 * wb, b);
|
|
481
|
+
invert_span(self, 8 * p2, b);
|
|
475
482
|
}
|
|
476
483
|
else if (n >= 8) {
|
|
477
484
|
const Py_ssize_t ca = BYTES(a); /* char-range(ca, cb) */
|
|
@@ -574,15 +581,14 @@ count_span(bitarrayobject *self, Py_ssize_t a, Py_ssize_t b)
|
|
|
574
581
|
assert(0 <= b && b <= self->nbits);
|
|
575
582
|
|
|
576
583
|
if (n >= 64) {
|
|
577
|
-
Py_ssize_t
|
|
578
|
-
p += to_aligned((void *) (self->ob_item + p)); /* align pointer */
|
|
579
|
-
w = (b / 8 - p) / 8; /* number of (full) words to count */
|
|
584
|
+
Py_ssize_t p1, p2, w;
|
|
580
585
|
|
|
581
|
-
|
|
586
|
+
w = aligned_words(self->ob_item, BYTES(a), b / 8, &p1, &p2);
|
|
582
587
|
|
|
583
|
-
cnt += count_span(self, a, 8 *
|
|
584
|
-
|
|
585
|
-
|
|
588
|
+
cnt += count_span(self, a, 8 * p1);
|
|
589
|
+
if (w)
|
|
590
|
+
cnt += popcnt_words((uint64_t *) (self->ob_item + p1), w);
|
|
591
|
+
cnt += count_span(self, 8 * p2, b);
|
|
586
592
|
}
|
|
587
593
|
else if (n >= 8) {
|
|
588
594
|
const Py_ssize_t ca = BYTES(a); /* char-range(ca, cb) */
|
|
@@ -636,31 +642,36 @@ static Py_ssize_t
|
|
|
636
642
|
find_bit_words(bitarrayobject *self, int vi,
|
|
637
643
|
Py_ssize_t a, Py_ssize_t b, int right)
|
|
638
644
|
{
|
|
639
|
-
const
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
645
|
+
const uint64_t word = vi ? 0 : ~0;
|
|
646
|
+
const uint64_t *words;
|
|
647
|
+
Py_ssize_t p1, p2, n, q, res, i;
|
|
648
|
+
|
|
649
|
+
n = aligned_words(self->ob_item, BYTES(a), b / 8, &p1, &p2);
|
|
650
|
+
words = n ? (uint64_t *) (self->ob_item + p1) : NULL;
|
|
644
651
|
|
|
645
652
|
if (right) {
|
|
646
|
-
if ((res = find_bit(self, vi,
|
|
653
|
+
if ((res = find_bit(self, vi, 8 * p2, b, 1)) >= 0)
|
|
647
654
|
return res;
|
|
648
655
|
|
|
649
|
-
for (i =
|
|
650
|
-
if (
|
|
651
|
-
|
|
656
|
+
for (i = n - 1; i >= 0; i--) { /* skip uint64 words */
|
|
657
|
+
if (word ^ words[i]) {
|
|
658
|
+
q = 8 * p1 + 64 * i;
|
|
659
|
+
return find_bit(self, vi, q, q + 64, 1);
|
|
660
|
+
}
|
|
652
661
|
}
|
|
653
|
-
return find_bit(self, vi, a,
|
|
662
|
+
return find_bit(self, vi, a, 8 * p1, 1);
|
|
654
663
|
}
|
|
655
664
|
else {
|
|
656
|
-
if ((res = find_bit(self, vi, a,
|
|
665
|
+
if ((res = find_bit(self, vi, a, 8 * p1, 0)) >= 0)
|
|
657
666
|
return res;
|
|
658
667
|
|
|
659
|
-
for (i =
|
|
660
|
-
if (
|
|
661
|
-
|
|
668
|
+
for (i = 0; i < n; i++) { /* skip uint64 words */
|
|
669
|
+
if (word ^ words[i]) {
|
|
670
|
+
q = 8 * p1 + 64 * i;
|
|
671
|
+
return find_bit(self, vi, q, q + 64, 0);
|
|
672
|
+
}
|
|
662
673
|
}
|
|
663
|
-
return find_bit(self, vi,
|
|
674
|
+
return find_bit(self, vi, 8 * p2, b, 0);
|
|
664
675
|
}
|
|
665
676
|
}
|
|
666
677
|
|
|
@@ -3428,16 +3439,25 @@ bitwise_lock_held(bitarrayobject *self,
|
|
|
3428
3439
|
bitarrayobject *other, const char oper)
|
|
3429
3440
|
{
|
|
3430
3441
|
const Py_ssize_t nbytes = Py_SIZE(self);
|
|
3431
|
-
|
|
3432
|
-
Py_ssize_t i;
|
|
3442
|
+
Py_ssize_t cwords, i;
|
|
3433
3443
|
char *buff_s = self->ob_item;
|
|
3434
3444
|
char *buff_o = other->ob_item;
|
|
3435
|
-
uint64_t *wbuff_s
|
|
3436
|
-
uint64_t *wbuff_o = WBUFF(other);
|
|
3445
|
+
uint64_t *wbuff_s, *wbuff_o;
|
|
3437
3446
|
|
|
3438
3447
|
assert(self->nbits == other->nbits);
|
|
3439
3448
|
assert(self->endian == other->endian);
|
|
3440
3449
|
assert(self->readonly == 0);
|
|
3450
|
+
|
|
3451
|
+
if (((uintptr_t) buff_s) % 8 == 0 &&
|
|
3452
|
+
((uintptr_t) buff_o) % 8 == 0) {
|
|
3453
|
+
cwords = nbytes / 8; /* complete aligned 64-bit words */
|
|
3454
|
+
wbuff_s = WBUFF(self);
|
|
3455
|
+
wbuff_o = WBUFF(other);
|
|
3456
|
+
}
|
|
3457
|
+
else {
|
|
3458
|
+
cwords = 0;
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3441
3461
|
switch (oper) {
|
|
3442
3462
|
case '&':
|
|
3443
3463
|
for (i = 0; i < cwords; i++)
|
|
@@ -5120,7 +5140,7 @@ static PyTypeObject Bitarray_Type = {
|
|
|
5120
5140
|
&bitarray_as_number, /* tp_as_number */
|
|
5121
5141
|
&bitarray_as_sequence, /* tp_as_sequence */
|
|
5122
5142
|
&bitarray_as_mapping, /* tp_as_mapping */
|
|
5123
|
-
|
|
5143
|
+
0, /* tp_hash */
|
|
5124
5144
|
0, /* tp_call */
|
|
5125
5145
|
0, /* tp_str */
|
|
5126
5146
|
PyObject_GenericGetAttr, /* tp_getattro */
|
|
@@ -205,6 +205,21 @@ count_n_lock_held(bitarrayobject *a, Py_ssize_t n, int vi)
|
|
|
205
205
|
return i;
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
+
static inline int
|
|
209
|
+
check_aligned(bitarrayobject *a)
|
|
210
|
+
{
|
|
211
|
+
#ifdef __sparc__
|
|
212
|
+
if (((uintptr_t) a->ob_item) % 8) {
|
|
213
|
+
PyErr_SetString(PyExc_NotImplementedError, "unaligned buffers "
|
|
214
|
+
"not supported on SPARC for this function");
|
|
215
|
+
return -1;
|
|
216
|
+
}
|
|
217
|
+
#else
|
|
218
|
+
(void) a; /* silence potential compiler warning about unused a */
|
|
219
|
+
#endif
|
|
220
|
+
return 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
208
223
|
static PyObject *
|
|
209
224
|
count_n(PyObject *module, PyObject *args)
|
|
210
225
|
{
|
|
@@ -220,6 +235,8 @@ count_n(PyObject *module, PyObject *args)
|
|
|
220
235
|
PyErr_SetString(PyExc_ValueError, "non-negative integer expected");
|
|
221
236
|
return NULL;
|
|
222
237
|
}
|
|
238
|
+
if (check_aligned(a) < 0)
|
|
239
|
+
return NULL;
|
|
223
240
|
|
|
224
241
|
Py_BEGIN_CRITICAL_SECTION(a);
|
|
225
242
|
nbits = a->nbits;
|
|
@@ -250,19 +267,22 @@ static PyObject *
|
|
|
250
267
|
parity(PyObject *module, PyObject *obj)
|
|
251
268
|
{
|
|
252
269
|
bitarrayobject *a;
|
|
253
|
-
uint64_t x
|
|
254
|
-
Py_ssize_t i;
|
|
270
|
+
uint64_t x;
|
|
271
|
+
Py_ssize_t i, p1, p2;
|
|
255
272
|
|
|
256
273
|
if (ensure_bitarray(obj) < 0)
|
|
257
274
|
return NULL;
|
|
258
275
|
|
|
259
276
|
a = (bitarrayobject *) obj;
|
|
260
277
|
Py_BEGIN_CRITICAL_SECTION(a);
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
i =
|
|
264
|
-
|
|
265
|
-
|
|
278
|
+
x = (unsigned char) zlc(a);
|
|
279
|
+
aligned_words(a->ob_item, 0, a->nbits / 8, &p1, &p2);
|
|
280
|
+
for (i = 0; i < p1; i++)
|
|
281
|
+
x ^= (unsigned char) a->ob_item[i];
|
|
282
|
+
for (i = p1; i < p2; i += 8)
|
|
283
|
+
x ^= *((uint64_t *) (a->ob_item + i));
|
|
284
|
+
for (i = p2; i < a->nbits / 8; i++)
|
|
285
|
+
x ^= (unsigned char) a->ob_item[i];
|
|
266
286
|
Py_END_CRITICAL_SECTION();
|
|
267
287
|
return PyLong_FromLong(parity_64(x));
|
|
268
288
|
}
|
|
@@ -460,6 +480,8 @@ binary_function(PyObject *args, const char *format, const char oper)
|
|
|
460
480
|
bitarray_type, (PyObject *) &a,
|
|
461
481
|
bitarray_type, (PyObject *) &b))
|
|
462
482
|
return NULL;
|
|
483
|
+
if (check_aligned(a) < 0 || check_aligned(b) < 0)
|
|
484
|
+
return NULL;
|
|
463
485
|
|
|
464
486
|
Py_BEGIN_CRITICAL_SECTION2(a, b);
|
|
465
487
|
if (ensure_eq_size_endian(a, b) == 0)
|
|
@@ -562,6 +584,8 @@ correspond_all(PyObject *module, PyObject *args)
|
|
|
562
584
|
bitarray_type, (PyObject *) &a,
|
|
563
585
|
bitarray_type, (PyObject *) &b))
|
|
564
586
|
return NULL;
|
|
587
|
+
if (check_aligned(a) < 0 || check_aligned(b) < 0)
|
|
588
|
+
return NULL;
|
|
565
589
|
|
|
566
590
|
Py_BEGIN_CRITICAL_SECTION2(a, b);
|
|
567
591
|
if (ensure_eq_size_endian(a, b) == 0)
|
|
@@ -582,21 +606,22 @@ byteswap_lock_held(Py_buffer view, Py_ssize_t n)
|
|
|
582
606
|
{
|
|
583
607
|
char *buff = view.buf;
|
|
584
608
|
Py_ssize_t m = view.len / n, k;
|
|
609
|
+
int is_aligned = ((uintptr_t) buff) % 8 == 0;
|
|
585
610
|
|
|
586
611
|
assert(n >= 1 && n * m == view.len);
|
|
587
612
|
|
|
588
|
-
if (n == 8 && HAVE_BUILTIN_BSWAP64) {
|
|
613
|
+
if (is_aligned && n == 8 && HAVE_BUILTIN_BSWAP64) {
|
|
589
614
|
uint64_t *w = (uint64_t *) buff;
|
|
590
615
|
for (k = 0; k < m; k++)
|
|
591
616
|
w[k] = builtin_bswap64(w[k]);
|
|
592
617
|
}
|
|
593
618
|
#if (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 5)))
|
|
594
|
-
else if (n == 4) {
|
|
619
|
+
else if (is_aligned && n == 4) {
|
|
595
620
|
uint32_t *w = (uint32_t *) buff;
|
|
596
621
|
for (k = 0; k < m; k++)
|
|
597
622
|
w[k] = __builtin_bswap32(w[k]);
|
|
598
623
|
}
|
|
599
|
-
else if (n == 2) {
|
|
624
|
+
else if (is_aligned && n == 2) {
|
|
600
625
|
uint16_t *w = (uint16_t *) buff;
|
|
601
626
|
for (k = 0; k < m; k++)
|
|
602
627
|
w[k] = __builtin_bswap16(w[k]);
|
|
@@ -1523,7 +1548,7 @@ sc_last_pop_seg(const Py_ssize_t *rts, Py_ssize_t nseg)
|
|
|
1523
1548
|
/* expose sc_rts() to Python during debug mode for testing */
|
|
1524
1549
|
#ifndef NDEBUG
|
|
1525
1550
|
static PyObject *
|
|
1526
|
-
|
|
1551
|
+
mod_sc_rts(PyObject *module, PyObject *obj)
|
|
1527
1552
|
{
|
|
1528
1553
|
PyObject *list;
|
|
1529
1554
|
bitarrayobject *a;
|
|
@@ -1857,6 +1882,8 @@ sc_encode(PyObject *module, PyObject *obj)
|
|
|
1857
1882
|
|
|
1858
1883
|
if (ensure_bitarray(obj) < 0)
|
|
1859
1884
|
return NULL;
|
|
1885
|
+
if (check_aligned((bitarrayobject *) obj) < 0)
|
|
1886
|
+
return NULL;
|
|
1860
1887
|
|
|
1861
1888
|
out = PyBytes_FromStringAndSize(NULL, ALLOC_SIZE);
|
|
1862
1889
|
if (out == NULL)
|
|
@@ -2627,7 +2654,7 @@ static PyTypeObject CHDI_Type = {
|
|
|
2627
2654
|
|
|
2628
2655
|
#ifndef NDEBUG
|
|
2629
2656
|
static PyObject *
|
|
2630
|
-
|
|
2657
|
+
mod_setup_table(PyObject *module, PyObject *obj)
|
|
2631
2658
|
{
|
|
2632
2659
|
char table[256];
|
|
2633
2660
|
|
|
@@ -2641,7 +2668,7 @@ module_setup_table(PyObject *module, PyObject *obj)
|
|
|
2641
2668
|
This makes testing easier, because the int result would depend
|
|
2642
2669
|
on the machine byteorder. */
|
|
2643
2670
|
static PyObject *
|
|
2644
|
-
|
|
2671
|
+
mod_zlw(PyObject *module, PyObject *obj)
|
|
2645
2672
|
{
|
|
2646
2673
|
bitarrayobject *a, *res;
|
|
2647
2674
|
uint64_t w;
|
|
@@ -2663,7 +2690,22 @@ module_zlw(PyObject *module, PyObject *obj)
|
|
|
2663
2690
|
}
|
|
2664
2691
|
|
|
2665
2692
|
static PyObject *
|
|
2666
|
-
|
|
2693
|
+
mod_aligned_words(PyObject *module, PyObject *args)
|
|
2694
|
+
{
|
|
2695
|
+
Py_ssize_t start, stop, p1, p2, n;
|
|
2696
|
+
bitarrayobject *a;
|
|
2697
|
+
|
|
2698
|
+
if (!PyArg_ParseTuple(args, "O!nn", bitarray_type, (PyObject *) &a,
|
|
2699
|
+
&start, &stop))
|
|
2700
|
+
return NULL;
|
|
2701
|
+
Py_BEGIN_CRITICAL_SECTION(a);
|
|
2702
|
+
n = aligned_words(a->ob_item, start, stop, &p1, &p2);
|
|
2703
|
+
Py_END_CRITICAL_SECTION();
|
|
2704
|
+
return Py_BuildValue("nnn", n, p1, p2);
|
|
2705
|
+
}
|
|
2706
|
+
|
|
2707
|
+
static PyObject *
|
|
2708
|
+
mod_adjust_slice(PyObject *module, PyObject *args)
|
|
2667
2709
|
{
|
|
2668
2710
|
Py_ssize_t length, slicelength, start, stop, step;
|
|
2669
2711
|
|
|
@@ -2674,7 +2716,7 @@ module_adjust_slice(PyObject *module, PyObject *args)
|
|
|
2674
2716
|
}
|
|
2675
2717
|
|
|
2676
2718
|
static PyObject *
|
|
2677
|
-
|
|
2719
|
+
mod_cfw(PyObject *module, PyObject *args) /* count_from_word() */
|
|
2678
2720
|
{
|
|
2679
2721
|
bitarrayobject *a;
|
|
2680
2722
|
Py_ssize_t res, i;
|
|
@@ -2690,7 +2732,7 @@ module_cfw(PyObject *module, PyObject *args) /* count_from_word() */
|
|
|
2690
2732
|
}
|
|
2691
2733
|
|
|
2692
2734
|
static PyObject *
|
|
2693
|
-
|
|
2735
|
+
mod_d2i(PyObject *module, PyObject *args)
|
|
2694
2736
|
{
|
|
2695
2737
|
int m;
|
|
2696
2738
|
char c;
|
|
@@ -2701,7 +2743,7 @@ module_d2i(PyObject *module, PyObject *args)
|
|
|
2701
2743
|
}
|
|
2702
2744
|
|
|
2703
2745
|
static PyObject *
|
|
2704
|
-
|
|
2746
|
+
mod_read_n(PyObject *module, PyObject *args)
|
|
2705
2747
|
{
|
|
2706
2748
|
PyObject *iter;
|
|
2707
2749
|
Py_ssize_t i;
|
|
@@ -2715,7 +2757,7 @@ module_read_n(PyObject *module, PyObject *args)
|
|
|
2715
2757
|
}
|
|
2716
2758
|
|
|
2717
2759
|
static PyObject *
|
|
2718
|
-
|
|
2760
|
+
mod_write_n(PyObject *module, PyObject *args)
|
|
2719
2761
|
{
|
|
2720
2762
|
PyObject *res;
|
|
2721
2763
|
char *str;
|
|
@@ -2803,14 +2845,15 @@ static PyMethodDef module_functions[] = {
|
|
|
2803
2845
|
|
|
2804
2846
|
#ifndef NDEBUG
|
|
2805
2847
|
/* functions exposed in debug mode for testing */
|
|
2806
|
-
{"_setup_table",
|
|
2807
|
-
{"_zlw",
|
|
2808
|
-
{"
|
|
2809
|
-
{"
|
|
2810
|
-
{"
|
|
2811
|
-
{"
|
|
2812
|
-
{"
|
|
2813
|
-
{"
|
|
2848
|
+
{"_setup_table", (PyCFunction) mod_setup_table, METH_O, 0},
|
|
2849
|
+
{"_zlw", (PyCFunction) mod_zlw, METH_O, 0},
|
|
2850
|
+
{"_aligned_words", (PyCFunction) mod_aligned_words, METH_VARARGS, 0},
|
|
2851
|
+
{"_adjust_slice", (PyCFunction) mod_adjust_slice, METH_VARARGS, 0},
|
|
2852
|
+
{"_cfw", (PyCFunction) mod_cfw, METH_VARARGS, 0},
|
|
2853
|
+
{"_d2i", (PyCFunction) mod_d2i, METH_VARARGS, 0},
|
|
2854
|
+
{"_read_n", (PyCFunction) mod_read_n, METH_VARARGS, 0},
|
|
2855
|
+
{"_write_n", (PyCFunction) mod_write_n, METH_VARARGS, 0},
|
|
2856
|
+
{"_sc_rts", (PyCFunction) mod_sc_rts, METH_O, 0},
|
|
2814
2857
|
#endif
|
|
2815
2858
|
|
|
2816
2859
|
{NULL} /* sentinel */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Author: Ilan Schnell
|
|
6
6
|
*/
|
|
7
|
-
#define BITARRAY_VERSION "3.12.
|
|
7
|
+
#define BITARRAY_VERSION "3.12.3"
|
|
8
8
|
|
|
9
9
|
#ifdef STDC_HEADERS
|
|
10
10
|
# include <stddef.h>
|
|
@@ -124,19 +124,22 @@ zlc(bitarrayobject *self) /* zlc = zeroed last char */
|
|
|
124
124
|
/* Return a uint64_t word representing the last (up to 63) remaining bits
|
|
125
125
|
of the buffer. All missing bytes (to complete the word) and padbits are
|
|
126
126
|
treated as zeros.
|
|
127
|
+
The remaining bytes are copied, so the buffer need not be word-aligned.
|
|
128
|
+
The result does not, in general, correspond to an aligned 64-bit
|
|
129
|
+
word in the buffer.
|
|
127
130
|
If the length of the bitarray is a multiple of 64 (which also includes
|
|
128
131
|
an empty bitarray), 0 is returned. */
|
|
129
132
|
static inline uint64_t
|
|
130
133
|
zlw(bitarrayobject *self) /* zlw = zeroed last word */
|
|
131
134
|
{
|
|
132
135
|
const size_t nbits = self->nbits;
|
|
133
|
-
const size_t
|
|
134
|
-
const size_t nr = (nbits % 64) / 8;
|
|
136
|
+
const size_t offset = (nbits / 64) * 8; /* bytes in complete words */
|
|
137
|
+
const size_t nr = (nbits % 64) / 8; /* complete remaining bytes */
|
|
135
138
|
uint64_t res = 0;
|
|
136
139
|
|
|
137
|
-
assert(
|
|
140
|
+
assert(offset + nr == nbits / 8);
|
|
138
141
|
if (nr)
|
|
139
|
-
memcpy((char *) &res, self->ob_item +
|
|
142
|
+
memcpy((char *) &res, self->ob_item + offset, nr);
|
|
140
143
|
if (nbits % 8)
|
|
141
144
|
*(((char *) &res) + nr) = zlc(self);
|
|
142
145
|
|
|
@@ -252,12 +255,35 @@ setup_table(char *table, char kop)
|
|
|
252
255
|
cause problems on older ones. Moreover, it may lead to slowdown (even
|
|
253
256
|
on modern compilers). */
|
|
254
257
|
static inline int
|
|
255
|
-
to_aligned(void *p)
|
|
258
|
+
to_aligned(const void *p)
|
|
256
259
|
{
|
|
257
260
|
int r = ((uintptr_t) p) % 8;
|
|
258
261
|
return (8 - r) % 8;
|
|
259
262
|
}
|
|
260
263
|
|
|
264
|
+
/* Return number of complete aligned words in byte-range(start, stop).
|
|
265
|
+
Set byte offsets *p1 and *p2 such that the aligned words are in
|
|
266
|
+
byte-range(*p1, *p2). */
|
|
267
|
+
static inline Py_ssize_t
|
|
268
|
+
aligned_words(const char *buff, Py_ssize_t start, Py_ssize_t stop,
|
|
269
|
+
Py_ssize_t *p1, Py_ssize_t *p2)
|
|
270
|
+
{
|
|
271
|
+
Py_ssize_t n = 0;
|
|
272
|
+
|
|
273
|
+
assert(0 <= start && start <= stop);
|
|
274
|
+
|
|
275
|
+
if (start < stop) {
|
|
276
|
+
/* non-empty buffer cannot be NULL */
|
|
277
|
+
start += to_aligned(buff + start);
|
|
278
|
+
if (start > stop)
|
|
279
|
+
start = stop;
|
|
280
|
+
n = (stop - start) / 8;
|
|
281
|
+
}
|
|
282
|
+
*p1 = start;
|
|
283
|
+
*p2 = start + 8 * n;
|
|
284
|
+
return n;
|
|
285
|
+
}
|
|
286
|
+
|
|
261
287
|
/* population count of n words starting at uint64_t pointer w */
|
|
262
288
|
static inline Py_ssize_t
|
|
263
289
|
popcnt_words(uint64_t *w, Py_ssize_t n)
|
|
@@ -265,7 +291,6 @@ popcnt_words(uint64_t *w, Py_ssize_t n)
|
|
|
265
291
|
Py_ssize_t cnt = 0;
|
|
266
292
|
|
|
267
293
|
assert(n >= 0);
|
|
268
|
-
assert(n == 0 || ((uintptr_t) w) % 8 == 0);
|
|
269
294
|
while (n--)
|
|
270
295
|
cnt += popcnt_64(*w++);
|
|
271
296
|
return cnt;
|
|
@@ -33,6 +33,7 @@ import weakref
|
|
|
33
33
|
|
|
34
34
|
is_emscripten = platform.machine() in ('wasm32', 'wasm64')
|
|
35
35
|
is_pypy = platform.python_implementation() == 'PyPy'
|
|
36
|
+
is_sparc = platform.machine().lower().startswith("sparc")
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
from bitarray import (bitarray, frozenbitarray, bits2bytes, decodetree,
|
|
@@ -73,6 +74,26 @@ class Util:
|
|
|
73
74
|
for a in self.randombitarrays():
|
|
74
75
|
yield a.tolist()
|
|
75
76
|
|
|
77
|
+
def unaligned_buffers(self, size=32, endian=None):
|
|
78
|
+
for remainder in range(8):
|
|
79
|
+
owner = bytearray(size + 8)
|
|
80
|
+
base = bitarray(buffer=owner).buffer_info().address
|
|
81
|
+
offset = (remainder - base) % 8
|
|
82
|
+
buffer = memoryview(owner)[offset:offset + size]
|
|
83
|
+
a = bitarray(buffer=buffer, endian=endian)
|
|
84
|
+
|
|
85
|
+
self.assertEqual(len(a), 8 * size)
|
|
86
|
+
self.assertEqual(a.buffer_info().address % 8, remainder)
|
|
87
|
+
yield a
|
|
88
|
+
|
|
89
|
+
self.assertEqual(owner[:offset], bytearray(offset))
|
|
90
|
+
self.assertEqual(owner[offset + size:], bytearray(8 - offset))
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def is_unaligned(a):
|
|
94
|
+
info = a.buffer_info()
|
|
95
|
+
return info.address % 8 != 0
|
|
96
|
+
|
|
76
97
|
@staticmethod
|
|
77
98
|
def opposite_endian(endian):
|
|
78
99
|
t = {'little': 'big',
|
|
@@ -1735,6 +1756,20 @@ class MiscTests(unittest.TestCase, Util):
|
|
|
1735
1756
|
for i in range(len(a)):
|
|
1736
1757
|
self.assertEqual(a[i], b[i + 1234])
|
|
1737
1758
|
|
|
1759
|
+
def test_subclass_inplace(self) -> None:
|
|
1760
|
+
class SubBitarray(bitarray):
|
|
1761
|
+
pass
|
|
1762
|
+
|
|
1763
|
+
a: SubBitarray = SubBitarray('101')
|
|
1764
|
+
a += bitarray()
|
|
1765
|
+
a *= 1
|
|
1766
|
+
a &= bitarray('110')
|
|
1767
|
+
a |= bitarray('001')
|
|
1768
|
+
a ^= bitarray('010')
|
|
1769
|
+
a <<= 1
|
|
1770
|
+
a >>= 1
|
|
1771
|
+
self.assertIs(type(a), SubBitarray)
|
|
1772
|
+
|
|
1738
1773
|
@unittest.skipIf(is_pypy, "skip test on PyPy")
|
|
1739
1774
|
def test_overflow(self):
|
|
1740
1775
|
a = bitarray(1)
|
|
@@ -1773,8 +1808,7 @@ class MiscTests(unittest.TestCase, Util):
|
|
|
1773
1808
|
self.assertIsInstance(a, abc.MutableSequence)
|
|
1774
1809
|
if sys.version_info[:2] >= (3, 12):
|
|
1775
1810
|
self.assertIsInstance(a, abc.Buffer)
|
|
1776
|
-
|
|
1777
|
-
self.assertFalse(isinstance(a, abc.Hashable))
|
|
1811
|
+
self.assertFalse(isinstance(a, abc.Hashable))
|
|
1778
1812
|
|
|
1779
1813
|
# ---------------------------------------------------------------------------
|
|
1780
1814
|
|
|
@@ -2080,14 +2114,16 @@ class SpecialMethodTests(unittest.TestCase, Util):
|
|
|
2080
2114
|
|
|
2081
2115
|
# -------------------------- Sequence methods tests -------------------------
|
|
2082
2116
|
|
|
2083
|
-
class SequenceTests(unittest.TestCase
|
|
2117
|
+
class SequenceTests(unittest.TestCase):
|
|
2084
2118
|
|
|
2085
2119
|
def test_len(self):
|
|
2086
2120
|
for n in range(100):
|
|
2087
2121
|
a = bitarray(n)
|
|
2088
2122
|
self.assertEqual(len(a), n)
|
|
2089
2123
|
|
|
2090
|
-
|
|
2124
|
+
class ConcatTests(unittest.TestCase, Util):
|
|
2125
|
+
|
|
2126
|
+
def test_simple(self):
|
|
2091
2127
|
a = bitarray('001')
|
|
2092
2128
|
b = a + bitarray('110')
|
|
2093
2129
|
self.assertEQUAL(b, bitarray('001110'))
|
|
@@ -2103,7 +2139,7 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2103
2139
|
self.assertRaises(TypeError, a.__add__, 42)
|
|
2104
2140
|
self.assertRaises(ValueError, a.__add__, b'1101')
|
|
2105
2141
|
|
|
2106
|
-
def
|
|
2142
|
+
def test_random(self):
|
|
2107
2143
|
for a in self.randombitarrays():
|
|
2108
2144
|
aa = a.copy()
|
|
2109
2145
|
for b in self.randombitarrays():
|
|
@@ -2116,7 +2152,7 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2116
2152
|
self.assertEQUAL(a, aa)
|
|
2117
2153
|
self.assertEQUAL(b, bb)
|
|
2118
2154
|
|
|
2119
|
-
def
|
|
2155
|
+
def test_frozenbitarray(self):
|
|
2120
2156
|
a = frozenbitarray('001')
|
|
2121
2157
|
b = a + bitarray('011')
|
|
2122
2158
|
self.assertIs(type(b), frozenbitarray)
|
|
@@ -2124,7 +2160,7 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2124
2160
|
self.assertTrue(b.readonly)
|
|
2125
2161
|
self.check_obj(b)
|
|
2126
2162
|
|
|
2127
|
-
def
|
|
2163
|
+
def test_inplace(self):
|
|
2128
2164
|
a = bitarray('001')
|
|
2129
2165
|
a += bitarray('110')
|
|
2130
2166
|
self.assertEqual(a, bitarray('001110'))
|
|
@@ -2151,7 +2187,9 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2151
2187
|
self.assertIs(c, d)
|
|
2152
2188
|
self.check_obj(d)
|
|
2153
2189
|
|
|
2154
|
-
|
|
2190
|
+
class RepeatTests(unittest.TestCase, Util):
|
|
2191
|
+
|
|
2192
|
+
def test_explicit(self):
|
|
2155
2193
|
for m, s, r in [
|
|
2156
2194
|
( 0, '', ''),
|
|
2157
2195
|
( 0, '1001111', ''),
|
|
@@ -2168,14 +2206,14 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2168
2206
|
c *= m
|
|
2169
2207
|
self.assertEqual(c, bitarray(r))
|
|
2170
2208
|
|
|
2171
|
-
def
|
|
2209
|
+
def test_wrong_args(self):
|
|
2172
2210
|
a = bitarray()
|
|
2173
2211
|
self.assertRaises(TypeError, a.__mul__, None)
|
|
2174
2212
|
self.assertRaises(TypeError, a.__mul__, 2.0)
|
|
2175
2213
|
self.assertRaises(TypeError, a.__imul__, None)
|
|
2176
2214
|
self.assertRaises(TypeError, a.__imul__, 3.0)
|
|
2177
2215
|
|
|
2178
|
-
def
|
|
2216
|
+
def test_frozenbitarray(self):
|
|
2179
2217
|
a = frozenbitarray('001')
|
|
2180
2218
|
b = 3 * a
|
|
2181
2219
|
self.assertIs(type(b), frozenbitarray)
|
|
@@ -2183,7 +2221,7 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2183
2221
|
self.assertTrue(b.readonly)
|
|
2184
2222
|
self.check_obj(b)
|
|
2185
2223
|
|
|
2186
|
-
def
|
|
2224
|
+
def test_random(self):
|
|
2187
2225
|
for a in self.randombitarrays():
|
|
2188
2226
|
b = a.copy()
|
|
2189
2227
|
for m in list(range(-3, 5)) + [randint(5, 200)]:
|
|
@@ -2200,7 +2238,9 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2200
2238
|
|
|
2201
2239
|
self.assertEQUAL(a, b)
|
|
2202
2240
|
|
|
2203
|
-
|
|
2241
|
+
class ContainsTests(unittest.TestCase):
|
|
2242
|
+
|
|
2243
|
+
def test_simple(self):
|
|
2204
2244
|
a = bitarray()
|
|
2205
2245
|
self.assertFalse(0 in a)
|
|
2206
2246
|
self.assertFalse(1 in a)
|
|
@@ -2215,7 +2255,7 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2215
2255
|
self.assertTrue(0 in a)
|
|
2216
2256
|
self.assertTrue(1 in a)
|
|
2217
2257
|
|
|
2218
|
-
def
|
|
2258
|
+
def test_errors(self):
|
|
2219
2259
|
a = bitarray()
|
|
2220
2260
|
self.assertFalse(a.__contains__(1))
|
|
2221
2261
|
a.append(1)
|
|
@@ -2227,7 +2267,7 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2227
2267
|
self.assertRaises(ValueError, a.__contains__, 2)
|
|
2228
2268
|
self.assertRaises(ValueError, a.__contains__, -1)
|
|
2229
2269
|
|
|
2230
|
-
def
|
|
2270
|
+
def test_range(self):
|
|
2231
2271
|
for n in range(2, 50):
|
|
2232
2272
|
a = zeros(n)
|
|
2233
2273
|
self.assertTrue(0 in a)
|
|
@@ -2242,7 +2282,7 @@ class SequenceTests(unittest.TestCase, Util):
|
|
|
2242
2282
|
self.assertTrue(True in a)
|
|
2243
2283
|
self.assertTrue(False in a)
|
|
2244
2284
|
|
|
2245
|
-
def
|
|
2285
|
+
def test_explicit(self):
|
|
2246
2286
|
a = bitarray('011010000001')
|
|
2247
2287
|
for s, r in [('', True), # every bitarray contains an empty one
|
|
2248
2288
|
('1', True), ('11', True), ('111', False),
|
|
@@ -2431,6 +2471,18 @@ class NumberTests(unittest.TestCase, Util):
|
|
|
2431
2471
|
b[16:] &= bitarray("1111 0000 1111 0000", 'big')
|
|
2432
2472
|
self.assertEqual(a, bytearray([0xfc, 0x88, 0x10, 0xe0]))
|
|
2433
2473
|
|
|
2474
|
+
def test_unaligned_buffers(self):
|
|
2475
|
+
for a in self.unaligned_buffers():
|
|
2476
|
+
for b in self.unaligned_buffers():
|
|
2477
|
+
a.setall(0)
|
|
2478
|
+
a[187] = a[193] = b[193] = b[194] = 1
|
|
2479
|
+
a &= b
|
|
2480
|
+
self.assertEqual(list(a.search(1)), [193])
|
|
2481
|
+
a ^= b
|
|
2482
|
+
self.assertEqual(list(a.search(1)), [194])
|
|
2483
|
+
a |= b
|
|
2484
|
+
self.assertEqual(list(a.search(1)), [193, 194])
|
|
2485
|
+
|
|
2434
2486
|
|
|
2435
2487
|
class ShiftTests(unittest.TestCase, Util):
|
|
2436
2488
|
|
|
@@ -2593,6 +2645,18 @@ class ShiftTests(unittest.TestCase, Util):
|
|
|
2593
2645
|
b >>= 8
|
|
2594
2646
|
self.assertEqual(a, bytearray([0x00, 0xfc, 0x88, 0x10]))
|
|
2595
2647
|
|
|
2648
|
+
def test_unaligned_buffers(self):
|
|
2649
|
+
for endian in ENDIANS:
|
|
2650
|
+
for a in self.unaligned_buffers(endian=endian):
|
|
2651
|
+
a[0] = a[193] = a[-1] = 1
|
|
2652
|
+
expected = self.shift(a, 3, 'left')
|
|
2653
|
+
a <<= 3
|
|
2654
|
+
self.assertEQUAL(a, expected)
|
|
2655
|
+
|
|
2656
|
+
expected = self.shift(a, 5, 'right')
|
|
2657
|
+
a >>= 5
|
|
2658
|
+
self.assertEQUAL(a, expected)
|
|
2659
|
+
|
|
2596
2660
|
# -------------------------------- .extend() ----------------------------
|
|
2597
2661
|
|
|
2598
2662
|
class ExtendTests(unittest.TestCase, Util):
|
|
@@ -3115,6 +3179,22 @@ class InvertTests(unittest.TestCase, Util):
|
|
|
3115
3179
|
b.invert()
|
|
3116
3180
|
self.assertEqual(a, bytearray([255, 254, 253, 252, 223, 0]))
|
|
3117
3181
|
|
|
3182
|
+
def test_unaligned_buffers(self):
|
|
3183
|
+
for n in range(20):
|
|
3184
|
+
for endian in ENDIANS:
|
|
3185
|
+
for a in self.unaligned_buffers(size=n, endian=endian):
|
|
3186
|
+
a.invert()
|
|
3187
|
+
self.assertEqual(a, ones(len(a)))
|
|
3188
|
+
if n == 0:
|
|
3189
|
+
continue
|
|
3190
|
+
i = randrange(len(a))
|
|
3191
|
+
a.invert(i)
|
|
3192
|
+
self.assertEqual(a.find(0), i)
|
|
3193
|
+
self.assertEqual(a.endian, endian)
|
|
3194
|
+
a.invert(slice(0, i))
|
|
3195
|
+
a.invert(slice(i + 1, None))
|
|
3196
|
+
self.assertEqual(a, zeros(8 * n))
|
|
3197
|
+
|
|
3118
3198
|
class SortTests(unittest.TestCase, Util):
|
|
3119
3199
|
|
|
3120
3200
|
def test_simple(self):
|
|
@@ -3813,13 +3893,15 @@ class CountTests(unittest.TestCase, Util):
|
|
|
3813
3893
|
self.assertEqual(a.count(v, s.start, s.stop, s.step),
|
|
3814
3894
|
a[s].count(v))
|
|
3815
3895
|
|
|
3816
|
-
def
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3896
|
+
def test_unaligned_buffers(self):
|
|
3897
|
+
for n in range(20):
|
|
3898
|
+
for endian in ENDIANS:
|
|
3899
|
+
for a in self.unaligned_buffers(size=n, endian=endian):
|
|
3900
|
+
b = urandom_2(8 * n)
|
|
3901
|
+
expected = b.count()
|
|
3902
|
+
a[:] = b
|
|
3903
|
+
self.assertEqual(a.count(), expected)
|
|
3904
|
+
self.assertEqual(a.endian, endian)
|
|
3823
3905
|
|
|
3824
3906
|
# -------------------------- .find() and .index() ---------------------------
|
|
3825
3907
|
|
|
@@ -3993,6 +4075,23 @@ class IndexTests(unittest.TestCase, Util):
|
|
|
3993
4075
|
self.assertEqual(a.find(v, i, j, 0), ref_l)
|
|
3994
4076
|
self.assertEqual(a.find(v, i, j, 1), ref_r)
|
|
3995
4077
|
|
|
4078
|
+
def test_unaligned_buffers(self):
|
|
4079
|
+
for n in range(20):
|
|
4080
|
+
for endian in ENDIANS:
|
|
4081
|
+
for a in self.unaligned_buffers(size=n, endian=endian):
|
|
4082
|
+
self.assertEqual(a.find(1), -1)
|
|
4083
|
+
if n == 0:
|
|
4084
|
+
continue
|
|
4085
|
+
i = randrange(len(a))
|
|
4086
|
+
a[i] = 1
|
|
4087
|
+
self.assertEqual(a.find(1), i)
|
|
4088
|
+
self.assertEqual(a.find(1, right=1), i)
|
|
4089
|
+
a.setall(1)
|
|
4090
|
+
self.assertEqual(a.find(0), -1)
|
|
4091
|
+
a[i] = 0
|
|
4092
|
+
self.assertEqual(a.find(0), i)
|
|
4093
|
+
self.assertEqual(a.find(0, right=1), i)
|
|
4094
|
+
|
|
3996
4095
|
# ----------------------------- .search() -----------------------------------
|
|
3997
4096
|
|
|
3998
4097
|
class SearchTests(unittest.TestCase, Util):
|
|
@@ -5623,12 +5722,17 @@ class FrozenbitarrayTests(unittest.TestCase, Util):
|
|
|
5623
5722
|
|
|
5624
5723
|
self.check_obj(a)
|
|
5625
5724
|
|
|
5626
|
-
def test_copy(self):
|
|
5725
|
+
def test_copy(self) -> None:
|
|
5627
5726
|
a = frozenbitarray('101')
|
|
5628
|
-
#
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5727
|
+
# Check the stub return types as well as the runtime types.
|
|
5728
|
+
copies: list[frozenbitarray] = [
|
|
5729
|
+
a.copy(), 3 * a, a * 5, a & bitarray('110'),
|
|
5730
|
+
a | bitarray('110'), a ^ bitarray('110'),
|
|
5731
|
+
a & frozenbitarray('110'), a | frozenbitarray('110'),
|
|
5732
|
+
a ^ frozenbitarray('110'), a >> 2, a << 1, ~a,
|
|
5733
|
+
a + bitarray(8*'1'), a[:], a[::2], a[[0, 1]], a[bitarray('011')],
|
|
5734
|
+
]
|
|
5735
|
+
for b in copies:
|
|
5632
5736
|
self.assertIs(type(b), frozenbitarray)
|
|
5633
5737
|
self.assertTrue(b.readonly)
|
|
5634
5738
|
self.check_obj(b)
|
|
@@ -5748,14 +5852,15 @@ def show_info(verbosity=1):
|
|
|
5748
5852
|
|
|
5749
5853
|
if verbosity >= 2:
|
|
5750
5854
|
print('bitarray version: %s' % __version__)
|
|
5855
|
+
print('platform.machine(): %s' % platform.machine())
|
|
5856
|
+
print('platform.platform(): %s' % platform.platform())
|
|
5857
|
+
print('sys.platform: %s' % sys.platform)
|
|
5751
5858
|
print('sys.version: %s' % sys.version)
|
|
5752
5859
|
if os.name == "posix":
|
|
5753
5860
|
print('sys.abiflags: %r' % sys.abiflags)
|
|
5754
5861
|
if sys.version_info[:2] >= (3, 14):
|
|
5755
5862
|
print('sys._is_gil_enabled(): %s' % sys._is_gil_enabled())
|
|
5756
5863
|
print('pointer size: %d bit' % (8 * PTRSIZE))
|
|
5757
|
-
print('sizeof(size_t): %d' % sysinfo("size_t"))
|
|
5758
|
-
print('sizeof(bitarrayobject): %d' % sysinfo("bitarrayobject"))
|
|
5759
5864
|
print('HAVE_BUILTIN_BSWAP64: %d' % sysinfo("HAVE_BUILTIN_BSWAP64"))
|
|
5760
5865
|
print('default bit-endianness: %s' % get_default_endian())
|
|
5761
5866
|
print('machine byte-order: %s' % sys.byteorder)
|
|
@@ -24,7 +24,8 @@ from collections import Counter
|
|
|
24
24
|
|
|
25
25
|
from bitarray import (bitarray, frozenbitarray, decodetree, bits2bytes,
|
|
26
26
|
get_default_endian)
|
|
27
|
-
from bitarray.test_bitarray import Util, is_pypy,
|
|
27
|
+
from bitarray.test_bitarray import (Util, is_pypy, is_sparc, urandom_2,
|
|
28
|
+
ENDIANS, PTRSIZE)
|
|
28
29
|
|
|
29
30
|
from bitarray.util import (
|
|
30
31
|
zeros, ones, urandom, random_k, random_p, pprint, strip, count_n,
|
|
@@ -687,6 +688,15 @@ class CountN_Tests(unittest.TestCase, Util):
|
|
|
687
688
|
i = count_n(a, n, v)
|
|
688
689
|
self.check_result(a, n, i, v)
|
|
689
690
|
|
|
691
|
+
def test_unaligned_buffers(self):
|
|
692
|
+
# size=1000 means that 8000 bits > BLOCK_BITS 4096
|
|
693
|
+
for a in self.unaligned_buffers(size=1000):
|
|
694
|
+
a[-1] = 1
|
|
695
|
+
if is_sparc and self.is_unaligned(a):
|
|
696
|
+
self.assertRaises(NotImplementedError, count_n, a, 1)
|
|
697
|
+
else:
|
|
698
|
+
self.assertEqual(count_n(a, 1), len(a))
|
|
699
|
+
|
|
690
700
|
# ---------------------------------------------------------------------------
|
|
691
701
|
|
|
692
702
|
class BitwiseCountTests(unittest.TestCase, Util):
|
|
@@ -771,6 +781,16 @@ class BitwiseCountTests(unittest.TestCase, Util):
|
|
|
771
781
|
self.assertEqual(all(a ^ b), count_xor(a, b) == n)
|
|
772
782
|
self.assertEqual(all(a ^ b), a == ~b)
|
|
773
783
|
|
|
784
|
+
def test_unaligned_buffers(self):
|
|
785
|
+
for f in count_and, count_or, count_xor, any_and, subset:
|
|
786
|
+
for a in self.unaligned_buffers():
|
|
787
|
+
for b in self.unaligned_buffers():
|
|
788
|
+
if is_sparc and (self.is_unaligned(a) or
|
|
789
|
+
self.is_unaligned(b)):
|
|
790
|
+
self.assertRaises(NotImplementedError, f, a, b)
|
|
791
|
+
else:
|
|
792
|
+
self.assertEqual(f(a, b), f == subset)
|
|
793
|
+
|
|
774
794
|
# --------------------------- any_and() -----------------------------------
|
|
775
795
|
|
|
776
796
|
class BitwiseAnyTests(unittest.TestCase, Util):
|
|
@@ -905,7 +925,7 @@ class SubsetTests(unittest.TestCase, Util):
|
|
|
905
925
|
|
|
906
926
|
# ------------------------- correspond_all() ------------------------------
|
|
907
927
|
|
|
908
|
-
class CorrespondAllTests(unittest.TestCase):
|
|
928
|
+
class CorrespondAllTests(unittest.TestCase, Util):
|
|
909
929
|
|
|
910
930
|
def test_basic(self):
|
|
911
931
|
a = frozenbitarray('0101')
|
|
@@ -941,10 +961,20 @@ class CorrespondAllTests(unittest.TestCase):
|
|
|
941
961
|
self.assertEqual(res[1] + res[2], count_xor(a, b))
|
|
942
962
|
self.assertEqual(sum(res), n)
|
|
943
963
|
|
|
964
|
+
def test_unaligned_buffers(self):
|
|
965
|
+
for a in self.unaligned_buffers():
|
|
966
|
+
for b in self.unaligned_buffers():
|
|
967
|
+
if is_sparc and (self.is_unaligned(a) or
|
|
968
|
+
self.is_unaligned(b)):
|
|
969
|
+
self.assertRaises(NotImplementedError,
|
|
970
|
+
correspond_all, a, b)
|
|
971
|
+
else:
|
|
972
|
+
self.assertEqual(correspond_all(a, b), (len(a), 0, 0, 0))
|
|
973
|
+
|
|
944
974
|
# ----------------------------- byteswap() --------------------------------
|
|
945
975
|
|
|
946
976
|
@unittest.skipIf(is_pypy, "skip test on PyPy")
|
|
947
|
-
class ByteSwapTests(unittest.TestCase):
|
|
977
|
+
class ByteSwapTests(unittest.TestCase, Util):
|
|
948
978
|
|
|
949
979
|
def test_basic_bytearray(self):
|
|
950
980
|
a = bytearray(b"ABCD")
|
|
@@ -1039,9 +1069,15 @@ class ByteSwapTests(unittest.TestCase):
|
|
|
1039
1069
|
a.bytereverse()
|
|
1040
1070
|
self.assertEqual(a, b[::-1])
|
|
1041
1071
|
|
|
1072
|
+
def test_unaligned_buffers(self):
|
|
1073
|
+
for n in 2, 4, 8, 16:
|
|
1074
|
+
for a in self.unaligned_buffers():
|
|
1075
|
+
byteswap(a, n)
|
|
1076
|
+
self.assertEqual(a, zeros(256))
|
|
1077
|
+
|
|
1042
1078
|
# ------------------------------ parity() ---------------------------------
|
|
1043
1079
|
|
|
1044
|
-
class ParityTests(unittest.TestCase):
|
|
1080
|
+
class ParityTests(unittest.TestCase, Util):
|
|
1045
1081
|
|
|
1046
1082
|
def test_explicit(self):
|
|
1047
1083
|
for s, res in [('', 0), ('1', 1), ('0010011', 1), ('10100110', 0)]:
|
|
@@ -1072,6 +1108,27 @@ class ParityTests(unittest.TestCase):
|
|
|
1072
1108
|
self.assertRaises(TypeError, parity)
|
|
1073
1109
|
self.assertRaises(TypeError, parity, bitarray("110"), 1)
|
|
1074
1110
|
|
|
1111
|
+
def test_unaligned_buffers(self):
|
|
1112
|
+
for a in self.unaligned_buffers():
|
|
1113
|
+
self.assertEqual(parity(a), 0)
|
|
1114
|
+
a[0] = 1
|
|
1115
|
+
self.assertEqual(parity(a), 1)
|
|
1116
|
+
a[193] = 1
|
|
1117
|
+
self.assertEqual(parity(a), 0)
|
|
1118
|
+
a[-1] = 1
|
|
1119
|
+
self.assertEqual(parity(a), 1)
|
|
1120
|
+
|
|
1121
|
+
def test_unaligned_buffers_random(self):
|
|
1122
|
+
for n in range(20):
|
|
1123
|
+
for endian in ENDIANS:
|
|
1124
|
+
for a in self.unaligned_buffers(size=n, endian=endian):
|
|
1125
|
+
b = urandom(8 * n)
|
|
1126
|
+
expected = b.count() % 2
|
|
1127
|
+
a[:] = b
|
|
1128
|
+
self.assertEqual(len(a), 8 * n)
|
|
1129
|
+
self.assertEqual(a.endian, endian)
|
|
1130
|
+
self.assertEqual(parity(a), expected)
|
|
1131
|
+
|
|
1075
1132
|
# ---------------------------- sum_indices() ------------------------------
|
|
1076
1133
|
|
|
1077
1134
|
class SumIndicesTests(unittest.TestCase):
|
|
@@ -2143,6 +2200,12 @@ class SC_Tests(unittest.TestCase, Util, SC_Util):
|
|
|
2143
2200
|
a &= urandom(n, endian)
|
|
2144
2201
|
self.round_trip(a)
|
|
2145
2202
|
|
|
2203
|
+
def test_unaligned_buffers(self):
|
|
2204
|
+
for a in self.unaligned_buffers(size=1000):
|
|
2205
|
+
if is_sparc and self.is_unaligned(a):
|
|
2206
|
+
self.assertRaises(NotImplementedError, sc_encode, a)
|
|
2207
|
+
else:
|
|
2208
|
+
self.assertEqual(sc_decode(sc_encode(a)), a)
|
|
2146
2209
|
|
|
2147
2210
|
# ------------------------ variable length codec ------------------------
|
|
2148
2211
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bitarray
|
|
3
|
-
Version: 3.12.
|
|
3
|
+
Version: 3.12.3
|
|
4
4
|
Summary: efficient arrays of booleans -- C extension
|
|
5
5
|
Home-page: https://github.com/ilanschnell/bitarray
|
|
6
6
|
Author: Ilan Schnell
|
|
@@ -57,6 +57,7 @@ Key features
|
|
|
57
57
|
their in-place versions ``&=``, ``|=``, ``^=``, ``<<=``, ``>>=``).
|
|
58
58
|
* `Free-threading support <https://github.com/ilanschnell/bitarray/blob/master/doc/free_threading.rst>`__
|
|
59
59
|
(for GIL-disabled CPython 3.14 and later)
|
|
60
|
+
* Written to `support all platforms supported by CPython and PyPy <https://github.com/ilanschnell/bitarray/blob/master/doc/platforms.rst>`__.
|
|
60
61
|
* Fast methods for encoding and decoding variable-length
|
|
61
62
|
`prefix codes <https://github.com/ilanschnell/bitarray/blob/master/doc/prefix_codes.rst>`__.
|
|
62
63
|
* Bitarray objects support the `buffer protocol <https://github.com/ilanschnell/bitarray/blob/master/doc/buffer.rst>`__
|
|
@@ -92,7 +93,7 @@ versions. Which means you can simply:
|
|
|
92
93
|
|
|
93
94
|
.. code-block:: shell-session
|
|
94
95
|
|
|
95
|
-
$ pip install bitarray
|
|
96
|
+
$ python -m pip install bitarray
|
|
96
97
|
|
|
97
98
|
Once you have installed the package, you may want to test it:
|
|
98
99
|
|
|
@@ -101,26 +102,27 @@ Once you have installed the package, you may want to test it:
|
|
|
101
102
|
$ python -c 'import bitarray; bitarray.test()'
|
|
102
103
|
bitarray is installed in: /Users/ilan/bitarray/bitarray
|
|
103
104
|
sys.prefix: /Users/ilan/miniforge
|
|
104
|
-
bitarray version: 3.12.
|
|
105
|
+
bitarray version: 3.12.3
|
|
106
|
+
platform.machine(): arm64
|
|
107
|
+
platform.platform(): macOS-14.3-arm64-arm-64bit-Mach-O
|
|
108
|
+
sys.platform: darwin
|
|
105
109
|
sys.version: 3.15.0 (main, Oct 9 2026) [Clang 21.1.8]
|
|
106
110
|
sys.abiflags: ''
|
|
107
111
|
sys._is_gil_enabled(): True
|
|
108
112
|
pointer size: 64 bit
|
|
109
|
-
sizeof(size_t): 8
|
|
110
|
-
sizeof(bitarrayobject): 80
|
|
111
113
|
HAVE_BUILTIN_BSWAP64: 1
|
|
112
114
|
default bit-endianness: big
|
|
113
115
|
machine byte-order: little
|
|
114
116
|
Py_GIL_DISABLED: 0
|
|
115
117
|
Py_DEBUG: 0
|
|
116
118
|
DEBUG: 0
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
.........................................................................
|
|
120
|
+
................................................s........................
|
|
119
121
|
......s.........................................................
|
|
120
122
|
----------------------------------------------------------------------
|
|
121
|
-
Ran
|
|
123
|
+
Ran 723 tests in 0.163s
|
|
122
124
|
|
|
123
|
-
OK (skipped=
|
|
125
|
+
OK (skipped=2)
|
|
124
126
|
|
|
125
127
|
The ``test()`` function is part of the API. It will return
|
|
126
128
|
a ``unittest.runner.TextTestResult`` object, such that one can verify that
|
|
@@ -312,7 +314,7 @@ and can therefore be used as a dictionary key:
|
|
|
312
314
|
Reference
|
|
313
315
|
=========
|
|
314
316
|
|
|
315
|
-
bitarray version: 3.12.
|
|
317
|
+
bitarray version: 3.12.3 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
|
|
316
318
|
|
|
317
319
|
In the following, ``item`` and ``value`` are usually a single bit -
|
|
318
320
|
an integer 0 or 1.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|