bitarray 3.12.2__tar.gz → 3.12.4__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.
Files changed (26) hide show
  1. {bitarray-3.12.2 → bitarray-3.12.4}/PKG-INFO +13 -11
  2. {bitarray-3.12.2 → bitarray-3.12.4}/README.rst +11 -9
  3. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/__init__.pyi +22 -20
  4. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/_bitarray.c +94 -59
  5. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/_util.c +75 -29
  6. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/bitarray.h +34 -8
  7. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/test_bitarray.py +136 -30
  8. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/test_util.py +138 -69
  9. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray.egg-info/PKG-INFO +13 -11
  10. {bitarray-3.12.2 → bitarray-3.12.4}/setup.py +11 -1
  11. {bitarray-3.12.2 → bitarray-3.12.4}/LICENSE +0 -0
  12. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/__init__.py +0 -0
  13. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/bitfields.py +0 -0
  14. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/py.typed +0 -0
  15. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/pythoncapi_compat.h +0 -0
  16. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/test_281.pickle +0 -0
  17. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/test_bitfields.py +0 -0
  18. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/test_free_threading.py +0 -0
  19. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/util.py +0 -0
  20. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray/util.pyi +0 -0
  21. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray.egg-info/SOURCES.txt +0 -0
  22. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray.egg-info/dependency_links.txt +0 -0
  23. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray.egg-info/not-zip-safe +0 -0
  24. {bitarray-3.12.2 → bitarray-3.12.4}/bitarray.egg-info/top_level.txt +0 -0
  25. {bitarray-3.12.2 → bitarray-3.12.4}/pyproject.toml +0 -0
  26. {bitarray-3.12.2 → bitarray-3.12.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitarray
3
- Version: 3.12.2
3
+ Version: 3.12.4
4
4
  Summary: efficient arrays of booleans -- C extension
5
5
  Home-page: https://github.com/ilanschnell/bitarray
6
6
  Author: Ilan Schnell
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Programming Language :: Python :: 3.13
21
21
  Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Programming Language :: Python :: 3.15
23
- Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
23
+ Classifier: Programming Language :: Python :: Free Threading :: 3 - Stable
24
24
  Classifier: Topic :: Utilities
25
25
  Requires-Python: >=3.7
26
26
  License-File: LICENSE
@@ -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 <https://github.com/ilanschnell/bitarray/blob/master/doc/platforms.rst>`__ by CPython and PyPy.
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.2
105
+ bitarray version: 3.12.4
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
- .....................................s...................................
118
- ..........s.....................................s........................
119
+ .........................................................................
120
+ ................................................s........................
119
121
  ......s.........................................................
120
122
  ----------------------------------------------------------------------
121
- Ran 711 tests in 0.161s
123
+ Ran 723 tests in 0.163s
122
124
 
123
- OK (skipped=4)
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.2 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
317
+ bitarray version: 3.12.4 -- `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 <https://github.com/ilanschnell/bitarray/blob/master/doc/platforms.rst>`__ by CPython and PyPy.
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.2
69
+ bitarray version: 3.12.4
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
- .....................................s...................................
82
- ..........s.....................................s........................
83
+ .........................................................................
84
+ ................................................s........................
83
85
  ......s.........................................................
84
86
  ----------------------------------------------------------------------
85
- Ran 711 tests in 0.161s
87
+ Ran 723 tests in 0.163s
86
88
 
87
- OK (skipped=4)
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.2 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
281
+ bitarray version: 3.12.4 -- `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) -> bitarray: ...
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]) -> bitarray: ...
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) -> bitarray: ...
131
- def __iadd__(self, other: bitarray) -> bitarray: ...
132
- def __mul__(self, n: int) -> bitarray: ...
133
- def __imul__(self, n: int) -> bitarray: ...
134
- def __rmul__(self, n: int) -> bitarray: ...
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) -> bitarray: ...
142
- def __or__(self, other: bitarray) -> bitarray: ...
143
- def __xor__(self, other: bitarray) -> bitarray: ...
144
- def __iand__(self, other: bitarray) -> bitarray: ...
145
- def __ior__(self, other: bitarray) -> bitarray: ...
146
- def __ixor__(self, other: bitarray) -> bitarray: ...
147
- def __invert__(self) -> bitarray: ...
148
- def __lshift__(self, n: int) -> bitarray: ...
149
- def __rshift__(self, n: int) -> bitarray: ...
150
- def __ilshift__(self, n: int) -> bitarray: ...
151
- def __irshift__(self, n: int) -> bitarray: ...
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 %= 8; /* number of remaining bytes */
231
+ r = n % 8; /* number of remaining bytes */
232
232
  #endif
233
- while (n--) { /* shift in byte-range(8 * w, n) */
234
- Py_ssize_t i = n + 8 * w;
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 (n || w) /* add shifted next lower byte */
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 %= 8; /* number of remaining bytes */
261
+ r = n % 8; /* number of remaining bytes */
262
262
  #endif
263
- while (n--) { /* shift in byte-range(8 * w, n) */
264
- Py_ssize_t i = n + 8 * w;
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 (n || w) /* add shifted next lower byte */
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 = (unsigned char *) self->ob_item + a;
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((void *) buff);
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
- const Py_ssize_t wa = (a + 63) / 64; /* word-range(wa, wb) */
468
- const Py_ssize_t wb = b / 64;
469
- uint64_t *wbuff = WBUFF(self);
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);
470
476
 
471
- invert_span(self, a, 64 * wa);
472
- for (i = wa; i < wb; i++)
473
- wbuff[i] = ~wbuff[i];
474
- invert_span(self, 64 * wb, b);
477
+ words = w ? (uint64_t *) (self->ob_item + p1) : NULL;
478
+ for (i = 0; i < w; i++)
479
+ words[i] = ~words[i];
480
+
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 p = BYTES(a), w; /* first full byte */
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
- assert(8 * p - a < 64 && b - (8 * (p + 8 * w)) < 64 && w >= 0);
586
+ w = aligned_words(self->ob_item, BYTES(a), b / 8, &p1, &p2);
582
587
 
583
- cnt += count_span(self, a, 8 * p);
584
- cnt += popcnt_words((uint64_t *) (self->ob_item + p), w);
585
- cnt += count_span(self, 8 * (p + 8 * w), b);
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 Py_ssize_t wa = (a + 63) / 64; /* word-range(wa, wb) */
640
- const Py_ssize_t wb = b / 64;
641
- const uint64_t *wbuff = WBUFF(self);
642
- const uint64_t w = vi ? 0 : ~0;
643
- Py_ssize_t res, i;
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, 64 * wb, b, 1)) >= 0)
653
+ if ((res = find_bit(self, vi, 8 * p2, b, 1)) >= 0)
647
654
  return res;
648
655
 
649
- for (i = wb - 1; i >= wa; i--) { /* skip uint64 words */
650
- if (w ^ wbuff[i])
651
- return find_bit(self, vi, 64 * i, 64 * i + 64, 1);
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, 64 * wa, 1);
662
+ return find_bit(self, vi, a, 8 * p1, 1);
654
663
  }
655
664
  else {
656
- if ((res = find_bit(self, vi, a, 64 * wa, 0)) >= 0)
665
+ if ((res = find_bit(self, vi, a, 8 * p1, 0)) >= 0)
657
666
  return res;
658
667
 
659
- for (i = wa; i < wb; i++) { /* skip uint64 words */
660
- if (w ^ wbuff[i])
661
- return find_bit(self, vi, 64 * i, 64 * i + 64, 0);
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, 64 * wb, b, 0);
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
- const Py_ssize_t cwords = nbytes / 8; /* complete 64-bit words */
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 = WBUFF(self);
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
- PyObject_HashNotImplemented, /* tp_hash */
5143
+ 0, /* tp_hash */
5124
5144
  0, /* tp_call */
5125
5145
  0, /* tp_str */
5126
5146
  PyObject_GenericGetAttr, /* tp_getattro */
@@ -5374,48 +5394,63 @@ PyInit__bitarray(void)
5374
5394
  reverse_trans = {0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, ..., 0xff} */
5375
5395
  setup_table(reverse_trans, 'r');
5376
5396
 
5377
- if ((m = PyModule_Create(&moduledef)) == NULL)
5397
+ m = PyModule_Create(&moduledef);
5398
+ if (m == NULL)
5378
5399
  return NULL;
5379
5400
 
5380
5401
  #ifdef Py_GIL_DISABLED
5381
5402
  if (PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED) < 0)
5382
- return NULL;
5403
+ goto error;
5383
5404
  #endif
5384
5405
 
5385
5406
  if (PyType_Ready(&Bitarray_Type) < 0)
5386
- return NULL;
5407
+ goto error;
5387
5408
  Py_SET_TYPE(&Bitarray_Type, &PyType_Type);
5388
5409
  Py_INCREF((PyObject *) &Bitarray_Type);
5389
- PyModule_AddObject(m, "bitarray", (PyObject *) &Bitarray_Type);
5410
+ if (PyModule_AddObject(m, "bitarray", (PyObject *) &Bitarray_Type) < 0) {
5411
+ Py_DECREF((PyObject *) &Bitarray_Type);
5412
+ goto error;
5413
+ }
5390
5414
 
5391
5415
  if (add_capsule(m) < 0)
5392
- return NULL;
5416
+ goto error;
5393
5417
 
5394
5418
  if (register_abc() < 0)
5395
- return NULL;
5419
+ goto error;
5396
5420
 
5397
5421
  if (PyType_Ready(&DecodeTree_Type) < 0)
5398
- return NULL;
5422
+ goto error;
5399
5423
  Py_SET_TYPE(&DecodeTree_Type, &PyType_Type);
5400
5424
  Py_INCREF((PyObject *) &DecodeTree_Type);
5401
- PyModule_AddObject(m, "decodetree", (PyObject *) &DecodeTree_Type);
5425
+ if (PyModule_AddObject(m, "decodetree",
5426
+ (PyObject *) &DecodeTree_Type) < 0) {
5427
+ Py_DECREF((PyObject *) &DecodeTree_Type);
5428
+ goto error;
5429
+ }
5402
5430
 
5403
5431
  if (PyType_Ready(&DecodeIter_Type) < 0)
5404
- return NULL;
5432
+ goto error;
5405
5433
  Py_SET_TYPE(&DecodeIter_Type, &PyType_Type);
5406
5434
  Py_INCREF((PyObject *) &DecodeIter_Type);
5407
- PyModule_AddObject(m, "decodeiterator", (PyObject *) &DecodeIter_Type);
5435
+ if (PyModule_AddObject(m, "decodeiterator",
5436
+ (PyObject *) &DecodeIter_Type) < 0) {
5437
+ Py_DECREF((PyObject *) &DecodeIter_Type);
5438
+ goto error;
5439
+ }
5408
5440
 
5409
5441
  if (PyType_Ready(&BitarrayIter_Type) < 0)
5410
- return NULL;
5442
+ goto error;
5411
5443
  Py_SET_TYPE(&BitarrayIter_Type, &PyType_Type);
5412
5444
 
5413
5445
  if (PyType_Ready(&SearchIter_Type) < 0)
5414
- return NULL;
5446
+ goto error;
5415
5447
  Py_SET_TYPE(&SearchIter_Type, &PyType_Type);
5416
5448
 
5417
5449
  if (PyModule_AddStringMacro(m, BITARRAY_VERSION) < 0)
5418
- return NULL;
5450
+ goto error;
5419
5451
 
5420
5452
  return m;
5453
+ error:
5454
+ Py_DECREF(m);
5455
+ return NULL;
5421
5456
  }