Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-bitarray for openSUSE:Factory 
checked in at 2026-04-04 19:06:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-bitarray (Old)
 and      /work/SRC/openSUSE:Factory/.python-bitarray.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-bitarray"

Sat Apr  4 19:06:53 2026 rev:43 rq:1344479 version:3.8.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-bitarray/python-bitarray.changes  
2025-11-18 15:38:05.075015972 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-bitarray.new.21863/python-bitarray.changes   
    2026-04-04 19:08:51.148655325 +0200
@@ -1,0 +2,7 @@
+Fri Apr  3 13:41:54 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 3.8.1:
+  * fixed critial findings in C Extension Analysis Report, see
+  * add tests, in particular devel/test_capi.py
+
+-------------------------------------------------------------------

Old:
----
  bitarray-3.8.0.tar.gz

New:
----
  bitarray-3.8.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-bitarray.spec ++++++
--- /var/tmp/diff_new_pack.DF8Epi/_old  2026-04-04 19:08:52.704719124 +0200
+++ /var/tmp/diff_new_pack.DF8Epi/_new  2026-04-04 19:08:52.732720272 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-bitarray
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-bitarray
-Version:        3.8.0
+Version:        3.8.1
 Release:        0
 Summary:        Efficient Arrays of Booleans
 License:        Python-2.0
@@ -26,7 +26,7 @@
 Source:         
https://github.com/ilanschnell/bitarray/archive/%{version}.tar.gz#/bitarray-%{version}.tar.gz
 BuildRequires:  %{python_module devel}
 BuildRequires:  %{python_module pip}
-BuildRequires:  %{python_module setuptools}
+BuildRequires:  %{python_module setuptools >= 42.0.0}
 BuildRequires:  %{python_module wheel}
 # SECTION test requirements
 BuildRequires:  %{python_module dbm}

++++++ bitarray-3.8.0.tar.gz -> bitarray-3.8.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/CHANGE_LOG 
new/bitarray-3.8.1/CHANGE_LOG
--- old/bitarray-3.8.0/CHANGE_LOG       2025-11-02 21:26:51.000000000 +0100
+++ new/bitarray-3.8.1/CHANGE_LOG       2026-04-02 17:13:02.000000000 +0200
@@ -1,3 +1,9 @@
+2026-04-02   3.8.1:
+-------------------
+  * fixed critial findings in C Extension Analysis Report, see #250
+  * add tests, in particular `devel/test_capi.py`
+
+
 2025-11-02   3.8.0:
 -------------------
   * add experimental support for free-threaded builds (GIL disabled), #234
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/LICENSE new/bitarray-3.8.1/LICENSE
--- old/bitarray-3.8.0/LICENSE  2025-11-02 21:26:51.000000000 +0100
+++ new/bitarray-3.8.1/LICENSE  2026-04-02 17:13:02.000000000 +0200
@@ -11,7 +11,7 @@
 prepare derivative works, distribute, and otherwise use bitarray
 alone or in any derivative version, provided, however, that Ilan Schnell's
 License Agreement and Ilan Schnell's notice of copyright, i.e., "Copyright (c)
-2008 - 2025 Ilan Schnell; All Rights Reserved" are retained in bitarray
+2008 - 2026 Ilan Schnell; All Rights Reserved" are retained in bitarray
 alone or in any derivative version prepared by Licensee.
 
 3. In the event Licensee prepares a derivative work that is based on
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/README.rst 
new/bitarray-3.8.1/README.rst
--- old/bitarray-3.8.0/README.rst       2025-11-02 21:26:51.000000000 +0100
+++ new/bitarray-3.8.1/README.rst       2026-04-02 17:13:02.000000000 +0200
@@ -57,7 +57,7 @@
 
     $ python -c 'import bitarray; bitarray.test()'
     bitarray is installed in: /Users/ilan/bitarray/bitarray
-    bitarray version: 3.8.0
+    bitarray version: 3.8.1
     sys.version: 3.13.5 (main, Jun 16 2025) [Clang 18.1.8]
     sys.prefix: /Users/ilan/miniforge
     pointer size: 64 bit
