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 2023-02-11 21:57:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-bitarray (Old)
 and      /work/SRC/openSUSE:Factory/.python-bitarray.new.1848 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-bitarray"

Sat Feb 11 21:57:12 2023 rev:15 rq:1064329 version:2.7.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-bitarray/python-bitarray.changes  
2023-02-10 14:36:13.786246585 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-bitarray.new.1848/python-bitarray.changes    
    2023-02-11 21:57:50.223814417 +0100
@@ -1,0 +2,6 @@
+Fri Feb 10 17:42:13 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 2.7.1:
+  * optimize ``util.sc_encode()``
+
+-------------------------------------------------------------------

Old:
----
  bitarray-2.7.0.tar.gz

New:
----
  bitarray-2.7.1.tar.gz

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

Other differences:
------------------
++++++ python-bitarray.spec ++++++
--- /var/tmp/diff_new_pack.dr6evN/_old  2023-02-11 21:57:50.575816609 +0100
+++ /var/tmp/diff_new_pack.dr6evN/_new  2023-02-11 21:57:50.583816659 +0100
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-bitarray
-Version:        2.7.0
+Version:        2.7.1
 Release:        0
 Summary:        Efficient Arrays of Booleans
 License:        Python-2.0

++++++ bitarray-2.7.0.tar.gz -> bitarray-2.7.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-2.7.0/CHANGE_LOG 
new/bitarray-2.7.1/CHANGE_LOG
--- old/bitarray-2.7.0/CHANGE_LOG       2023-02-05 17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/CHANGE_LOG       2023-02-10 16:30:12.000000000 +0100
@@ -1,3 +1,8 @@
+2023-02-10   2.7.1:
+-------------------
+  * optimize `util.sc_encode()`
+
+
 2023-02-05   2.7.0:
 -------------------
   * add `util.sc_encode()` and `util.sc_decode()` for
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-2.7.0/README.rst 
new/bitarray-2.7.1/README.rst
--- old/bitarray-2.7.0/README.rst       2023-02-05 17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/README.rst       2023-02-10 16:30:12.000000000 +0100
@@ -63,7 +63,7 @@
 
     $ python -c 'import bitarray; bitarray.test()'
     bitarray is installed in: /Users/ilan/bitarray/bitarray
-    bitarray version: 2.7.0
+    bitarray version: 2.7.1
     sys.version: 3.11.0 (main, Oct 25 2022) [Clang 14.0.4]
     sys.prefix: /Users/ilan/Mini3/envs/py311
     pointer size: 64 bit
@@ -401,7 +401,7 @@
 Reference
 =========
 
