bitarray 3.7.2__tar.gz → 3.8.0__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.7.2 → bitarray-3.8.0}/PKG-INFO +7 -6
- {bitarray-3.7.2 → bitarray-3.8.0}/README.rst +5 -5
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/__init__.py +1 -2
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/__init__.pyi +0 -1
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/_bitarray.c +17 -38
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/_util.c +4 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/bitarray.h +3 -1
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/pythoncapi_compat.h +391 -2
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/test_bitarray.py +43 -64
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/test_util.py +21 -41
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray.egg-info/PKG-INFO +7 -6
- {bitarray-3.7.2 → bitarray-3.8.0}/setup.py +1 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/LICENSE +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/py.typed +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/test_281.pickle +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/util.py +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray/util.pyi +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray.egg-info/SOURCES.txt +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray.egg-info/dependency_links.txt +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray.egg-info/not-zip-safe +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/bitarray.egg-info/top_level.txt +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/pyproject.toml +0 -0
- {bitarray-3.7.2 → bitarray-3.8.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bitarray
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.8.0
|
|
4
4
|
Summary: efficient arrays of booleans -- C extension
|
|
5
5
|
Home-page: https://github.com/ilanschnell/bitarray
|
|
6
6
|
Author: Ilan Schnell
|
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Programming Language :: Python :: Free Threading :: 1 - Unstable
|
|
23
24
|
Classifier: Topic :: Utilities
|
|
24
25
|
License-File: LICENSE
|
|
25
26
|
Dynamic: author
|
|
@@ -90,7 +91,7 @@ Once you have installed the package, you may want to test it:
|
|
|
90
91
|
|
|
91
92
|
$ python -c 'import bitarray; bitarray.test()'
|
|
92
93
|
bitarray is installed in: /Users/ilan/bitarray/bitarray
|
|
93
|
-
bitarray version: 3.
|
|
94
|
+
bitarray version: 3.8.0
|
|
94
95
|
sys.version: 3.13.5 (main, Jun 16 2025) [Clang 18.1.8]
|
|
95
96
|
sys.prefix: /Users/ilan/miniforge
|
|
96
97
|
pointer size: 64 bit
|
|
@@ -99,13 +100,14 @@ Once you have installed the package, you may want to test it:
|
|
|
99
100
|
HAVE_BUILTIN_BSWAP64: 1
|
|
100
101
|
default bit-endianness: big
|
|
101
102
|
machine byte-order: little
|
|
103
|
+
Py_GIL_DISABLED: 0
|
|
102
104
|
Py_DEBUG: 0
|
|
103
105
|
DEBUG: 0
|
|
104
106
|
.........................................................................
|
|
105
107
|
.........................................................................
|
|
106
108
|
................................................................
|
|
107
109
|
----------------------------------------------------------------------
|
|
108
|
-
Ran
|
|
110
|
+
Ran 595 tests in 0.165s
|
|
109
111
|
|
|
110
112
|
OK
|
|
111
113
|
|
|
@@ -352,7 +354,7 @@ and can therefore be used as a dictionary key:
|
|
|
352
354
|
Reference
|
|
353
355
|
=========
|
|
354
356
|
|
|
355
|
-
bitarray version: 3.
|
|
357
|
+
bitarray version: 3.8.0 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
|
|
356
358
|
|
|
357
359
|
In the following, ``item`` and ``value`` are usually a single bit -
|
|
358
360
|
an integer 0 or 1.
|
|
@@ -588,6 +590,7 @@ bitarray methods:
|
|
|
588
590
|
|
|
589
591
|
``tobytes()`` -> bytes
|
|
590
592
|
Return the bitarray buffer (pad bits are set to zero).
|
|
593
|
+
``a.tobytes()`` is equivalent to ``bytes(a)``
|
|
591
594
|
|
|
592
595
|
|
|
593
596
|
``tofile(f, /)``
|
|
@@ -658,8 +661,6 @@ Functions defined in the `bitarray` module:
|
|
|
658
661
|
|
|
659
662
|
``get_default_endian()`` -> str
|
|
660
663
|
Return the default bit-endianness for new bitarray objects being created.
|
|
661
|
-
Unless ``_set_default_endian('little')`` was called, the default
|
|
662
|
-
bit-endianness is ``big``.
|
|
663
664
|
|
|
664
665
|
New in version 1.3
|
|
665
666
|
|
|
@@ -57,7 +57,7 @@ Once you have installed the package, you may want to test it:
|
|
|
57
57
|
|
|
58
58
|
$ python -c 'import bitarray; bitarray.test()'
|
|
59
59
|
bitarray is installed in: /Users/ilan/bitarray/bitarray
|
|
60
|
-
bitarray version: 3.
|
|
60
|
+
bitarray version: 3.8.0
|
|
61
61
|
sys.version: 3.13.5 (main, Jun 16 2025) [Clang 18.1.8]
|
|
62
62
|
sys.prefix: /Users/ilan/miniforge
|
|
63
63
|
pointer size: 64 bit
|
|
@@ -66,13 +66,14 @@ Once you have installed the package, you may want to test it:
|
|
|
66
66
|
HAVE_BUILTIN_BSWAP64: 1
|
|
67
67
|
default bit-endianness: big
|
|
68
68
|
machine byte-order: little
|
|
69
|
+
Py_GIL_DISABLED: 0
|
|
69
70
|
Py_DEBUG: 0
|
|
70
71
|
DEBUG: 0
|
|
71
72
|
.........................................................................
|
|
72
73
|
.........................................................................
|
|
73
74
|
................................................................
|
|
74
75
|
----------------------------------------------------------------------
|
|
75
|
-
Ran
|
|
76
|
+
Ran 595 tests in 0.165s
|
|
76
77
|
|
|
77
78
|
OK
|
|
78
79
|
|
|
@@ -319,7 +320,7 @@ and can therefore be used as a dictionary key:
|
|
|
319
320
|
Reference
|
|
320
321
|
=========
|
|
321
322
|
|
|
322
|
-
bitarray version: 3.
|
|
323
|
+
bitarray version: 3.8.0 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
|
|
323
324
|
|
|
324
325
|
In the following, ``item`` and ``value`` are usually a single bit -
|
|
325
326
|
an integer 0 or 1.
|
|
@@ -555,6 +556,7 @@ bitarray methods:
|
|
|
555
556
|
|
|
556
557
|
``tobytes()`` -> bytes
|
|
557
558
|
Return the bitarray buffer (pad bits are set to zero).
|
|
559
|
+
``a.tobytes()`` is equivalent to ``bytes(a)``
|
|
558
560
|
|
|
559
561
|
|
|
560
562
|
``tofile(f, /)``
|
|
@@ -625,8 +627,6 @@ Functions defined in the `bitarray` module:
|
|
|
625
627
|
|
|
626
628
|
``get_default_endian()`` -> str
|
|
627
629
|
Return the default bit-endianness for new bitarray objects being created.
|
|
628
|
-
Unless ``_set_default_endian('little')`` was called, the default
|
|
629
|
-
bit-endianness is ``big``.
|
|
630
630
|
|
|
631
631
|
New in version 1.3
|
|
632
632
|
|
|
@@ -13,8 +13,7 @@ from collections import namedtuple
|
|
|
13
13
|
|
|
14
14
|
from bitarray._bitarray import (
|
|
15
15
|
bitarray, decodetree, bits2bytes, _bitarray_reconstructor,
|
|
16
|
-
get_default_endian,
|
|
17
|
-
BITARRAY_VERSION as __version__
|
|
16
|
+
get_default_endian, _sysinfo, BITARRAY_VERSION as __version__
|
|
18
17
|
)
|
|
19
18
|
|
|
20
19
|
__all__ = ['bitarray', 'frozenbitarray', 'decodetree', 'bits2bytes']
|
|
@@ -162,7 +162,6 @@ __version__: str
|
|
|
162
162
|
def bits2bytes(n: int) -> int: ...
|
|
163
163
|
def get_default_endian() -> str: ...
|
|
164
164
|
def test(verbosity: int = ...) -> TextTestResult: ...
|
|
165
|
-
def _set_default_endian(endian: str) -> None: ...
|
|
166
165
|
def _sysinfo(key: str) -> int: ...
|
|
167
166
|
def _bitarray_reconstructor(cls: type,
|
|
168
167
|
buffer: bytes,
|
|
@@ -16,9 +16,6 @@
|
|
|
16
16
|
/* size used when reading / writing blocks from files (in bytes) */
|
|
17
17
|
#define BLOCKSIZE 65536
|
|
18
18
|
|
|
19
|
-
/* default bit-endianness */
|
|
20
|
-
static int default_endian = ENDIAN_BIG;
|
|
21
|
-
|
|
22
19
|
/* translation table - setup during module initialization */
|
|
23
20
|
static char reverse_trans[256];
|
|
24
21
|
|
|
@@ -1576,7 +1573,8 @@ bitarray_tobytes(bitarrayobject *self)
|
|
|
1576
1573
|
PyDoc_STRVAR(tobytes_doc,
|
|
1577
1574
|
"tobytes() -> bytes\n\
|
|
1578
1575
|
\n\
|
|
1579
|
-
Return the bitarray buffer (pad bits are set to zero)
|
|
1576
|
+
Return the bitarray buffer (pad bits are set to zero).\n\
|
|
1577
|
+
`a.tobytes()` is equivalent to `bytes(a)`");
|
|
1580
1578
|
|
|
1581
1579
|
|
|
1582
1580
|
/* Extend self with bytes from f.read(n). Return number of bytes actually
|
|
@@ -3116,7 +3114,7 @@ decodetree_todict(decodetreeobject *self)
|
|
|
3116
3114
|
if ((dict = PyDict_New()) == NULL)
|
|
3117
3115
|
return NULL;
|
|
3118
3116
|
|
|
3119
|
-
prefix = newbitarrayobject(&Bitarray_Type, 0,
|
|
3117
|
+
prefix = newbitarrayobject(&Bitarray_Type, 0, ENDIAN_DEFAULT);
|
|
3120
3118
|
if (prefix == NULL)
|
|
3121
3119
|
goto error;
|
|
3122
3120
|
|
|
@@ -3565,6 +3563,8 @@ static PyMethodDef bitarray_methods[] = {
|
|
|
3565
3563
|
to01_doc},
|
|
3566
3564
|
{"tobytes", (PyCFunction) bitarray_tobytes, METH_NOARGS,
|
|
3567
3565
|
tobytes_doc},
|
|
3566
|
+
{"__bytes__", (PyCFunction) bitarray_tobytes, METH_NOARGS,
|
|
3567
|
+
tobytes_doc},
|
|
3568
3568
|
{"tofile", (PyCFunction) bitarray_tofile, METH_O,
|
|
3569
3569
|
tofile_doc},
|
|
3570
3570
|
{"tolist", (PyCFunction) bitarray_tolist, METH_NOARGS,
|
|
@@ -3600,10 +3600,8 @@ static PyMethodDef bitarray_methods[] = {
|
|
|
3600
3600
|
static int
|
|
3601
3601
|
endian_from_string(const char *str)
|
|
3602
3602
|
{
|
|
3603
|
-
assert(default_endian == ENDIAN_LITTLE || default_endian == ENDIAN_BIG);
|
|
3604
|
-
|
|
3605
3603
|
if (str == NULL)
|
|
3606
|
-
return
|
|
3604
|
+
return ENDIAN_DEFAULT;
|
|
3607
3605
|
|
|
3608
3606
|
if (strcmp(str, "little") == 0)
|
|
3609
3607
|
return ENDIAN_LITTLE;
|
|
@@ -4126,39 +4124,13 @@ reconstructor(PyObject *module, PyObject *args)
|
|
|
4126
4124
|
static PyObject *
|
|
4127
4125
|
get_default_endian(PyObject *module)
|
|
4128
4126
|
{
|
|
4129
|
-
return PyUnicode_FromString(ENDIAN_STR(
|
|
4127
|
+
return PyUnicode_FromString(ENDIAN_STR(ENDIAN_DEFAULT));
|
|
4130
4128
|
}
|
|
4131
4129
|
|
|
4132
4130
|
PyDoc_STRVAR(get_default_endian_doc,
|
|
4133
4131
|
"get_default_endian() -> str\n\
|
|
4134
4132
|
\n\
|
|
4135
|
-
Return the default bit-endianness for new bitarray objects being created
|
|
4136
|
-
Unless `_set_default_endian('little')` was called, the default\n\
|
|
4137
|
-
bit-endianness is `big`.");
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
static PyObject *
|
|
4141
|
-
set_default_endian(PyObject *module, PyObject *args)
|
|
4142
|
-
{
|
|
4143
|
-
char *endian_str;
|
|
4144
|
-
int t;
|
|
4145
|
-
|
|
4146
|
-
if (!PyArg_ParseTuple(args, "s:_set_default_endian", &endian_str))
|
|
4147
|
-
return NULL;
|
|
4148
|
-
|
|
4149
|
-
/* As endian_from_string() might return -1, we have to store its value
|
|
4150
|
-
in a temporary variable before setting default_endian. */
|
|
4151
|
-
if ((t = endian_from_string(endian_str)) < 0)
|
|
4152
|
-
return NULL;
|
|
4153
|
-
default_endian = t;
|
|
4154
|
-
|
|
4155
|
-
Py_RETURN_NONE;
|
|
4156
|
-
}
|
|
4157
|
-
|
|
4158
|
-
PyDoc_STRVAR(set_default_endian_doc,
|
|
4159
|
-
"_set_default_endian(endian, /)\n\
|
|
4160
|
-
\n\
|
|
4161
|
-
Set the default bit-endianness for new bitarray objects being created.");
|
|
4133
|
+
Return the default bit-endianness for new bitarray objects being created.");
|
|
4162
4134
|
|
|
4163
4135
|
|
|
4164
4136
|
static PyObject *
|
|
@@ -4181,6 +4153,11 @@ sysinfo(PyObject *module, PyObject *args)
|
|
|
4181
4153
|
R("PY_LITTLE_ENDIAN", PY_LITTLE_ENDIAN);
|
|
4182
4154
|
R("PY_BIG_ENDIAN", PY_BIG_ENDIAN);
|
|
4183
4155
|
R("HAVE_BUILTIN_BSWAP64", HAVE_BUILTIN_BSWAP64);
|
|
4156
|
+
#ifdef Py_GIL_DISABLED /* Python configured using --disable-gil */
|
|
4157
|
+
R("Py_GIL_DISABLED", 1);
|
|
4158
|
+
#else
|
|
4159
|
+
R("Py_GIL_DISABLED", 0);
|
|
4160
|
+
#endif
|
|
4184
4161
|
#ifdef Py_DEBUG /* Python configured using --with-pydebug */
|
|
4185
4162
|
R("Py_DEBUG", 1);
|
|
4186
4163
|
#else
|
|
@@ -4211,8 +4188,6 @@ static PyMethodDef module_functions[] = {
|
|
|
4211
4188
|
reduce_doc},
|
|
4212
4189
|
{"get_default_endian", (PyCFunction) get_default_endian, METH_NOARGS,
|
|
4213
4190
|
get_default_endian_doc},
|
|
4214
|
-
{"_set_default_endian", (PyCFunction) set_default_endian, METH_VARARGS,
|
|
4215
|
-
set_default_endian_doc},
|
|
4216
4191
|
{"_sysinfo", (PyCFunction) sysinfo, METH_VARARGS,
|
|
4217
4192
|
sysinfo_doc},
|
|
4218
4193
|
{NULL, NULL} /* sentinel */
|
|
@@ -4260,6 +4235,10 @@ PyInit__bitarray(void)
|
|
|
4260
4235
|
if ((m = PyModule_Create(&moduledef)) == NULL)
|
|
4261
4236
|
return NULL;
|
|
4262
4237
|
|
|
4238
|
+
#ifdef Py_GIL_DISABLED
|
|
4239
|
+
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
|
4240
|
+
#endif
|
|
4241
|
+
|
|
4263
4242
|
if (PyType_Ready(&Bitarray_Type) < 0)
|
|
4264
4243
|
return NULL;
|
|
4265
4244
|
Py_SET_TYPE(&Bitarray_Type, &PyType_Type);
|
|
@@ -2249,6 +2249,10 @@ PyInit__util(void)
|
|
|
2249
2249
|
if ((m = PyModule_Create(&moduledef)) == NULL)
|
|
2250
2250
|
return NULL;
|
|
2251
2251
|
|
|
2252
|
+
#ifdef Py_GIL_DISABLED
|
|
2253
|
+
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
|
2254
|
+
#endif
|
|
2255
|
+
|
|
2252
2256
|
if (PyType_Ready(&CHDI_Type) < 0)
|
|
2253
2257
|
return NULL;
|
|
2254
2258
|
Py_SET_TYPE(&CHDI_Type, &PyType_Type);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Author: Ilan Schnell
|
|
6
6
|
*/
|
|
7
|
-
#define BITARRAY_VERSION "3.
|
|
7
|
+
#define BITARRAY_VERSION "3.8.0"
|
|
8
8
|
|
|
9
9
|
#ifdef STDC_HEADERS
|
|
10
10
|
# include <stddef.h>
|
|
@@ -52,6 +52,8 @@ typedef struct {
|
|
|
52
52
|
/* --- bit-endianness --- */
|
|
53
53
|
#define ENDIAN_LITTLE 0
|
|
54
54
|
#define ENDIAN_BIG 1
|
|
55
|
+
/* default bit-endianness */
|
|
56
|
+
#define ENDIAN_DEFAULT ENDIAN_BIG
|
|
55
57
|
|
|
56
58
|
#define IS_LE(self) ((self)->endian == ENDIAN_LITTLE)
|
|
57
59
|
#define IS_BE(self) ((self)->endian == ENDIAN_BIG)
|
|
@@ -1456,6 +1456,18 @@ PyUnicodeWriter_WriteUTF8(PyUnicodeWriter *writer,
|
|
|
1456
1456
|
return res;
|
|
1457
1457
|
}
|
|
1458
1458
|
|
|
1459
|
+
static inline int
|
|
1460
|
+
PyUnicodeWriter_WriteASCII(PyUnicodeWriter *writer,
|
|
1461
|
+
const char *str, Py_ssize_t size)
|
|
1462
|
+
{
|
|
1463
|
+
if (size < 0) {
|
|
1464
|
+
size = (Py_ssize_t)strlen(str);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
return _PyUnicodeWriter_WriteASCIIString((_PyUnicodeWriter*)writer,
|
|
1468
|
+
str, size);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1459
1471
|
static inline int
|
|
1460
1472
|
PyUnicodeWriter_WriteWideChar(PyUnicodeWriter *writer,
|
|
1461
1473
|
const wchar_t *str, Py_ssize_t size)
|
|
@@ -1479,7 +1491,8 @@ PyUnicodeWriter_WriteSubstring(PyUnicodeWriter *writer, PyObject *str,
|
|
|
1479
1491
|
Py_ssize_t start, Py_ssize_t end)
|
|
1480
1492
|
{
|
|
1481
1493
|
if (!PyUnicode_Check(str)) {
|
|
1482
|
-
PyErr_Format(PyExc_TypeError, "expect str, not %
|
|
1494
|
+
PyErr_Format(PyExc_TypeError, "expect str, not %s",
|
|
1495
|
+
Py_TYPE(str)->tp_name);
|
|
1483
1496
|
return -1;
|
|
1484
1497
|
}
|
|
1485
1498
|
if (start < 0 || start > end) {
|
|
@@ -1978,7 +1991,7 @@ static inline int Py_fclose(FILE *file)
|
|
|
1978
1991
|
#endif
|
|
1979
1992
|
|
|
1980
1993
|
|
|
1981
|
-
#if
|
|
1994
|
+
#if 0x03080000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030E0000 && !defined(PYPY_VERSION)
|
|
1982
1995
|
static inline PyObject*
|
|
1983
1996
|
PyConfig_Get(const char *name)
|
|
1984
1997
|
{
|
|
@@ -2019,7 +2032,9 @@ PyConfig_Get(const char *name)
|
|
|
2019
2032
|
PYTHONCAPI_COMPAT_SPEC(module_search_paths, WSTR_LIST, "path"),
|
|
2020
2033
|
PYTHONCAPI_COMPAT_SPEC(optimization_level, UINT, _Py_NULL),
|
|
2021
2034
|
PYTHONCAPI_COMPAT_SPEC(parser_debug, BOOL, _Py_NULL),
|
|
2035
|
+
#if 0x03090000 <= PY_VERSION_HEX
|
|
2022
2036
|
PYTHONCAPI_COMPAT_SPEC(platlibdir, WSTR, "platlibdir"),
|
|
2037
|
+
#endif
|
|
2023
2038
|
PYTHONCAPI_COMPAT_SPEC(prefix, WSTR_OPT, "prefix"),
|
|
2024
2039
|
PYTHONCAPI_COMPAT_SPEC(pycache_prefix, WSTR_OPT, "pycache_prefix"),
|
|
2025
2040
|
PYTHONCAPI_COMPAT_SPEC(quiet, BOOL, _Py_NULL),
|
|
@@ -2198,6 +2213,380 @@ PyConfig_GetInt(const char *name, int *value)
|
|
|
2198
2213
|
}
|
|
2199
2214
|
#endif // PY_VERSION_HEX > 0x03090000 && !defined(PYPY_VERSION)
|
|
2200
2215
|
|
|
2216
|
+
// gh-133144 added PyUnstable_Object_IsUniquelyReferenced() to Python 3.14.0b1.
|
|
2217
|
+
// Adapted from _PyObject_IsUniquelyReferenced() implementation.
|
|
2218
|
+
#if PY_VERSION_HEX < 0x030E00B0
|
|
2219
|
+
static inline int PyUnstable_Object_IsUniquelyReferenced(PyObject *obj)
|
|
2220
|
+
{
|
|
2221
|
+
#if !defined(Py_GIL_DISABLED)
|
|
2222
|
+
return Py_REFCNT(obj) == 1;
|
|
2223
|
+
#else
|
|
2224
|
+
// NOTE: the entire ob_ref_shared field must be zero, including flags, to
|
|
2225
|
+
// ensure that other threads cannot concurrently create new references to
|
|
2226
|
+
// this object.
|
|
2227
|
+
return (_Py_IsOwnedByCurrentThread(obj) &&
|
|
2228
|
+
_Py_atomic_load_uint32_relaxed(&obj->ob_ref_local) == 1 &&
|
|
2229
|
+
_Py_atomic_load_ssize_relaxed(&obj->ob_ref_shared) == 0);
|
|
2230
|
+
#endif
|
|
2231
|
+
}
|
|
2232
|
+
#endif
|
|
2233
|
+
|
|
2234
|
+
|
|
2235
|
+
#if PY_VERSION_HEX < 0x030F0000
|
|
2236
|
+
static inline PyObject*
|
|
2237
|
+
PySys_GetAttrString(const char *name)
|
|
2238
|
+
{
|
|
2239
|
+
#if PY_VERSION_HEX >= 0x03000000
|
|
2240
|
+
PyObject *value = Py_XNewRef(PySys_GetObject(name));
|
|
2241
|
+
#else
|
|
2242
|
+
PyObject *value = Py_XNewRef(PySys_GetObject((char*)name));
|
|
2243
|
+
#endif
|
|
2244
|
+
if (value != NULL) {
|
|
2245
|
+
return value;
|
|
2246
|
+
}
|
|
2247
|
+
if (!PyErr_Occurred()) {
|
|
2248
|
+
PyErr_Format(PyExc_RuntimeError, "lost sys.%s", name);
|
|
2249
|
+
}
|
|
2250
|
+
return NULL;
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
static inline PyObject*
|
|
2254
|
+
PySys_GetAttr(PyObject *name)
|
|
2255
|
+
{
|
|
2256
|
+
#if PY_VERSION_HEX >= 0x03000000
|
|
2257
|
+
const char *name_str = PyUnicode_AsUTF8(name);
|
|
2258
|
+
#else
|
|
2259
|
+
const char *name_str = PyString_AsString(name);
|
|
2260
|
+
#endif
|
|
2261
|
+
if (name_str == NULL) {
|
|
2262
|
+
return NULL;
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
return PySys_GetAttrString(name_str);
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
static inline int
|
|
2269
|
+
PySys_GetOptionalAttrString(const char *name, PyObject **value)
|
|
2270
|
+
{
|
|
2271
|
+
#if PY_VERSION_HEX >= 0x03000000
|
|
2272
|
+
*value = Py_XNewRef(PySys_GetObject(name));
|
|
2273
|
+
#else
|
|
2274
|
+
*value = Py_XNewRef(PySys_GetObject((char*)name));
|
|
2275
|
+
#endif
|
|
2276
|
+
if (*value != NULL) {
|
|
2277
|
+
return 1;
|
|
2278
|
+
}
|
|
2279
|
+
return 0;
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
static inline int
|
|
2283
|
+
PySys_GetOptionalAttr(PyObject *name, PyObject **value)
|
|
2284
|
+
{
|
|
2285
|
+
#if PY_VERSION_HEX >= 0x03000000
|
|
2286
|
+
const char *name_str = PyUnicode_AsUTF8(name);
|
|
2287
|
+
#else
|
|
2288
|
+
const char *name_str = PyString_AsString(name);
|
|
2289
|
+
#endif
|
|
2290
|
+
if (name_str == NULL) {
|
|
2291
|
+
*value = NULL;
|
|
2292
|
+
return -1;
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
return PySys_GetOptionalAttrString(name_str, value);
|
|
2296
|
+
}
|
|
2297
|
+
#endif // PY_VERSION_HEX < 0x030F00A1
|
|
2298
|
+
|
|
2299
|
+
|
|
2300
|
+
#if PY_VERSION_HEX < 0x030F00A1
|
|
2301
|
+
typedef struct PyBytesWriter {
|
|
2302
|
+
char small_buffer[256];
|
|
2303
|
+
PyObject *obj;
|
|
2304
|
+
Py_ssize_t size;
|
|
2305
|
+
} PyBytesWriter;
|
|
2306
|
+
|
|
2307
|
+
static inline Py_ssize_t
|
|
2308
|
+
_PyBytesWriter_GetAllocated(PyBytesWriter *writer)
|
|
2309
|
+
{
|
|
2310
|
+
if (writer->obj == NULL) {
|
|
2311
|
+
return sizeof(writer->small_buffer);
|
|
2312
|
+
}
|
|
2313
|
+
else {
|
|
2314
|
+
return PyBytes_GET_SIZE(writer->obj);
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2318
|
+
|
|
2319
|
+
static inline int
|
|
2320
|
+
_PyBytesWriter_Resize_impl(PyBytesWriter *writer, Py_ssize_t size,
|
|
2321
|
+
int resize)
|
|
2322
|
+
{
|
|
2323
|
+
int overallocate = resize;
|
|
2324
|
+
assert(size >= 0);
|
|
2325
|
+
|
|
2326
|
+
if (size <= _PyBytesWriter_GetAllocated(writer)) {
|
|
2327
|
+
return 0;
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
if (overallocate) {
|
|
2331
|
+
#ifdef MS_WINDOWS
|
|
2332
|
+
/* On Windows, overallocate by 50% is the best factor */
|
|
2333
|
+
if (size <= (PY_SSIZE_T_MAX - size / 2)) {
|
|
2334
|
+
size += size / 2;
|
|
2335
|
+
}
|
|
2336
|
+
#else
|
|
2337
|
+
/* On Linux, overallocate by 25% is the best factor */
|
|
2338
|
+
if (size <= (PY_SSIZE_T_MAX - size / 4)) {
|
|
2339
|
+
size += size / 4;
|
|
2340
|
+
}
|
|
2341
|
+
#endif
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
if (writer->obj != NULL) {
|
|
2345
|
+
if (_PyBytes_Resize(&writer->obj, size)) {
|
|
2346
|
+
return -1;
|
|
2347
|
+
}
|
|
2348
|
+
assert(writer->obj != NULL);
|
|
2349
|
+
}
|
|
2350
|
+
else {
|
|
2351
|
+
writer->obj = PyBytes_FromStringAndSize(NULL, size);
|
|
2352
|
+
if (writer->obj == NULL) {
|
|
2353
|
+
return -1;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
if (resize) {
|
|
2357
|
+
assert((size_t)size > sizeof(writer->small_buffer));
|
|
2358
|
+
memcpy(PyBytes_AS_STRING(writer->obj),
|
|
2359
|
+
writer->small_buffer,
|
|
2360
|
+
sizeof(writer->small_buffer));
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
return 0;
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
static inline void*
|
|
2367
|
+
PyBytesWriter_GetData(PyBytesWriter *writer)
|
|
2368
|
+
{
|
|
2369
|
+
if (writer->obj == NULL) {
|
|
2370
|
+
return writer->small_buffer;
|
|
2371
|
+
}
|
|
2372
|
+
else {
|
|
2373
|
+
return PyBytes_AS_STRING(writer->obj);
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
static inline Py_ssize_t
|
|
2378
|
+
PyBytesWriter_GetSize(PyBytesWriter *writer)
|
|
2379
|
+
{
|
|
2380
|
+
return writer->size;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
static inline void
|
|
2384
|
+
PyBytesWriter_Discard(PyBytesWriter *writer)
|
|
2385
|
+
{
|
|
2386
|
+
if (writer == NULL) {
|
|
2387
|
+
return;
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
Py_XDECREF(writer->obj);
|
|
2391
|
+
PyMem_Free(writer);
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
static inline PyBytesWriter*
|
|
2395
|
+
PyBytesWriter_Create(Py_ssize_t size)
|
|
2396
|
+
{
|
|
2397
|
+
if (size < 0) {
|
|
2398
|
+
PyErr_SetString(PyExc_ValueError, "size must be >= 0");
|
|
2399
|
+
return NULL;
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
PyBytesWriter *writer = (PyBytesWriter*)PyMem_Malloc(sizeof(PyBytesWriter));
|
|
2403
|
+
if (writer == NULL) {
|
|
2404
|
+
PyErr_NoMemory();
|
|
2405
|
+
return NULL;
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
writer->obj = NULL;
|
|
2409
|
+
writer->size = 0;
|
|
2410
|
+
|
|
2411
|
+
if (size >= 1) {
|
|
2412
|
+
if (_PyBytesWriter_Resize_impl(writer, size, 0) < 0) {
|
|
2413
|
+
PyBytesWriter_Discard(writer);
|
|
2414
|
+
return NULL;
|
|
2415
|
+
}
|
|
2416
|
+
writer->size = size;
|
|
2417
|
+
}
|
|
2418
|
+
return writer;
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
static inline PyObject*
|
|
2422
|
+
PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
|
|
2423
|
+
{
|
|
2424
|
+
PyObject *result;
|
|
2425
|
+
if (size == 0) {
|
|
2426
|
+
result = PyBytes_FromStringAndSize("", 0);
|
|
2427
|
+
}
|
|
2428
|
+
else if (writer->obj != NULL) {
|
|
2429
|
+
if (size != PyBytes_GET_SIZE(writer->obj)) {
|
|
2430
|
+
if (_PyBytes_Resize(&writer->obj, size)) {
|
|
2431
|
+
goto error;
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
result = writer->obj;
|
|
2435
|
+
writer->obj = NULL;
|
|
2436
|
+
}
|
|
2437
|
+
else {
|
|
2438
|
+
result = PyBytes_FromStringAndSize(writer->small_buffer, size);
|
|
2439
|
+
}
|
|
2440
|
+
PyBytesWriter_Discard(writer);
|
|
2441
|
+
return result;
|
|
2442
|
+
|
|
2443
|
+
error:
|
|
2444
|
+
PyBytesWriter_Discard(writer);
|
|
2445
|
+
return NULL;
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
static inline PyObject*
|
|
2449
|
+
PyBytesWriter_Finish(PyBytesWriter *writer)
|
|
2450
|
+
{
|
|
2451
|
+
return PyBytesWriter_FinishWithSize(writer, writer->size);
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
static inline PyObject*
|
|
2455
|
+
PyBytesWriter_FinishWithPointer(PyBytesWriter *writer, void *buf)
|
|
2456
|
+
{
|
|
2457
|
+
Py_ssize_t size = (char*)buf - (char*)PyBytesWriter_GetData(writer);
|
|
2458
|
+
if (size < 0 || size > _PyBytesWriter_GetAllocated(writer)) {
|
|
2459
|
+
PyBytesWriter_Discard(writer);
|
|
2460
|
+
PyErr_SetString(PyExc_ValueError, "invalid end pointer");
|
|
2461
|
+
return NULL;
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
return PyBytesWriter_FinishWithSize(writer, size);
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
static inline int
|
|
2468
|
+
PyBytesWriter_Resize(PyBytesWriter *writer, Py_ssize_t size)
|
|
2469
|
+
{
|
|
2470
|
+
if (size < 0) {
|
|
2471
|
+
PyErr_SetString(PyExc_ValueError, "size must be >= 0");
|
|
2472
|
+
return -1;
|
|
2473
|
+
}
|
|
2474
|
+
if (_PyBytesWriter_Resize_impl(writer, size, 1) < 0) {
|
|
2475
|
+
return -1;
|
|
2476
|
+
}
|
|
2477
|
+
writer->size = size;
|
|
2478
|
+
return 0;
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
static inline int
|
|
2482
|
+
PyBytesWriter_Grow(PyBytesWriter *writer, Py_ssize_t size)
|
|
2483
|
+
{
|
|
2484
|
+
if (size < 0 && writer->size + size < 0) {
|
|
2485
|
+
PyErr_SetString(PyExc_ValueError, "invalid size");
|
|
2486
|
+
return -1;
|
|
2487
|
+
}
|
|
2488
|
+
if (size > PY_SSIZE_T_MAX - writer->size) {
|
|
2489
|
+
PyErr_NoMemory();
|
|
2490
|
+
return -1;
|
|
2491
|
+
}
|
|
2492
|
+
size = writer->size + size;
|
|
2493
|
+
|
|
2494
|
+
if (_PyBytesWriter_Resize_impl(writer, size, 1) < 0) {
|
|
2495
|
+
return -1;
|
|
2496
|
+
}
|
|
2497
|
+
writer->size = size;
|
|
2498
|
+
return 0;
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
static inline void*
|
|
2502
|
+
PyBytesWriter_GrowAndUpdatePointer(PyBytesWriter *writer,
|
|
2503
|
+
Py_ssize_t size, void *buf)
|
|
2504
|
+
{
|
|
2505
|
+
Py_ssize_t pos = (char*)buf - (char*)PyBytesWriter_GetData(writer);
|
|
2506
|
+
if (PyBytesWriter_Grow(writer, size) < 0) {
|
|
2507
|
+
return NULL;
|
|
2508
|
+
}
|
|
2509
|
+
return (char*)PyBytesWriter_GetData(writer) + pos;
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
static inline int
|
|
2513
|
+
PyBytesWriter_WriteBytes(PyBytesWriter *writer,
|
|
2514
|
+
const void *bytes, Py_ssize_t size)
|
|
2515
|
+
{
|
|
2516
|
+
if (size < 0) {
|
|
2517
|
+
size_t len = strlen((const char*)bytes);
|
|
2518
|
+
if (len > (size_t)PY_SSIZE_T_MAX) {
|
|
2519
|
+
PyErr_NoMemory();
|
|
2520
|
+
return -1;
|
|
2521
|
+
}
|
|
2522
|
+
size = (Py_ssize_t)len;
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
Py_ssize_t pos = writer->size;
|
|
2526
|
+
if (PyBytesWriter_Grow(writer, size) < 0) {
|
|
2527
|
+
return -1;
|
|
2528
|
+
}
|
|
2529
|
+
char *buf = (char*)PyBytesWriter_GetData(writer);
|
|
2530
|
+
memcpy(buf + pos, bytes, (size_t)size);
|
|
2531
|
+
return 0;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
static inline int
|
|
2535
|
+
PyBytesWriter_Format(PyBytesWriter *writer, const char *format, ...)
|
|
2536
|
+
Py_GCC_ATTRIBUTE((format(printf, 2, 3)));
|
|
2537
|
+
|
|
2538
|
+
static inline int
|
|
2539
|
+
PyBytesWriter_Format(PyBytesWriter *writer, const char *format, ...)
|
|
2540
|
+
{
|
|
2541
|
+
va_list vargs;
|
|
2542
|
+
va_start(vargs, format);
|
|
2543
|
+
PyObject *str = PyBytes_FromFormatV(format, vargs);
|
|
2544
|
+
va_end(vargs);
|
|
2545
|
+
|
|
2546
|
+
if (str == NULL) {
|
|
2547
|
+
return -1;
|
|
2548
|
+
}
|
|
2549
|
+
int res = PyBytesWriter_WriteBytes(writer,
|
|
2550
|
+
PyBytes_AS_STRING(str),
|
|
2551
|
+
PyBytes_GET_SIZE(str));
|
|
2552
|
+
Py_DECREF(str);
|
|
2553
|
+
return res;
|
|
2554
|
+
}
|
|
2555
|
+
#endif // PY_VERSION_HEX < 0x030F00A1
|
|
2556
|
+
|
|
2557
|
+
|
|
2558
|
+
#if PY_VERSION_HEX < 0x030F00A1
|
|
2559
|
+
static inline PyObject*
|
|
2560
|
+
PyTuple_FromArray(PyObject *const *array, Py_ssize_t size)
|
|
2561
|
+
{
|
|
2562
|
+
PyObject *tuple = PyTuple_New(size);
|
|
2563
|
+
if (tuple == NULL) {
|
|
2564
|
+
return NULL;
|
|
2565
|
+
}
|
|
2566
|
+
for (Py_ssize_t i=0; i < size; i++) {
|
|
2567
|
+
PyObject *item = array[i];
|
|
2568
|
+
PyTuple_SET_ITEM(tuple, i, Py_NewRef(item));
|
|
2569
|
+
}
|
|
2570
|
+
return tuple;
|
|
2571
|
+
}
|
|
2572
|
+
#endif
|
|
2573
|
+
|
|
2574
|
+
|
|
2575
|
+
#if PY_VERSION_HEX < 0x030F00A1
|
|
2576
|
+
static inline Py_hash_t
|
|
2577
|
+
PyUnstable_Unicode_GET_CACHED_HASH(PyObject *op)
|
|
2578
|
+
{
|
|
2579
|
+
#ifdef PYPY_VERSION
|
|
2580
|
+
(void)op; // unused argument
|
|
2581
|
+
return -1;
|
|
2582
|
+
#elif PY_VERSION_HEX >= 0x03000000
|
|
2583
|
+
return ((PyASCIIObject*)op)->hash;
|
|
2584
|
+
#else
|
|
2585
|
+
return ((PyUnicodeObject*)op)->hash;
|
|
2586
|
+
#endif
|
|
2587
|
+
}
|
|
2588
|
+
#endif
|
|
2589
|
+
|
|
2201
2590
|
|
|
2202
2591
|
#ifdef __cplusplus
|
|
2203
2592
|
}
|
|
@@ -33,7 +33,7 @@ is_pypy = bool(platform.python_implementation() == 'PyPy')
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
from bitarray import (bitarray, frozenbitarray, bits2bytes, decodetree,
|
|
36
|
-
get_default_endian,
|
|
36
|
+
get_default_endian,
|
|
37
37
|
_bitarray_reconstructor, _sysinfo as sysinfo,
|
|
38
38
|
BufferInfo, __version__)
|
|
39
39
|
|
|
@@ -152,11 +152,20 @@ class ModuleFunctionsTests(unittest.TestCase):
|
|
|
152
152
|
|
|
153
153
|
def test_sysinfo(self):
|
|
154
154
|
for key in ["void*", "size_t", "bitarrayobject", "decodetreeobject",
|
|
155
|
-
"binode", "HAVE_BUILTIN_BSWAP64",
|
|
156
|
-
"
|
|
155
|
+
"binode", "HAVE_BUILTIN_BSWAP64",
|
|
156
|
+
"PY_LITTLE_ENDIAN", "PY_BIG_ENDIAN",
|
|
157
|
+
"Py_GIL_DISABLED", "Py_DEBUG", "DEBUG"]:
|
|
157
158
|
res = sysinfo(key)
|
|
158
159
|
self.assertEqual(type(res), int)
|
|
159
160
|
|
|
161
|
+
@skipIf(sys.version_info[:2] < (3, 14))
|
|
162
|
+
def test_gil_disabled(self):
|
|
163
|
+
self.assertEqual(sysinfo("Py_GIL_DISABLED"),
|
|
164
|
+
"free-threading" in sys.version)
|
|
165
|
+
# see if GIL is actually disabled in free-threading build
|
|
166
|
+
if sysinfo("Py_GIL_DISABLED"):
|
|
167
|
+
self.assertFalse(sys._is_gil_enabled())
|
|
168
|
+
|
|
160
169
|
def test_sysinfo_errors(self):
|
|
161
170
|
self.assertRaises(TypeError, sysinfo)
|
|
162
171
|
self.assertRaises(TypeError, sysinfo, b"void*")
|
|
@@ -175,36 +184,12 @@ class ModuleFunctionsTests(unittest.TestCase):
|
|
|
175
184
|
self.assertEqual(sys.byteorder == "big",
|
|
176
185
|
sysinfo("PY_BIG_ENDIAN"))
|
|
177
186
|
|
|
178
|
-
def test_set_default_endian(self):
|
|
179
|
-
for default_endian in 'big', 'little':
|
|
180
|
-
_set_default_endian(default_endian)
|
|
181
|
-
a = bitarray()
|
|
182
|
-
self.assertEqual(a.endian, default_endian)
|
|
183
|
-
for x in None, 0, 64, '10111', [1, 0]:
|
|
184
|
-
a = bitarray(x)
|
|
185
|
-
self.assertEqual(a.endian, default_endian)
|
|
186
|
-
|
|
187
|
-
for endian in 'big', 'little', None:
|
|
188
|
-
a = bitarray(endian=endian)
|
|
189
|
-
self.assertEqual(a.endian,
|
|
190
|
-
default_endian if endian is None else endian)
|
|
191
|
-
|
|
192
|
-
# make sure that wrong calling _set_default_endian() does not
|
|
193
|
-
# change the default endianness
|
|
194
|
-
self.assertRaises(ValueError, _set_default_endian, 'foobar')
|
|
195
|
-
self.assertEqual(bitarray().endian, default_endian)
|
|
196
|
-
|
|
197
|
-
def test_set_default_endian_errors(self):
|
|
198
|
-
self.assertRaises(TypeError, _set_default_endian, 0)
|
|
199
|
-
self.assertRaises(TypeError, _set_default_endian, 'little', 0)
|
|
200
|
-
self.assertRaises(ValueError, _set_default_endian, 'foo')
|
|
201
|
-
|
|
202
187
|
def test_get_default_endian(self):
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
188
|
+
endian = get_default_endian()
|
|
189
|
+
self.assertTrue(endian in ('little', 'big'))
|
|
190
|
+
self.assertEqual(type(endian), str)
|
|
191
|
+
a = bitarray()
|
|
192
|
+
self.assertEqual(a.endian, endian)
|
|
208
193
|
|
|
209
194
|
def test_get_default_endian_errors(self):
|
|
210
195
|
# takes no arguments
|
|
@@ -257,16 +242,6 @@ class CreateObjectTests(unittest.TestCase, Util):
|
|
|
257
242
|
self.assertNotEqual(a, b)
|
|
258
243
|
self.assertEqual(a.tobytes(), b.tobytes())
|
|
259
244
|
|
|
260
|
-
def test_endian_default(self):
|
|
261
|
-
_set_default_endian('big')
|
|
262
|
-
a_big = bitarray()
|
|
263
|
-
_set_default_endian('little')
|
|
264
|
-
a_little = bitarray()
|
|
265
|
-
_set_default_endian('big')
|
|
266
|
-
|
|
267
|
-
self.assertEqual(a_big.endian, 'big')
|
|
268
|
-
self.assertEqual(a_little.endian, 'little')
|
|
269
|
-
|
|
270
245
|
def test_endian_wrong(self):
|
|
271
246
|
self.assertRaises(TypeError, bitarray, endian=0)
|
|
272
247
|
self.assertRaises(ValueError, bitarray, endian='')
|
|
@@ -283,10 +258,9 @@ class CreateObjectTests(unittest.TestCase, Util):
|
|
|
283
258
|
a = bitarray(buffer=b'', endian=endian)
|
|
284
259
|
self.assertEQUAL(a, bitarray(0, endian))
|
|
285
260
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
self.assertEqual(len(a), 8)
|
|
261
|
+
a = bitarray(buffer=b'A')
|
|
262
|
+
self.assertEqual(a.endian, "big")
|
|
263
|
+
self.assertEqual(len(a), 8)
|
|
290
264
|
|
|
291
265
|
def test_buffer_readonly(self):
|
|
292
266
|
a = bitarray(buffer=b'\xf0', endian='little')
|
|
@@ -538,6 +512,13 @@ class ToObjectsTests(unittest.TestCase, Util):
|
|
|
538
512
|
self.assertEqual(bytes(a), a.tobytes())
|
|
539
513
|
self.assertEqual(bytearray(a), a.tobytes())
|
|
540
514
|
|
|
515
|
+
def test_bytes_bytearray_pad(self):
|
|
516
|
+
for endian, res in ("little", b"\x01"), ("big", b"\x80"):
|
|
517
|
+
a = bitarray("1", endian)
|
|
518
|
+
self.assertEqual(a.tobytes(), res)
|
|
519
|
+
a = bitarray("1", endian)
|
|
520
|
+
self.assertEqual(bytes(a), res)
|
|
521
|
+
|
|
541
522
|
def test_set(self):
|
|
542
523
|
for a in self.randombitarrays():
|
|
543
524
|
self.assertEqual(set(a), set(a.tolist()))
|
|
@@ -2423,7 +2404,6 @@ class NumberTests(unittest.TestCase, Util):
|
|
|
2423
2404
|
|
|
2424
2405
|
@skipIf(is_pypy)
|
|
2425
2406
|
def test_imported(self):
|
|
2426
|
-
_set_default_endian("big")
|
|
2427
2407
|
a = bytearray([0xf0, 0x01, 0x02, 0x0f])
|
|
2428
2408
|
b = bitarray(buffer=a)
|
|
2429
2409
|
self.assertFalse(b.readonly)
|
|
@@ -2937,20 +2917,18 @@ class SortTests(unittest.TestCase, Util):
|
|
|
2937
2917
|
class PackTests(unittest.TestCase, Util):
|
|
2938
2918
|
|
|
2939
2919
|
def test_pack_simple(self):
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
self.assertEQUAL(a, bitarray('01101 1011'))
|
|
2953
|
-
self.check_obj(a)
|
|
2920
|
+
a = bitarray()
|
|
2921
|
+
a.pack(bytes())
|
|
2922
|
+
self.assertEQUAL(a, bitarray())
|
|
2923
|
+
a.pack(b'\x00')
|
|
2924
|
+
self.assertEQUAL(a, bitarray('0'))
|
|
2925
|
+
a.pack(b'\xff')
|
|
2926
|
+
self.assertEQUAL(a, bitarray('01'))
|
|
2927
|
+
a.pack(b'\x01\x00\x7a')
|
|
2928
|
+
self.assertEQUAL(a, bitarray('01101'))
|
|
2929
|
+
a.pack(bytearray([0x01, 0x00, 0xff, 0xa7]))
|
|
2930
|
+
self.assertEQUAL(a, bitarray('01101 1011'))
|
|
2931
|
+
self.check_obj(a)
|
|
2954
2932
|
|
|
2955
2933
|
def test_pack_types(self):
|
|
2956
2934
|
a = bitarray()
|
|
@@ -5174,17 +5152,19 @@ class FrozenbitarrayTests(unittest.TestCase, Util):
|
|
|
5174
5152
|
def run(verbosity=1):
|
|
5175
5153
|
import bitarray.test_util
|
|
5176
5154
|
|
|
5177
|
-
default_endian = get_default_endian()
|
|
5178
5155
|
print('bitarray is installed in: %s' % os.path.dirname(__file__))
|
|
5179
5156
|
print('bitarray version: %s' % __version__)
|
|
5180
5157
|
print('sys.version: %s' % sys.version)
|
|
5181
5158
|
print('sys.prefix: %s' % sys.prefix)
|
|
5159
|
+
if sys.version_info[:2] >= (3, 14):
|
|
5160
|
+
print('sys._is_gil_enabled(): %s' % sys._is_gil_enabled())
|
|
5182
5161
|
print('pointer size: %d bit' % (8 * PTRSIZE))
|
|
5183
5162
|
print('sizeof(size_t): %d' % sysinfo("size_t"));
|
|
5184
5163
|
print('sizeof(bitarrayobject): %d' % sysinfo("bitarrayobject"))
|
|
5185
5164
|
print('HAVE_BUILTIN_BSWAP64: %d' % sysinfo("HAVE_BUILTIN_BSWAP64"))
|
|
5186
|
-
print('default bit-endianness: %s' %
|
|
5165
|
+
print('default bit-endianness: %s' % get_default_endian())
|
|
5187
5166
|
print('machine byte-order: %s' % sys.byteorder)
|
|
5167
|
+
print('Py_GIL_DISABLED: %s' % sysinfo("Py_GIL_DISABLED"))
|
|
5188
5168
|
print('Py_DEBUG: %s' % sysinfo("Py_DEBUG"))
|
|
5189
5169
|
print('DEBUG: %s' % sysinfo("DEBUG"))
|
|
5190
5170
|
loader = unittest.TestLoader()
|
|
@@ -5194,7 +5174,6 @@ def run(verbosity=1):
|
|
|
5194
5174
|
|
|
5195
5175
|
runner = unittest.TextTestRunner(verbosity=verbosity)
|
|
5196
5176
|
result = runner.run(suite)
|
|
5197
|
-
_set_default_endian(default_endian)
|
|
5198
5177
|
return result
|
|
5199
5178
|
|
|
5200
5179
|
if __name__ == '__main__':
|
|
@@ -24,7 +24,7 @@ from string import hexdigits, whitespace
|
|
|
24
24
|
from collections import Counter
|
|
25
25
|
|
|
26
26
|
from bitarray import (bitarray, frozenbitarray, decodetree, bits2bytes,
|
|
27
|
-
|
|
27
|
+
get_default_endian)
|
|
28
28
|
from bitarray.test_bitarray import Util, skipIf, is_pypy, urandom_2, PTRSIZE
|
|
29
29
|
|
|
30
30
|
from bitarray.util import (
|
|
@@ -46,12 +46,10 @@ class ZerosOnesTests(unittest.TestCase):
|
|
|
46
46
|
|
|
47
47
|
def test_basic(self):
|
|
48
48
|
for _ in range(50):
|
|
49
|
-
default_endian = choice(['little', 'big'])
|
|
50
|
-
_set_default_endian(default_endian)
|
|
51
49
|
a = choice([zeros(0), zeros(0, None), zeros(0, endian=None),
|
|
52
50
|
ones(0), ones(0, None), ones(0, endian=None)])
|
|
53
51
|
self.assertEqual(a, bitarray())
|
|
54
|
-
self.assertEqual(a.endian,
|
|
52
|
+
self.assertEqual(a.endian, get_default_endian())
|
|
55
53
|
self.assertEqual(type(a), bitarray)
|
|
56
54
|
|
|
57
55
|
endian = choice(['little', 'big', None])
|
|
@@ -59,11 +57,11 @@ class ZerosOnesTests(unittest.TestCase):
|
|
|
59
57
|
|
|
60
58
|
a = choice([zeros(n, endian), zeros(n, endian=endian)])
|
|
61
59
|
self.assertEqual(a.to01(), n * "0")
|
|
62
|
-
self.assertEqual(a.endian, endian or
|
|
60
|
+
self.assertEqual(a.endian, endian or get_default_endian())
|
|
63
61
|
|
|
64
62
|
b = choice([ones(n, endian), ones(n, endian=endian)])
|
|
65
63
|
self.assertEqual(b.to01(), n * "1")
|
|
66
|
-
self.assertEqual(b.endian, endian or
|
|
64
|
+
self.assertEqual(b.endian, endian or get_default_endian())
|
|
67
65
|
|
|
68
66
|
def test_errors(self):
|
|
69
67
|
for f in zeros, ones:
|
|
@@ -86,18 +84,16 @@ class URandomTests(unittest.TestCase):
|
|
|
86
84
|
|
|
87
85
|
def test_basic(self):
|
|
88
86
|
for _ in range(20):
|
|
89
|
-
default_endian = choice(['little', 'big'])
|
|
90
|
-
_set_default_endian(default_endian)
|
|
91
87
|
a = choice([urandom(0), urandom(0, endian=None)])
|
|
92
88
|
self.assertEqual(a, bitarray())
|
|
93
|
-
self.assertEqual(a.endian,
|
|
89
|
+
self.assertEqual(a.endian, get_default_endian())
|
|
94
90
|
|
|
95
91
|
endian = choice(['little', 'big', None])
|
|
96
92
|
n = randrange(100)
|
|
97
93
|
|
|
98
94
|
a = choice([urandom(n, endian), urandom(n, endian=endian)])
|
|
99
95
|
self.assertEqual(len(a), n)
|
|
100
|
-
self.assertEqual(a.endian, endian or
|
|
96
|
+
self.assertEqual(a.endian, endian or get_default_endian())
|
|
101
97
|
self.assertEqual(type(a), bitarray)
|
|
102
98
|
|
|
103
99
|
def test_errors(self):
|
|
@@ -122,8 +118,6 @@ class Random_K_Tests(unittest.TestCase):
|
|
|
122
118
|
|
|
123
119
|
def test_basic(self):
|
|
124
120
|
for _ in range(250):
|
|
125
|
-
default_endian = choice(['little', 'big'])
|
|
126
|
-
_set_default_endian(default_endian)
|
|
127
121
|
endian = choice(['little', 'big', None])
|
|
128
122
|
n = randrange(120)
|
|
129
123
|
k = randint(0, n)
|
|
@@ -131,7 +125,7 @@ class Random_K_Tests(unittest.TestCase):
|
|
|
131
125
|
self.assertTrue(type(a), bitarray)
|
|
132
126
|
self.assertEqual(len(a), n)
|
|
133
127
|
self.assertEqual(a.count(), k)
|
|
134
|
-
self.assertEqual(a.endian, endian or
|
|
128
|
+
self.assertEqual(a.endian, endian or get_default_endian())
|
|
135
129
|
|
|
136
130
|
def test_inputs_and_edge_cases(self):
|
|
137
131
|
R = random_k
|
|
@@ -210,7 +204,6 @@ class Random_K_Tests(unittest.TestCase):
|
|
|
210
204
|
# We ensure that after setting a seed value, random_k() will
|
|
211
205
|
# always return the same random bitarrays. However, we do not ensure
|
|
212
206
|
# that these results will not change in future versions of bitarray.
|
|
213
|
-
_set_default_endian("little")
|
|
214
207
|
a = []
|
|
215
208
|
for val in 654321, 654322, 654321, 654322:
|
|
216
209
|
seed(val)
|
|
@@ -289,15 +282,13 @@ class Random_P_Tests(unittest.TestCase):
|
|
|
289
282
|
|
|
290
283
|
def test_basic(self):
|
|
291
284
|
for _ in range(250):
|
|
292
|
-
default_endian = choice(['little', 'big'])
|
|
293
|
-
_set_default_endian(default_endian)
|
|
294
285
|
endian = choice(['little', 'big', None])
|
|
295
286
|
n = randrange(120)
|
|
296
287
|
p = choice([0.0, 0.0001, 0.2, 0.5, 0.9, 1.0])
|
|
297
288
|
a = random_p(n, p, endian)
|
|
298
289
|
self.assertTrue(type(a), bitarray)
|
|
299
290
|
self.assertEqual(len(a), n)
|
|
300
|
-
self.assertEqual(a.endian, endian or
|
|
291
|
+
self.assertEqual(a.endian, endian or get_default_endian())
|
|
301
292
|
|
|
302
293
|
def test_inputs_and_edge_cases(self):
|
|
303
294
|
R = random_p
|
|
@@ -347,7 +338,6 @@ class Random_P_Tests(unittest.TestCase):
|
|
|
347
338
|
# We ensure that after setting a seed value, random_p() will always
|
|
348
339
|
# return the same random bitarrays. However, we do not ensure that
|
|
349
340
|
# these results will not change in future versions of bitarray.
|
|
350
|
-
_set_default_endian("little")
|
|
351
341
|
a = []
|
|
352
342
|
for val in 123456, 123457, 123456, 123457:
|
|
353
343
|
seed(val)
|
|
@@ -391,13 +381,11 @@ class PrimeTests(unittest.TestCase):
|
|
|
391
381
|
|
|
392
382
|
def test_explitcit(self):
|
|
393
383
|
for n in range(230):
|
|
394
|
-
default_endian = choice(['little', 'big'])
|
|
395
|
-
_set_default_endian(default_endian)
|
|
396
384
|
endian = choice(["little", "big", None])
|
|
397
385
|
odd = getrandbits(1)
|
|
398
386
|
a = gen_primes(n, endian, odd)
|
|
399
387
|
self.assertEqual(len(a), n)
|
|
400
|
-
self.assertEqual(a.endian, endian or
|
|
388
|
+
self.assertEqual(a.endian, endian or get_default_endian())
|
|
401
389
|
if odd:
|
|
402
390
|
lst = [2] + [2 * i + 1 for i in a.search(1)]
|
|
403
391
|
else:
|
|
@@ -530,16 +518,15 @@ class StripTests(unittest.TestCase, Util):
|
|
|
530
518
|
self.assertRaises(TypeError, strip, '0110')
|
|
531
519
|
self.assertRaises(TypeError, strip, bitarray(), 123)
|
|
532
520
|
self.assertRaises(ValueError, strip, bitarray(), 'up')
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
self.assertEqual(type(c), frozenbitarray)
|
|
521
|
+
|
|
522
|
+
a = bitarray('00010110000')
|
|
523
|
+
self.assertEQUAL(strip(a), bitarray('0001011'))
|
|
524
|
+
self.assertEQUAL(strip(a, 'left'), bitarray('10110000'))
|
|
525
|
+
self.assertEQUAL(strip(a, 'both'), bitarray('1011'))
|
|
526
|
+
b = frozenbitarray('00010110000')
|
|
527
|
+
c = strip(b, 'both')
|
|
528
|
+
self.assertEqual(c, bitarray('1011'))
|
|
529
|
+
self.assertEqual(type(c), frozenbitarray)
|
|
543
530
|
|
|
544
531
|
def test_zeros_ones(self):
|
|
545
532
|
for _ in range(50):
|
|
@@ -1412,7 +1399,6 @@ class HexlifyTests(unittest.TestCase, Util):
|
|
|
1412
1399
|
self.assertRaises(ValueError, ba2hex, a, 2, " \0")
|
|
1413
1400
|
|
|
1414
1401
|
def test_hex2ba_whitespace(self):
|
|
1415
|
-
_set_default_endian('big')
|
|
1416
1402
|
self.assertEqual(hex2ba("F1 FA %s f3 c0" % whitespace),
|
|
1417
1403
|
bitarray("11110001 11111010 11110011 11000000"))
|
|
1418
1404
|
self.assertEQUAL(hex2ba(b' a F ', 'big'),
|
|
@@ -1441,13 +1427,11 @@ class HexlifyTests(unittest.TestCase, Util):
|
|
|
1441
1427
|
|
|
1442
1428
|
def test_random(self):
|
|
1443
1429
|
for _ in range(100):
|
|
1444
|
-
default_endian = self.random_endian()
|
|
1445
|
-
_set_default_endian(default_endian)
|
|
1446
1430
|
endian = choice(["little", "big", None])
|
|
1447
1431
|
a = urandom_2(4 * randrange(100), endian)
|
|
1448
1432
|
s = ba2hex(a, group=randrange(10), sep=choice(whitespace))
|
|
1449
1433
|
b = hex2ba(s, endian)
|
|
1450
|
-
self.assertEqual(b.endian, endian or
|
|
1434
|
+
self.assertEqual(b.endian, endian or get_default_endian())
|
|
1451
1435
|
self.assertEqual(a, b)
|
|
1452
1436
|
self.check_obj(b)
|
|
1453
1437
|
|
|
@@ -1978,14 +1962,11 @@ class VLFTests(unittest.TestCase, Util):
|
|
|
1978
1962
|
(b'\xb5\xa7\x18', '0101 0100111 0011'),
|
|
1979
1963
|
(b'\x95\xb7\x1c', '0101 0110111 001110'),
|
|
1980
1964
|
]:
|
|
1981
|
-
default_endian = self.random_endian()
|
|
1982
|
-
_set_default_endian(default_endian)
|
|
1983
|
-
|
|
1984
1965
|
a = bitarray(s)
|
|
1985
1966
|
self.assertEqual(vl_encode(a), blob)
|
|
1986
1967
|
c = vl_decode(blob)
|
|
1987
1968
|
self.assertEqual(c, a)
|
|
1988
|
-
self.assertEqual(c.endian,
|
|
1969
|
+
self.assertEqual(c.endian, get_default_endian())
|
|
1989
1970
|
|
|
1990
1971
|
for endian in 'big', 'little', None:
|
|
1991
1972
|
a = bitarray(s, endian)
|
|
@@ -1995,7 +1976,7 @@ class VLFTests(unittest.TestCase, Util):
|
|
|
1995
1976
|
|
|
1996
1977
|
c = vl_decode(blob, endian)
|
|
1997
1978
|
self.assertEqual(c, a)
|
|
1998
|
-
self.assertEqual(c.endian, endian or
|
|
1979
|
+
self.assertEqual(c.endian, endian or get_default_endian())
|
|
1999
1980
|
|
|
2000
1981
|
def test_encode_types(self):
|
|
2001
1982
|
s = "0011 01"
|
|
@@ -2264,7 +2245,6 @@ class IntegerizationTests(unittest.TestCase, Util):
|
|
|
2264
2245
|
bitarray(n * '1'))
|
|
2265
2246
|
|
|
2266
2247
|
def test_explicit(self):
|
|
2267
|
-
_set_default_endian('big')
|
|
2268
2248
|
for i, sa in [( 0, '0'), (1, '1'),
|
|
2269
2249
|
( 2, '10'), (3, '11'),
|
|
2270
2250
|
(25, '11001'), (265, '100001001'),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bitarray
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.8.0
|
|
4
4
|
Summary: efficient arrays of booleans -- C extension
|
|
5
5
|
Home-page: https://github.com/ilanschnell/bitarray
|
|
6
6
|
Author: Ilan Schnell
|
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Programming Language :: Python :: Free Threading :: 1 - Unstable
|
|
23
24
|
Classifier: Topic :: Utilities
|
|
24
25
|
License-File: LICENSE
|
|
25
26
|
Dynamic: author
|
|
@@ -90,7 +91,7 @@ Once you have installed the package, you may want to test it:
|
|
|
90
91
|
|
|
91
92
|
$ python -c 'import bitarray; bitarray.test()'
|
|
92
93
|
bitarray is installed in: /Users/ilan/bitarray/bitarray
|
|
93
|
-
bitarray version: 3.
|
|
94
|
+
bitarray version: 3.8.0
|
|
94
95
|
sys.version: 3.13.5 (main, Jun 16 2025) [Clang 18.1.8]
|
|
95
96
|
sys.prefix: /Users/ilan/miniforge
|
|
96
97
|
pointer size: 64 bit
|
|
@@ -99,13 +100,14 @@ Once you have installed the package, you may want to test it:
|
|
|
99
100
|
HAVE_BUILTIN_BSWAP64: 1
|
|
100
101
|
default bit-endianness: big
|
|
101
102
|
machine byte-order: little
|
|
103
|
+
Py_GIL_DISABLED: 0
|
|
102
104
|
Py_DEBUG: 0
|
|
103
105
|
DEBUG: 0
|
|
104
106
|
.........................................................................
|
|
105
107
|
.........................................................................
|
|
106
108
|
................................................................
|
|
107
109
|
----------------------------------------------------------------------
|
|
108
|
-
Ran
|
|
110
|
+
Ran 595 tests in 0.165s
|
|
109
111
|
|
|
110
112
|
OK
|
|
111
113
|
|
|
@@ -352,7 +354,7 @@ and can therefore be used as a dictionary key:
|
|
|
352
354
|
Reference
|
|
353
355
|
=========
|
|
354
356
|
|
|
355
|
-
bitarray version: 3.
|
|
357
|
+
bitarray version: 3.8.0 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
|
|
356
358
|
|
|
357
359
|
In the following, ``item`` and ``value`` are usually a single bit -
|
|
358
360
|
an integer 0 or 1.
|
|
@@ -588,6 +590,7 @@ bitarray methods:
|
|
|
588
590
|
|
|
589
591
|
``tobytes()`` -> bytes
|
|
590
592
|
Return the bitarray buffer (pad bits are set to zero).
|
|
593
|
+
``a.tobytes()`` is equivalent to ``bytes(a)``
|
|
591
594
|
|
|
592
595
|
|
|
593
596
|
``tofile(f, /)``
|
|
@@ -658,8 +661,6 @@ Functions defined in the `bitarray` module:
|
|
|
658
661
|
|
|
659
662
|
``get_default_endian()`` -> str
|
|
660
663
|
Return the default bit-endianness for new bitarray objects being created.
|
|
661
|
-
Unless ``_set_default_endian('little')`` was called, the default
|
|
662
|
-
bit-endianness is ``big``.
|
|
663
664
|
|
|
664
665
|
New in version 1.3
|
|
665
666
|
|
|
@@ -56,6 +56,7 @@ setup(
|
|
|
56
56
|
"Programming Language :: Python :: 3.12",
|
|
57
57
|
"Programming Language :: Python :: 3.13",
|
|
58
58
|
"Programming Language :: Python :: 3.14",
|
|
59
|
+
"Programming Language :: Python :: Free Threading :: 1 - Unstable",
|
|
59
60
|
"Topic :: Utilities",
|
|
60
61
|
],
|
|
61
62
|
description = "efficient arrays of booleans -- C extension",
|
|
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
|