@@ -73,7 +73,7 @@
     .........................................................................
     ................................................................
     ----------------------------------------------------------------------
-    Ran 595 tests in 0.165s
+    Ran 598 tests in 0.165s
 
     OK
 
@@ -320,7 +320,7 @@
 Reference
 =========
 
-bitarray version: 3.8.0 -- `change log 
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
+bitarray version: 3.8.1 -- `change log 
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
 
 In the following, ``item`` and ``value`` are usually a single bit -
 an integer 0 or 1.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/__init__.py 
new/bitarray-3.8.1/bitarray/__init__.py
--- old/bitarray-3.8.0/bitarray/__init__.py     2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/bitarray/__init__.py     2026-04-02 17:13:02.000000000 
+0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2008 - 2025, Ilan Schnell; All Rights Reserved
+# Copyright (c) 2008 - 2026, Ilan Schnell; All Rights Reserved
 """
 This package defines an object type which can efficiently represent
 a bitarray.  Bitarrays are sequence types and behave very much like lists.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/__init__.pyi 
new/bitarray-3.8.1/bitarray/__init__.pyi
--- old/bitarray-3.8.0/bitarray/__init__.pyi    2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/bitarray/__init__.pyi    2026-04-02 17:13:02.000000000 
+0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2021 - 2025, Ilan Schnell; All Rights Reserved
+# Copyright (c) 2021 - 2026, Ilan Schnell; All Rights Reserved
 #
 # This stub, as well as util.pyi, are tested with Python 3.10 and mypy 1.11.2
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/_bitarray.c 
new/bitarray-3.8.1/bitarray/_bitarray.c
--- old/bitarray-3.8.0/bitarray/_bitarray.c     2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/bitarray/_bitarray.c     2026-04-02 17:13:02.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2008 - 2025, Ilan Schnell; All Rights Reserved
+   Copyright (c) 2008 - 2026, Ilan Schnell; All Rights Reserved
    bitarray is published under the PSF license.
 
    This file is the C part of the bitarray package.
@@ -96,6 +96,9 @@
     assert(new_allocated >= newsize);
     self->ob_item = PyMem_Realloc(self->ob_item, new_allocated);
     if (self->ob_item == NULL) {
+        Py_SET_SIZE(self, 0);
+        self->allocated = 0;
+        self->nbits = 0;
         PyErr_NoMemory();
         return -1;
     }
@@ -1028,7 +1031,7 @@
     readonly = PyBool_FromLong(self->readonly);
     imported = PyBool_FromLong(self->buffer ? 1 : 0);
     if (address == NULL || readonly == NULL || imported == NULL)
-        return NULL;
+        goto error;
 
     args = Py_BuildValue("OnsnnOOi",
                          address,
@@ -1039,12 +1042,21 @@
                          readonly,
                          imported,
                          self->ob_exports);
+    if (args == NULL)
+        goto error;
+
     Py_DECREF(address);
     Py_DECREF(readonly);
     Py_DECREF(imported);
     res = PyObject_CallObject(info, args);
     Py_DECREF(args);
     return res;
+
+ error:
+    Py_XDECREF(address);
+    Py_XDECREF(readonly);
+    Py_XDECREF(imported);
+    return NULL;
 }
 
 PyDoc_STRVAR(buffer_info_doc,
@@ -1600,7 +1612,7 @@
     ret = bitarray_frombytes(self, bytes);
     Py_DECREF(bytes);
     if (ret == NULL)
-        res = -1;
+        return -1;
     Py_DECREF(ret);
     return res;
 }
@@ -2844,8 +2856,9 @@
 
     /* extend self with the bitarrays from codedict */
     while ((symbol = PyIter_Next(iter))) {
-        value = PyDict_GetItem(codedict, symbol);
-        Py_DECREF(symbol);
+        if (PyDict_GetItemRef(codedict, symbol, &value) < 0)
+            goto error;
+
         if (value == NULL) {
             PyErr_Format(PyExc_ValueError,
                          "symbol not defined in prefix code: %A", symbol);
@@ -2854,6 +2867,9 @@
         if (check_value(value) < 0 ||
                 extend_bitarray(self, (bitarrayobject *) value) < 0)
             goto error;
+
+        Py_DECREF(symbol);
+        Py_DECREF(value);
     }
     Py_DECREF(iter);
     if (PyErr_Occurred())       /* from PyIter_Next() */
@@ -2862,6 +2878,8 @@
 
  error:
     Py_DECREF(iter);
+    Py_DECREF(symbol);
+    Py_XDECREF(value);
     return NULL;
 }
 
@@ -3023,8 +3041,10 @@
 
         if ((t = bitarray_cp(prefix)) == NULL)
             return -1;
-        if (resize(t, t->nbits + 1) < 0)
+        if (resize(t, t->nbits + 1) < 0) {
+            Py_DECREF(t);
             return -1;
+        }
         setbit(t, t->nbits - 1, k);
         ret = binode_to_dict(nd->child[k], dict, t);
         Py_DECREF(t);
@@ -3321,12 +3341,12 @@
 static void
 decodeiter_dealloc(decodeiterobject *it)
 {
+    PyObject_GC_UnTrack(it);
     if (it->decodetree)
         Py_DECREF(it->decodetree);
     else       /* when decodeiter was created from dict - free tree */
         binode_delete(it->tree);
 
-    PyObject_GC_UnTrack(it);
     Py_DECREF(it->self);
     PyObject_GC_Del(it);
 }
@@ -3466,6 +3486,7 @@
 searchiter_traverse(searchiterobject *it, visitproc visit, void *arg)
 {
     Py_VISIT(it->self);
+    Py_VISIT(it->sub);
     return 0;
 }
 
@@ -4044,7 +4065,8 @@
         return PyErr_Format(PyExc_TypeError, "'int' object expected, "
                             "got '%s'", Py_TYPE(n)->tp_name);
 
-    zero = PyLong_FromLong(0);
+    if ((zero = PyLong_FromLong(0)) == NULL)
+        return NULL;
     cmp_res = PyObject_RichCompareBool(n, zero, Py_LT);
     Py_DECREF(zero);
     if (cmp_res < 0)
@@ -4054,13 +4076,17 @@
         return NULL;
     }
 
-    seven = PyLong_FromLong(7);
+    if ((seven = PyLong_FromLong(7)) == NULL)
+        return NULL;
     a = PyNumber_Add(n, seven);          /* a = n + 7 */
     Py_DECREF(seven);
     if (a == NULL)
         return NULL;
 
-    eight = PyLong_FromLong(8);
+    if ((eight = PyLong_FromLong(8)) == NULL) {
+        Py_DECREF(a);
+        return NULL;
+    }
     b = PyNumber_FloorDivide(a, eight);  /* b = a // 8 */
     Py_DECREF(eight);
     Py_DECREF(a);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/_util.c 
new/bitarray-3.8.1/bitarray/_util.c
--- old/bitarray-3.8.0/bitarray/_util.c 2025-11-02 21:26:51.000000000 +0100
+++ new/bitarray-3.8.1/bitarray/_util.c 2026-04-02 17:13:02.000000000 +0200
@@ -1,5 +1,5 @@
 /*
-   Copyright (c) 2019 - 2025, Ilan Schnell; All Rights Reserved
+   Copyright (c) 2019 - 2026, Ilan Schnell; All Rights Reserved
    bitarray is published under the PSF license.
 
    This file contains the C implementation of some useful utility functions.
@@ -102,6 +102,9 @@
 
     self->ob_item = PyMem_Realloc(self->ob_item, newsize);
     if (self->ob_item == NULL) {
+        Py_SET_SIZE(self, 0);
+        self->allocated = 0;
+        self->nbits = 0;
         PyErr_NoMemory();
         return -1;
     }
@@ -1154,7 +1157,8 @@
        BSI(1) = 32                         (BSI = Buffer Size Indexable)
 
    Moving from block type n to n + 1 multiplies the decoded block size
-   by a factor of 256 (as the extra byte can index 256 times as much):
+   by a factor of 256 (as one extra byte can index 256 times as much
+   address space):
 
        BSI(n + 1) = 256 * BSI(n)
 */
@@ -1281,7 +1285,8 @@
       a.count(1, 8 * offset, 8 * offset + (1 << (8 * n)))
 
    The offset must be divisible by SEGSIZE, as this functions makes use of
-   running totals, stored in rts[]. */
+   running totals, stored in rts[].
+   Here, and in the following, 'offset' is in units of bytes. */
 static Py_ssize_t
 sc_count(bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset, int n)
 {
@@ -1968,8 +1973,10 @@
         return NULL;
 
     it = PyObject_GC_New(chdi_obj, &CHDI_Type);
-    if (it == NULL)
-        goto error;
+    if (it == NULL) {
+        Py_DECREF(symbol);
+        return NULL;
+    }
 
     if ((count_sum = set_count(it->count, count)) < 0)
         goto error;
@@ -1990,7 +1997,7 @@
 
  error:
     it->array = NULL;
-    Py_XDECREF(symbol);
+    Py_DECREF(symbol);
     it->symbol = NULL;
     Py_DECREF(it);
     return NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/bitarray.h 
new/bitarray-3.8.1/bitarray/bitarray.h
--- old/bitarray-3.8.0/bitarray/bitarray.h      2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/bitarray/bitarray.h      2026-04-02 17:13:02.000000000 
+0200
@@ -1,10 +1,10 @@
 /*
-   Copyright (c) 2008 - 2025, Ilan Schnell; All Rights Reserved
+   Copyright (c) 2008 - 2026, Ilan Schnell; All Rights Reserved
    bitarray is published under the PSF license.
 
    Author: Ilan Schnell
 */
-#define BITARRAY_VERSION  "3.8.0"
+#define BITARRAY_VERSION  "3.8.1"
 
 #ifdef STDC_HEADERS
 #  include <stddef.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/test_bitarray.py 
new/bitarray-3.8.1/bitarray/test_bitarray.py
--- old/bitarray-3.8.0/bitarray/test_bitarray.py        2025-11-02 
21:26:51.000000000 +0100
+++ new/bitarray-3.8.1/bitarray/test_bitarray.py        2026-04-02 
17:13:02.000000000 +0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2008 - 2025, Ilan Schnell; All Rights Reserved
+# Copyright (c) 2008 - 2026, Ilan Schnell; All Rights Reserved
 # bitarray is published under the PSF license.
 #
 # Author: Ilan Schnell
@@ -259,7 +259,7 @@
             self.assertEQUAL(a, bitarray(0, endian))
 
         a = bitarray(buffer=b'A')
-        self.assertEqual(a.endian, "big")
+        self.assertEqual(a.endian, get_default_endian())
         self.assertEqual(len(a), 8)
 
     def test_buffer_readonly(self):
@@ -2405,16 +2405,16 @@
     @skipIf(is_pypy)
     def test_imported(self):
         a = bytearray([0xf0, 0x01, 0x02, 0x0f])
-        b = bitarray(buffer=a)
+        b = bitarray(buffer=a, endian='big')
         self.assertFalse(b.readonly)
         # operate on imported (writable) buffer
         b[8:24] <<= 3
         self.assertEqual(a, bytearray([0xf0, 0x08, 0x10, 0x0f]))
-        b[0:9] |= bitarray("0000 1100 1")
+        b[0:9] |= bitarray("0000 1100 1", 'big')
         self.assertEqual(a, bytearray([0xfc, 0x88, 0x10, 0x0f]))
-        b[23:] ^= bitarray("1 1110 1110")
+        b[23:] ^= bitarray("1 1110 1110", 'big')
         self.assertEqual(a, bytearray([0xfc, 0x88, 0x11, 0xe1]))
-        b[16:] &= bitarray("1111 0000 1111 0000")
+        b[16:] &= bitarray("1111 0000 1111 0000", 'big')
         self.assertEqual(a, bytearray([0xfc, 0x88, 0x10, 0xe0]))
         b >>= 8
         self.assertEqual(a, bytearray([0x00, 0xfc, 0x88, 0x10]))
@@ -4038,7 +4038,7 @@
         with open(self.tmpfname, 'rb') as fi:
             self.assertRaises(TypeError, a.fromfile, fi, None)
 
-    def test_fromfile_erros(self):
+    def test_fromfile_errors(self):
         with open(self.tmpfname, 'wb') as fo:
             fo.write(b'0123456789')
         self.assertFileSize(10)
@@ -4052,6 +4052,13 @@
             self.assertRaisesMessage(TypeError, ".read() did not return "
                                      "'bytes', got 'str'", a.fromfile, fi)
 
+    def test_fromfile_exported_buffer(self):
+        a = bitarray()
+        v = memoryview(a)  # export buffer — prevents resize/frombytes
+        f = BytesIO(b'\x00' * 100)
+        msg = "cannot resize bitarray that is exporting buffers"
+        self.assertRaisesMessage(BufferError, msg, a.fromfile, f)
+
     def test_frombytes_invalid_reader(self):
         class Reader:
             def read(self, n):
@@ -4408,6 +4415,26 @@
         msg = "symbol not defined in prefix code: None"
         self.assertRaisesMessage(ValueError, msg, a.encode, d, [None, 2])
 
+    def test_encode_symbol_ref_count(self):
+        a = bitarray()
+        codedict = {'a': bitarray('0')}
+        # Generator yields a fresh object with refcount 1
+        def gen():
+            yield type('X', (), {
+                '__hash__': lambda s: 42,
+                '__repr__': lambda s: 'X()'
+            })()
+        self.assertRaises(ValueError, a.encode, codedict, gen())
+
+    def test_encode_swallowed_exception(self):
+        a = bitarray()
+        codedict = {'a': bitarray('0')}
+        class Unhashable:
+            def __hash__(self):
+                raise MemoryError("OOM in __hash__")
+        # MemoryError is not swallowed by ValueError
+        self.assertRaises(MemoryError, a.encode, codedict, [Unhashable()])
+
     def test_encode_not_iterable(self):
         d = {'a': bitarray('0'), 'b': bitarray('1')}
         a = bitarray()
@@ -4714,10 +4741,10 @@
     @skipIf(is_pypy)
     def test_bitarray_shared_sections(self):
         a = urandom_2(0x2000, 'big')
-        b = bitarray(buffer=memoryview(a)[0x100:0x300])
+        b = bitarray(buffer=memoryview(a)[0x100:0x300], endian='big')
         self.assertEqual(b.buffer_info().address,
                          a.buffer_info().address + 0x100)
-        c = bitarray(buffer=memoryview(a)[0x200:0x800])
+        c = bitarray(buffer=memoryview(a)[0x200:0x800], endian='big')
         self.assertEqual(c.buffer_info().address,
                          a.buffer_info().address + 0x200)
         self.assertEqual(a[8 * 0x100 : 8 * 0x300], b)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/test_util.py 
new/bitarray-3.8.1/bitarray/test_util.py
--- old/bitarray-3.8.0/bitarray/test_util.py    2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/bitarray/test_util.py    2026-04-02 17:13:02.000000000 
+0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2019 - 2025, Ilan Schnell; All Rights Reserved
+# Copyright (c) 2019 - 2026, Ilan Schnell; All Rights Reserved
 # bitarray is published under the PSF license.
 #
 # Author: Ilan Schnell
@@ -1400,7 +1400,9 @@
 
     def test_hex2ba_whitespace(self):
         self.assertEqual(hex2ba("F1 FA %s f3 c0" % whitespace),
-                         bitarray("11110001 11111010 11110011 11000000"))
+                         bitarray("11110001 11111010 11110011 11000000"
+                                  if get_default_endian() == "big" else
+                                  "11111000 11110101 11111100 00110000"))
         self.assertEQUAL(hex2ba(b' a F ', 'big'),
                          bitarray('1010 1111', 'big'))
         self.assertEQUAL(hex2ba(860 * " " + '0  1D' + 590 * " ", 'little'),
@@ -2251,7 +2253,8 @@
                       (3691038, '1110000101001000011110')]:
             ab = bitarray(sa, 'big')
             al = bitarray(sa[::-1], 'little')
-            self.assertEQUAL(int2ba(i), ab)
+            self.assertEQUAL(int2ba(i),
+                             ab if get_default_endian() == 'big' else al)
             self.assertEQUAL(int2ba(i, endian='big'), ab)
             self.assertEQUAL(int2ba(i, endian='little'), al)
             self.assertEqual(ba2int(ab), ba2int(al), i)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/util.py 
new/bitarray-3.8.1/bitarray/util.py
--- old/bitarray-3.8.0/bitarray/util.py 2025-11-02 21:26:51.000000000 +0100
+++ new/bitarray-3.8.1/bitarray/util.py 2026-04-02 17:13:02.000000000 +0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2019 - 2025, Ilan Schnell; All Rights Reserved
+# Copyright (c) 2019 - 2026, Ilan Schnell; All Rights Reserved
 # bitarray is published under the PSF license.
 #
 # Author: Ilan Schnell
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/bitarray/util.pyi 
new/bitarray-3.8.1/bitarray/util.pyi
--- old/bitarray-3.8.0/bitarray/util.pyi        2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/bitarray/util.pyi        2026-04-02 17:13:02.000000000 
+0200
@@ -1,4 +1,4 @@
-# Copyright (c) 2021 - 2025, Ilan Schnell; All Rights Reserved
+# Copyright (c) 2021 - 2026, Ilan Schnell; All Rights Reserved
 
 from collections import Counter
 from collections.abc import Iterable, Iterator, Sequence
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/devel/sc/sc_stat.py 
new/bitarray-3.8.1/devel/sc/sc_stat.py
--- old/bitarray-3.8.0/devel/sc/sc_stat.py      2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/devel/sc/sc_stat.py      2026-04-02 17:13:02.000000000 
+0200
@@ -107,7 +107,16 @@
             self.assertEqual(sc_decode(blob), bitarray(8))
 
     def test_untouch(self):
-        stream = iter(b"\x01\x07\x01\x73\0XYZ")
+        blob = b"\x01\x07\x01\x73\0XYZ"
+        stream = iter(blob)
+        stat = sc_stat(stream, count=True)
+        self.assertEqual(stat,
+                         {'endian': 'little',
+                          'nbits': 7,
+                          'blocks': [1, 0, 0, 0, 0],
+                          'count': [5, 0, 0, 0, 0]})
+        self.assertEqual(next(stream), ord('X'))
+        stream = iter(blob)
         self.assertEqual(sc_decode(stream), bitarray("1100111"))
         self.assertEqual(next(stream), ord('X'))
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/devel/test_capi.py 
new/bitarray-3.8.1/devel/test_capi.py
--- old/bitarray-3.8.0/devel/test_capi.py       1970-01-01 01:00:00.000000000 
+0100
+++ new/bitarray-3.8.1/devel/test_capi.py       2026-04-02 17:13:02.000000000 
+0200
@@ -0,0 +1,49 @@
+"""
+This test file contains unittests which depend on the _testapi module in
+the standard library, as _testapi is not officially supported, and many
+not be available on all CPython builds.
+"""
+import unittest
+import _testcapi
+
+from bitarray import bitarray
+
+
+class Tests(unittest.TestCase):
+
+    def test_finding4(self):
+        got_here = False
+        a = bitarray('10101010' * 1000)
+        a.buffer_info()  # warmup cached namedtuple
+        _testcapi.set_nomemory(1, 0)  # fail all allocations from 1st onward
+        try:
+            a.buffer_info()  # used to segfault
+            _testcapi.remove_mem_hooks()
+        except MemoryError:
+            _testcapi.remove_mem_hooks()
+            got_here = True
+
+        self.assertTrue(got_here)
+
+    def test_finding9(self):
+        got_here = False
+        a = bitarray('1' * 1000)
+        self.assertEqual(len(a), 1000)
+        _testcapi.set_nomemory(5, 0)  # fail from 5th allocation
+        try:
+            a.extend(bitarray('0' * 10_000_000))
+            _testcapi.remove_mem_hooks()
+        except MemoryError:
+            _testcapi.remove_mem_hooks()
+            try:
+                a[0]  # used to segfault — ob_item is NULL
+            except IndexError:
+                got_here = True
+
+        self.assertTrue(got_here)
+        self.assertEqual(len(a), 0)
+
+# ---------------------------------------------------------------------------
+
+if __name__ == '__main__':
+    unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/devel/test_random.py 
new/bitarray-3.8.1/devel/test_random.py
--- old/bitarray-3.8.0/devel/test_random.py     2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/devel/test_random.py     2026-04-02 17:13:02.000000000 
+0200
@@ -797,7 +797,7 @@
 
         # for small p set randomly individual bits, which is much faster
         if p < SMALL_P:
-            return p  # random.binomialvariate() and .random_pop()
+            return p  # random.binomialvariate() and .random_k()
 
         # calculate operator sequence
         i = int(p * K)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/doc/changelog.rst 
new/bitarray-3.8.1/doc/changelog.rst
--- old/bitarray-3.8.0/doc/changelog.rst        2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/doc/changelog.rst        2026-04-02 17:13:02.000000000 
+0200
@@ -1,6 +1,12 @@
 Change log
 ==========
 
+**3.8.1** (2026-04-02):
+
+* fixed critial findings in C Extension Analysis Report, see `#250 
<https://github.com/ilanschnell/bitarray/issues/250>`__
+* add tests, in particular ``devel/test_capi.py``
+
+
 **3.8.0** (2025-11-02):
 
 * add experimental support for free-threaded builds (GIL disabled), `#234 
<https://github.com/ilanschnell/bitarray/issues/234>`__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/doc/indexing.rst 
new/bitarray-3.8.1/doc/indexing.rst
--- old/bitarray-3.8.0/doc/indexing.rst 2025-11-02 21:26:51.000000000 +0100
+++ new/bitarray-3.8.1/doc/indexing.rst 2026-04-02 17:13:02.000000000 +0200
@@ -64,6 +64,17 @@
 Note that ``del a[mask]`` is equivalent to the in-place version of
 selecting the reverse mask ``a = a[~mask]``.
 
-Also note that masked assignment is not implemented,
+As of bitarray version 3.1, masked assignment to bitarrays is also
+supported:
+
+.. code-block:: python
+
+    >>> a =    bitarray('1001001')
+    >>> mask = bitarray('1010111')
+    >>> a[mask] = bitarray("11100")
+    >>> a
+    bitarray('1011100')
+
+However, masked assignment to Booleans is not implemented,
 as ``a[mask] = 1`` would be equivalent to the bitwise operation ``a |= mask``.
 And ``a[mask] = 0`` would be equivalent to ``a &= ~mask``.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-3.8.0/doc/reference.rst 
new/bitarray-3.8.1/doc/reference.rst
--- old/bitarray-3.8.0/doc/reference.rst        2025-11-02 21:26:51.000000000 
+0100
+++ new/bitarray-3.8.1/doc/reference.rst        2026-04-02 17:13:02.000000000 
+0200
@@ -1,7 +1,7 @@
 Reference
 =========
 
-bitarray version: 3.8.0 -- `change log 
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
+bitarray version: 3.8.1 -- `change log 
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
 
 In the following, ``item`` and ``value`` are usually a single bit -
 an integer 0 or 1.

Reply via email to