-bitarray version: 2.7.0 -- `change log 
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
+bitarray version: 2.7.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-2.7.0/bitarray/_util.c 
new/bitarray-2.7.1/bitarray/_util.c
--- old/bitarray-2.7.0/bitarray/_util.c 2023-02-05 17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/bitarray/_util.c 2023-02-10 16:30:12.000000000 +0100
@@ -32,7 +32,7 @@
     return 0;
 }
 
-/* return new bitarray of length 'nbits' (with uninitialized buffer) and
+/* return new bitarray of length `nbits` (with uninitialized buffer) and
    endianness given by the PyObject 'endian' */
 static bitarrayobject *
 new_bitarray(Py_ssize_t nbits, PyObject *endian)
@@ -639,8 +639,8 @@
     return 0;
 }
 
-/* Return new reference to bytes object from either str (unicode) or bytes.
-   On failure, set exception and return NULL. */
+/* Return new reference to bytes object from either ASCII str (unicode) or
+   bytes.  On failure, set exception and return NULL. */
 static PyObject *
 anystr_to_bytes(PyObject *obj)
 {
@@ -669,14 +669,14 @@
 {
     static char *kwlist[] = {"", "endian", NULL};
     PyObject *obj, *bytes, *endian = Py_None;
-    bitarrayobject *a = NULL;
+    bitarrayobject *a;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:hex2ba", kwlist,
                                      &obj, &endian))
         return NULL;
 
     if ((bytes = anystr_to_bytes(obj)) == NULL)
-        goto error;
+        return NULL;
 
     a = new_bitarray(4 * PyBytes_GET_SIZE(bytes), endian);
     if (a == NULL)
@@ -688,7 +688,7 @@
     Py_DECREF(bytes);
     return (PyObject *) a;
  error:
-    Py_XDECREF(bytes);
+    Py_DECREF(bytes);
     Py_XDECREF((PyObject *) a);
     return NULL;
 }
@@ -854,7 +854,7 @@
 {
     static char *kwlist[] = {"", "", "endian", NULL};
     PyObject *obj, *bytes, *endian = Py_None;
-    bitarrayobject *a = NULL;
+    bitarrayobject *a;
     int n, m;                   /* n = 2^m */
 
     if (!PyArg_ParseTupleAndKeywords(args, kwds, "iO|O:base2ba", kwlist,
@@ -865,7 +865,7 @@
         return NULL;
 
     if ((bytes = anystr_to_bytes(obj)) == NULL)
-        goto error;
+        return NULL;
 
     a = new_bitarray(m * PyBytes_GET_SIZE(bytes), endian);
     if (a == NULL)
@@ -877,7 +877,7 @@
     Py_DECREF(bytes);
     return (PyObject *) a;
  error:
-    Py_XDECREF(bytes);
+    Py_DECREF(bytes);
     Py_XDECREF((PyObject *) a);
     return NULL;
 }
@@ -1030,28 +1030,9 @@
     return n;
 }
 
-/* ---------------------- sparse compressed bitarray ------------------- */
-
-/* Bitarray buffer size (in bytes) that can be indexed by n bytes.  E.g.:
-   with 1 byte you can index 256 bits which have a buffer size of 32 bytes,
-   so BSI(1) = 32, BSI(2) = 8192, ... */
-#define BSI(n)  (((Py_ssize_t) 1) << (8 * (n) - 3))
-
-static int
-sc_encode_header(char *str, bitarrayobject *a)
-{
-    int len;
-
-    len = byte_length(a->nbits);
-    *str = (IS_BE(a) ? 0x10 : 0x00) | ((char) len);
-    write_n(str + 1, len, a->nbits);
-
-    return 1 + len;
-}
-
-/* starting at byte index 'i' count the remaining bits */
+/* starting from byte i count the remaining population in bitarray buffer */
 static Py_ssize_t
-count_final(bitarrayobject *a, Py_ssize_t i)
+count_from(bitarrayobject *a, Py_ssize_t i)
 {
     Py_ssize_t cnt = 0;
 
@@ -1064,12 +1045,21 @@
     return cnt;
 }
 
-/* segment size in bytes - although of little practical value, the code
+/* ---------------------- sparse compressed bitarray -------------------
+ *
+ * see also: doc/sparse_compression.rst
+ */
+
+/* Bitarray buffer size (in bytes) that can be indexed by n bytes.  E.g.:
+   with 1 byte you can index 256 bits which have a buffer size of 32 bytes.
+   BSI(1) = 32, BSI(2) = 8_192, BSI(3) = 2_097_152, BSI(4) = 536_870_912 */
+#define BSI(n)  (((Py_ssize_t) 1) << (8 * (n) - 3))
+
+/* segment size in bytes - Although of little practical value, the code
    below will also work when changing SEGSIZE to 1, 2, 4, 8 or 16, as long
    as a multiple of SEGSIZE is 32.  The size 32 is rooted in the fact that
    a bitarray of 32 bytes (256 bits) can be indexed with one index byte
-   (BSI(0) = 32).  Our entire 'sc' format is constructed around this.
- */
+   (BSI(1) = 32).  Our entire 'sc' format is constructed around this. */
 #define SEGSIZE  32
 
 /* number of 256 bit segments given nbits */
@@ -1079,44 +1069,44 @@
    Note that we call these "segments", as opposed to "blocks", in order to
    avoid confusion with encode blocks.
 
-   0       1       2       3       4       5    6   index into rts array, i
-   +-------+-------+-------+-------+-------+----+
-   |     5 |     7 |     0 |    11 |     6 |  4 |   count per segment
-   +-------+-------+-------+-------+-------+----+
-   0       5      12      12      23      29   33   running totals, rts[i]
-
-   In this example we have a bitarray with 6 segments, e.g. with 1407 bits.
-   Note that:
-
-     * Here we have 6 segments, but the rts array has a size
-       of 7 elements: 0 .. 6
-       The rts array has always NSEG(nbits) + 1 elements, such that the
-       last element is always indexed by NSEG(nbits).  Here, NSEG(1407) = 6
-
-     * The zeroth element rts[0] is always zero.
-
-     * The last last element rts[NSEG(nbits)] is always the total count.
-       Here: rts[NSEG(nbits)] = rts[NSEG(1407)] = rts[6] = 33
-
-     * The last segment may be partial.  Here, spanning 127 bits, that
-       is a[1280:1407].  The count of this segment is 4:
-       a[1280:].count() = a.count(1, 1280) = 4
-
-     * The segment a[512:768] has a count of zero, such that: rts[2] = rts[3]
-
-   As each segment covers 256 bits (32 bytes), and each element in the
-   running totals array takes up 8 bytes (on a 64-bit machine at least) the
-   additional memory to accommodate the rts array is 1/4 of the bitarrays
-   memory.  However, calculating this array upfront allows count_block() to
+   0           1           2           3           4   index in rts array, i
+   +-----------+-----------+-----------+-----------+
+   |      5    |      0    |      3    |      4    |   segment population
+   |           |           |           |           |
+   |  [0:256]  | [256:512] | [512:768] | [768:987] |   bitarray slice
+   +-----------+-----------+-----------+-----------+
+   0           5           5           8          12   running totals, rts[i]
+
+   In this example we have a bitarray of length nbits = 987.  Note that:
+
+     * The number of segments is given by NSEG(nbits).
+       Here we have 4 segments: NSEG(nbits) = NSEG(987) = 4
+
+     * The rts array has always NSEG(nbits) + 1 elements, such that
+       last element is always indexed by NSEG(nbits).
+
+     * The element rts[0] is always zero.
+
+     * The last element rts[NSEG(nbits)] is always the total count.
+       Here: rts[NSEG(nbits)] = rts[NSEG(987)] = rts[4] = 12
+
+     * The last segment may be partial.  In that case, it's size it given
+       by nbits % 256.  Here: nbits % 256 = 987 % 256 = 219
+
+   As each segment (at large) covers 256 bits (32 bytes), and each element
+   in the running totals array takes up 8 bytes (on a 64-bit machine) the
+   additional memory to accommodate the rts array is therefore 1/4 of the
+   bitarray's memory.
+   However, calculating this array upfront allows sc_count() to
    simply look up two entries from the array and take their difference.
-   Thus, the speedup we get can be significant.
+   Thus, the speedup is significant.
 
-   The function write_sparse_block() also takes advantage of the running
-   totals array, as it can quickly check for segments that only contain
-   only zeros to skip.
+   The function sc_write_indices() also takes advantage of the running
+   totals array.  It loops over segments and skips to the next segment as
+   soon as the count the current segment is reached.
 */
 static Py_ssize_t *
-calc_rts(bitarrayobject *a)
+sc_calc_rts(bitarrayobject *a)
 {
     const Py_ssize_t n_seg = NSEG(a->nbits);  /* number of segments */
     const Py_ssize_t c_seg = a->nbits / (8 * SEGSIZE);  /* complete segs */
@@ -1125,6 +1115,7 @@
     char *buff;
     Py_ssize_t *res, i, j;
 
+    assert(n_seg == c_seg || n_seg == c_seg + 1);
     memset(zeros, 0x00, SEGSIZE);
     res = (Py_ssize_t *) PyMem_Malloc((size_t)
                                       sizeof(Py_ssize_t) * (n_seg + 1));
@@ -1144,11 +1135,10 @@
     res[c_seg] = cnt;
 
     if (n_seg > c_seg) {           /* we have a final partial segment */
-        assert(n_seg == c_seg + 1);
         assert(Py_SIZE(a) <= SEGSIZE * n_seg);
         assert(a->nbits && a->nbits < 8 * SEGSIZE * n_seg);
 
-        cnt += count_final(a, SEGSIZE * c_seg);
+        cnt += count_from(a, SEGSIZE * c_seg);
         res[n_seg] = cnt;
     }
     return res;
@@ -1161,7 +1151,7 @@
    The offset is required to be multiple of 32 (the segment size), as this
    functions makes use of running totals (stored in Py_ssize_t array rts). */
 static Py_ssize_t
-count_block(bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset, int n)
+sc_count(bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset, int n)
 {
     Py_ssize_t nbits;
 
@@ -1178,8 +1168,7 @@
        is 1 << 32.  This is problematic, as 32-bit machines can address
        at least partially filled type 4 blocks).  Therefore, we first
        limit BSI(n) by the buffer size before multiplying 8. */
-    nbits = Py_MIN(8 * Py_MIN(BSI(n), Py_SIZE(a)),
-                   a->nbits - 8 * offset);
+    nbits = Py_MIN(8 * Py_MIN(BSI(n), Py_SIZE(a)), a->nbits - 8 * offset);
     assert(nbits >= 0);
 
     offset /= SEGSIZE;               /* offset in terms of segments now */
@@ -1193,10 +1182,9 @@
    buffer str), and return the number of raw bytes.
    Note that the encoded block size is the return value + 1. */
 static int
-write_raw_block(char *str, bitarrayobject *a, Py_ssize_t *rts,
-                Py_ssize_t offset)
+sc_write_raw(char *str, bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset)
 {
-    Py_ssize_t nbytes = Py_SIZE(a) - offset;  /* remaining bytes */
+    const Py_ssize_t nbytes = Py_SIZE(a) - offset;  /* remaining bytes */
     Py_ssize_t k = Py_MIN(32, nbytes);
 
     assert(nbytes > 0);
@@ -1205,8 +1193,10 @@
            raw bytes (otherwise this function wouldn't have been called).
            Now also check the next 3 segments. */
         while (k < 128 &&
-               Py_MIN(32, nbytes - k) <= count_block(a, rts, offset + k, 1))
+               Py_MIN(32, nbytes - k) <= sc_count(a, rts, offset + k, 1))
             k += 32;
+
+        assert(k % SEGSIZE == 0);
     }
     k = Py_MIN(k, nbytes);
     assert(0 < k && k <= 128 && k <= nbytes);
@@ -1221,56 +1211,87 @@
     return (int) k;
 }
 
-/* Encode one sparse block (from offset, and up to k one bits).
-   Return number of bytes written to buffer str (encoded block size). */
+/* Write `k` indices (of `n` bytes each) into buffer `str`.
+   Note that `n` (which is also the block type) has been selected
+   (in sc_encode_block()) such that:
+
+       k = sc_count(a, rts, offset, n) < 256
+*/
+static void
+sc_write_indices(char *str, bitarrayobject *a, Py_ssize_t *rts,
+                 Py_ssize_t offset, int n, int k)
+{
+    const char *str_stop = str + n * k;  /* stop position in buffer `str` */
+    const char *buff = a->ob_item + offset;
+    Py_ssize_t m, i;
+
+    assert(1 <= n && n <= 4);
+    assert(0 < k && k < 256);  /* note that k cannot be 0 in this function */
+    assert(k == sc_count(a, rts, offset, n));   /* see above */
+    assert(offset % SEGSIZE == 0);
+
+    rts += offset / SEGSIZE;   /* rts index relative to offset now */
+
+    for (m = 0;;) {  /* loop segments */
+        int j, ni;
+
+        assert(m + offset / SEGSIZE < NSEG(a->nbits));
+        ni = (int) (rts[m + 1] - rts[m]);  /* indices in this segment */
+        if (ni == 0)
+            goto next_segment;
+
+        for (i = m * SEGSIZE;; i++) {  /* loop bytes in segment */
+            assert(i < (m + 1) * SEGSIZE && i + offset < Py_SIZE(a));
+            if (buff[i] == 0)
+                continue;
+
+            for (j = 0; j < 8; j++)  /* loop bits */
+                if (buff[i] & BITMASK(a, j)) {
+                    write_n(str, n, 8 * i + j);
+                    str += n;
+                    if (--ni == 0) {
+                        /* we have encountered all indices in this segment */
+                        if (str == str_stop)
+                            return;
+                        goto next_segment;
+                    }
+                }
+        }
+    next_segment:
+        m++;
+    }
+    Py_UNREACHABLE();
+}
+
+#undef SEGSIZE
+#undef NSEG
+
+/* Write one sparse block (from `offset`, and up to `k` one bits).
+   Return number of bytes written to buffer `str` (encoded block size). */
 static Py_ssize_t
-write_sparse_block(char *str, bitarrayobject *a, Py_ssize_t *rts,
-                   Py_ssize_t offset, int n, int k)
+sc_write_sparse(char *str, bitarrayobject *a, Py_ssize_t *rts,
+                Py_ssize_t offset, int n, int k)
 {
-    /* bytes to encode limited by remaining buffer size */
-    Py_ssize_t na = Py_MIN(BSI(n), Py_SIZE(a) - offset);
-    Py_ssize_t i, j, outsize, len = 0;
-    char *buff = a->ob_item + offset;
+    int len = 0;
 
-    assert(offset % SEGSIZE == 0);
-    assert(1 <= n && n <= 4 && 0 <= k && k < 256);
-    assert(na > 0 && offset + na <= Py_SIZE(a));
+    assert(1 <= n && n <= 4);
+    assert(0 <= k && k < 256);
 
-    /* block header */
+    /* write block header */
     if (n == 1) {               /* type 1 - single byte for each position */
         assert(k < 32);
-        str[len++] = 0xa0 + k;
+        str[len++] = (char) (0xa0 + k);
     }
-    else {            /* type 2, 3, 4 - multiple bytes for each positions */
-        str[len++] = 0xc0 + n;
-        str[len++] = k;
+    else {                 /* type 2, 3, 4 - `n` bytes for each positions */
+        str[len++] = (char) (0xc0 + n);
+        str[len++] = (char) k;
     }
     if (k == 0)  /* no index bytes */
         return len;
 
-    /* block data */
-    outsize = len + n * k;
-    for (i = 0; i < na; i++) {
-        if (i % SEGSIZE == 0) {
-            j = (i + offset) / SEGSIZE;  /* running total index */
-            assert(j < NSEG(a->nbits));
-            if (rts[j] == rts[j + 1]) {  /* the segment has only zeros */
-                i += SEGSIZE - 1;        /* skip ahead */
-                continue;
-            }
-        }
-        assert(offset + i < Py_SIZE(a));
-        if (buff[i])
-            for (j = 0; j < 8; j++)
-                if (buff[i] & BITMASK(a, j)) {
-                    write_n(str + len, n, 8 * i + j);
-                    len += n;
-                    if (len == outsize)  /* final index reached */
-                        return len;
-                }
-    }
-    Py_FatalError("internal sc_encode() error");
-    return -1;  /* cannot happen - silence compiler warning */
+    /* write block data - `k` indices, `n` bytes per index */
+    sc_write_indices(str + len, a, rts, offset, n, k);
+    return len + n * k;
 }
 
 /* Encode one block (starting at offset) and return offset increment.
@@ -1312,15 +1333,15 @@
 sc_encode_block(char *str, Py_ssize_t *len,
                 bitarrayobject *a, Py_ssize_t *rts, Py_ssize_t offset)
 {
-    Py_ssize_t nbytes = Py_SIZE(a) - offset;        /* remaining bytes */
+    const Py_ssize_t nbytes = Py_SIZE(a) - offset;  /* remaining bytes */
     int count, n;
 
     assert(nbytes > 0);
 
-    count = (int) count_block(a, rts, offset, 1);
+    count = (int) sc_count(a, rts, offset, 1);
     /* are there fewer or equal raw bytes than index bytes */
     if (Py_MIN(32, nbytes) <= count) {           /* type 0 - raw bytes */
-        int k = write_raw_block(str + *len, a, rts, offset);
+        int k = sc_write_raw(str + *len, a, rts, offset);
         *len += 1 + k;
         return k;
     }
@@ -1329,7 +1350,7 @@
         Py_ssize_t next_count, size_a, size_b;
 
         /* population for next block type n+1 */
-        next_count = count_block(a, rts, offset, n + 1);
+        next_count = sc_count(a, rts, offset, n + 1);
         if (next_count >= 256)
             /* too many index bytes for next block type n+1 */
             break;
@@ -1347,12 +1368,21 @@
         count = (int) next_count;
     }
 
-    *len += write_sparse_block(str + *len, a, rts, offset, n, count);
+    *len += sc_write_sparse(str + *len, a, rts, offset, n, count);
     return BSI(n);
 }
 
-#undef SEGSIZE
-#undef NSEG
+static int
+sc_encode_header(char *str, bitarrayobject *a)
+{
+    int len;
+
+    len = byte_length(a->nbits);
+    *str = (IS_BE(a) ? 0x10 : 0x00) | ((char) len);
+    write_n(str + 1, len, a->nbits);
+
+    return 1 + len;
+}
 
 static PyObject *
 sc_encode(PyObject *module, PyObject *obj)
@@ -1361,14 +1391,15 @@
     char *str;                  /* output buffer */
     Py_ssize_t len = 0;         /* bytes written into output buffer */
     bitarrayobject *a;
-    Py_ssize_t offset = 0;      /* block offset into bitarray a in bytes */
+    Py_ssize_t offset = 0;      /* block offset into bitarray `a` in bytes */
     Py_ssize_t *rts;            /* running totals for 256 bit segments */
 
     if (ensure_bitarray(obj) < 0)
         return NULL;
 
     a = (bitarrayobject *) obj;
-    if ((rts = calc_rts(a)) == NULL)
+    set_padbits(a);
+    if ((rts = sc_calc_rts(a)) == NULL)
         return NULL;
 
     out = PyBytes_FromStringAndSize(NULL, 32768);
@@ -1383,7 +1414,7 @@
 
         /* Make sure we have enough space in output buffer for next block.
            The largest block possible is a type 4 block with 255 indices.
-           It's site is: 2 header bytes + 4 * 255 index bytes */
+           It's size is: 2 header bytes + 4 * 255 index bytes */
         allocated = PyBytes_GET_SIZE(out);
         if (allocated < len + 2 + 4 * 255) {  /* increase allocation */
             if (_PyBytes_Resize(&out, allocated + 32768) < 0)
@@ -1440,10 +1471,10 @@
 /* Read k bytes from iter and set elements in bitarray.  Return the size of
    the offset increment in bytes (i.e. just k), or -1 on failure. */
 static Py_ssize_t
-read_raw_block(bitarrayobject *a, Py_ssize_t offset, PyObject *iter, int k)
+sc_read_raw(bitarrayobject *a, Py_ssize_t offset, PyObject *iter, int k)
 {
-    Py_ssize_t i;
     char *buff = a->ob_item + offset;
+    Py_ssize_t i;
 
     if (offset + k > Py_SIZE(a)) {
         PyErr_Format(PyExc_ValueError, "decode error (raw): %zd + %d > %zd",
@@ -1463,8 +1494,8 @@
 /* Read n * k bytes from iter and set elements in bitarray.
    Return size of offset increment in bytes, or -1 on failure. */
 static Py_ssize_t
-read_sparse_block(bitarrayobject *a, Py_ssize_t offset, PyObject *iter,
-                  int n, int k)
+sc_read_sparse(bitarrayobject *a, Py_ssize_t offset, PyObject *iter,
+               int n, int k)
 {
     assert(1 <= n && n <= 4 && k >= 0);
     while (k--) {
@@ -1499,10 +1530,10 @@
         return 0;
 
     if (head <= 0x80)                      /* type 0 - 0x01 .. 0x80 */
-        return read_raw_block(a, offset, iter, head);
+        return sc_read_raw(a, offset, iter, head);
 
     if (0xa0 <= head && head < 0xc0)       /* type 1 - 0xa0 .. 0xbf */
-        return read_sparse_block(a, offset, iter, 1, head - 0xa0);
+        return sc_read_sparse(a, offset, iter, 1, head - 0xa0);
 
     if (0xc2 <= head && head <= 0xc4) {    /* type 2 .. 4 - 0xc2 .. 0xc4 */
         int k;
@@ -1510,7 +1541,7 @@
         if ((k = next_char(iter)) < 0)
             return -1;
 
-        return read_sparse_block(a, offset, iter, head - 0xc0, k);
+        return sc_read_sparse(a, offset, iter, head - 0xc0, k);
     }
 
     PyErr_Format(PyExc_ValueError, "invalid block head: 0x%02x", head);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-2.7.0/bitarray/bitarray.h 
new/bitarray-2.7.1/bitarray/bitarray.h
--- old/bitarray-2.7.0/bitarray/bitarray.h      2023-02-05 17:58:14.000000000 
+0100
+++ new/bitarray-2.7.1/bitarray/bitarray.h      2023-02-10 16:30:12.000000000 
+0100
@@ -4,7 +4,7 @@
 
    Author: Ilan Schnell
 */
-#define BITARRAY_VERSION  "2.7.0"
+#define BITARRAY_VERSION  "2.7.1"
 
 #ifdef STDC_HEADERS
 #include <stddef.h>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-2.7.0/bitarray/test_bitarray.py 
new/bitarray-2.7.1/bitarray/test_bitarray.py
--- old/bitarray-2.7.0/bitarray/test_bitarray.py        2023-02-05 
17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/bitarray/test_bitarray.py        2023-02-10 
16:30:12.000000000 +0100
@@ -1142,6 +1142,21 @@
         a[2:5] = bitarray('0')  # remove
         self.assertEqual(a, bitarray('11011'))
 
+    def test_setslice_frozenbitarray(self):
+        a = bitarray('11111111 1111')
+        b = frozenbitarray('0000')
+        a[2:6] = b
+        self.assertEqual(a, bitarray('11000011 1111'))
+        self.assertIsType(b, 'frozenbitarray')
+        self.assertEqual(b, bitarray('0000'))
+
+        b = frozenbitarray('011100')
+        a[::2] = b
+        self.assertEqual(a, bitarray('01101011 0101'))
+        self.check_obj(a)
+        self.assertIsType(b, 'frozenbitarray')
+        self.assertEqual(b, bitarray('011100'))
+
     def test_setslice_bitarray_random_same_length(self):
         for endian in 'little', 'big':
             for _ in range(100):
@@ -2750,22 +2765,6 @@
         self.assertRaises(IndexError, a.bytereverse, 5)
         self.assertRaises(IndexError, a.bytereverse, 0, 5)
 
-    @skipIf(sys.version_info[0] == 2)
-    def test_bytereverse_part(self):
-        a = bitarray(5, 'big')
-        memoryview(a)[0] = 0x13  # 0001 0011
-        self.assertEqual(a, bitarray('0001 0'))
-        # the padbits (011) are not treated as zeros
-        a.bytereverse()
-        self.assertEqual(a, bitarray('1100 1'))
-
-        a = bitarray(12, 'little')
-        memoryview(a)[1] = 0xd4  # .... ....  0010 1011
-        self.assertEqual(a[8:], bitarray('0010'))
-        # the padbits (1011) are not treated as zeros
-        a.bytereverse(1)
-        self.assertEqual(a[8:], bitarray('1101'))
-
     def test_bytereverse_byte(self):
         for i in range(256):
             a = bitarray()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-2.7.0/bitarray/test_util.py 
new/bitarray-2.7.1/bitarray/test_util.py
--- old/bitarray-2.7.0/bitarray/test_util.py    2023-02-05 17:58:14.000000000 
+0100
+++ new/bitarray-2.7.1/bitarray/test_util.py    2023-02-10 16:30:12.000000000 
+0100
@@ -948,21 +948,22 @@
             self.assertEqual(ba2hex(a_be), hex_be)
             self.assertEqual(ba2hex(a_le), hex_le)
 
-    def test_round_trip(self):
-        s = ''.join(choice(hexdigits) for _ in range(randint(20, 100)))
+    def test_hexdigits(self):
         for default_endian in 'big', 'little':
             _set_default_endian(default_endian)
-            a = hex2ba(s)
-            self.check_obj(a)
+            a = hex2ba(hexdigits)
             self.assertEqual(len(a) % 4, 0)
             self.assertEqual(a.endian(), default_endian)
+            self.assertIsType(a, 'bitarray')
+            self.check_obj(a)
+
             t = ba2hex(a)
-            self.assertEqual(t, s.lower())
-            b = hex2ba(t, default_endian)
-            self.assertEQUAL(a, b)
+            self.assertEqual(t, hexdigits.lower())
+            self.assertIsInstance(t, str)
+            self.assertEQUAL(a, hex2ba(t, default_endian))
 
     def test_binascii(self):
-        a = urandom(800, 'big')
+        a = urandom(80, 'big')
         s = binascii.hexlify(a.tobytes()).decode()
         self.assertEqual(ba2hex(a), s)
         b = bitarray(endian='big')
@@ -1145,8 +1146,7 @@
                 (b'\x11\x09\xa1\x08\0',     '00000000 1',        'big'),
                 (b'\x01E\xa3ABD\0',         65 * '0' + '1101',   'little'),
         ]:
-            # the padbits in a frozenbitarray are guaranteed to be zero
-            a = frozenbitarray(bits, endian)
+            a = bitarray(bits, endian)
             self.assertEqual(sc_encode(a), b)
             self.assertEqual(sc_decode(b), a)
 
@@ -1345,16 +1345,16 @@
         for a in bitarray('1', 'big'), frozenbitarray('1', 'big'):
             b = sc_encode(a)
             self.assertIsInstance(b, bytes)
-            self.assertEqual(len(b), 5)
+            self.assertEqual(b, b'\x11\x01\x01\x80\0')
 
         for a in None, [], 0, 123, b'', b'\x00', 3.14:
             self.assertRaises(TypeError, sc_encode, a)
 
     def round_trip(self, a):
-        b = sc_encode(a)
-        c = sc_decode(b)
-        self.assertEqual(a, c)
-        self.assertEqual(a.endian(), c.endian())
+        c = a.copy()
+        b = sc_decode(sc_encode(a))
+        self.assertTrue(a == b == c)
+        self.assertTrue(a.endian() == b.endian() == c.endian())
 
     def test_encode_zeros(self):
         for i in range(18):
@@ -1523,10 +1523,10 @@
             self.assertEqual(vl_decode(s), a)
 
     def round_trip(self, a):
+        c = a.copy()
         s = vl_encode(a)
         b = vl_decode(s)
-        self.check_obj(b)
-        self.assertEqual(a, b)
+        self.assertTrue(a == b == c)
         LEN_PAD_BITS = 3
         self.assertEqual(len(s), (len(a) + LEN_PAD_BITS + 6) // 7)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-2.7.0/doc/changelog.rst 
new/bitarray-2.7.1/doc/changelog.rst
--- old/bitarray-2.7.0/doc/changelog.rst        2023-02-05 17:58:14.000000000 
+0100
+++ new/bitarray-2.7.1/doc/changelog.rst        2023-02-10 16:30:12.000000000 
+0100
@@ -1,6 +1,11 @@
 Change log
 ==========
 
+**2.7.1** (2023-02-10):
+
+* optimize ``util.sc_encode()``
+
+
 **2.7.0** (2023-02-05):
 
 * add ``util.sc_encode()`` and ``util.sc_decode()`` for
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bitarray-2.7.0/doc/reference.rst 
new/bitarray-2.7.1/doc/reference.rst
--- old/bitarray-2.7.0/doc/reference.rst        2023-02-05 17:58:14.000000000 
+0100
+++ new/bitarray-2.7.1/doc/reference.rst        2023-02-10 16:30:12.000000000 
+0100
@@ -1,7 +1,7 @@
 Reference
 =========
 
-bitarray version: 2.7.0 -- `change log 
<https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
+bitarray version: 2.7.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-2.7.0/doc/sparse_compression.rst 
new/bitarray-2.7.1/doc/sparse_compression.rst
--- old/bitarray-2.7.0/doc/sparse_compression.rst       2023-02-05 
17:58:14.000000000 +0100
+++ new/bitarray-2.7.1/doc/sparse_compression.rst       2023-02-10 
16:30:12.000000000 +0100
@@ -48,7 +48,7 @@
                      compress (ms)   decompress (ms)    ratio
    ----------------------------------------------------------
    serialize            4.562             1.188        1.0000
-   sc                   7.864             2.680        0.0158
+   sc                   6.069             2.680        0.0158
    gzip               920.343            16.161        0.0169
    bz2                 59.580            33.435        0.0117
 

Reply via email to