You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by jo...@apache.org on 2020/05/05 15:13:40 UTC
[impala] branch master updated: IMPALA-9720: Update bitarray 0.9.0
-> 1.2.1
This is an automated email from the ASF dual-hosted git repository.
joemcdonnell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git
The following commit(s) were added to refs/heads/master by this push:
new 537c30d IMPALA-9720: Update bitarray 0.9.0 -> 1.2.1
537c30d is described below
commit 537c30dd063934373d171bdd9ad03835ee8febfc
Author: David Knupp <dk...@cloudera.com>
AuthorDate: Thu Apr 30 01:02:17 2020 -0700
IMPALA-9720: Update bitarray 0.9.0 -> 1.2.1
This is needed for python3 compatibility.
Tested by running gerrit-verify-dryrun.
Change-Id: I0641b03e880314a424d9d5a0651945c4f51273bc
Reviewed-on: http://gerrit.cloudera.org:8080/15858
Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
LICENSE.txt | 2 +-
bin/rat_exclude_files.txt | 2 +-
shell/.gitignore | 5 +-
shell/ext-py/bitarray-0.9.0/PKG-INFO | 593 -----------
shell/ext-py/bitarray-0.9.0/bitarray/__init__.py | 116 ---
shell/ext-py/bitarray-1.2.1/AUTHORS | 22 +
shell/ext-py/bitarray-1.2.1/CHANGE_LOG | 254 +++++
shell/ext-py/bitarray-1.2.1/LICENSE | 48 +
shell/ext-py/bitarray-1.2.1/README.md | 695 +++++++++++++
shell/ext-py/bitarray-1.2.1/TODO | 95 ++
shell/ext-py/bitarray-1.2.1/bitarray/__init__.py | 91 ++
.../bitarray/_bitarray.c | 662 +++++++-----
shell/ext-py/bitarray-1.2.1/bitarray/_util.c | 422 ++++++++
.../bitarray/test_bitarray.py | 1085 ++++++++++++--------
shell/ext-py/bitarray-1.2.1/bitarray/test_util.py | 590 +++++++++++
shell/ext-py/bitarray-1.2.1/bitarray/util.py | 274 +++++
.../{bitarray-0.9.0 => bitarray-1.2.1}/setup.py | 8 +-
shell/ext-py/bitarray-1.2.1/update_readme.py | 112 ++
shell/packaging/requirements.txt | 2 +-
19 files changed, 3651 insertions(+), 1427 deletions(-)
diff --git a/LICENSE.txt b/LICENSE.txt
index 1d832c8..b4cedd9 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -398,7 +398,7 @@ www/DataTables* and www/datatables*: MIT license
Parts of be/src/runtime/string-search.h: Python Software License V2
Parts of shell/impala_shell.py: Python Software License V2
-shell/ext-py/bit-array*: Python Software License V2
+shell/ext-py/bitarray*: Python Software License V2
Copyright (c) 2001 - 2016 Python Software Foundation; All Rights Reserved
diff --git a/bin/rat_exclude_files.txt b/bin/rat_exclude_files.txt
index d0c4968..e0e78f9 100644
--- a/bin/rat_exclude_files.txt
+++ b/bin/rat_exclude_files.txt
@@ -42,7 +42,7 @@ www/favicon.ico
tests/comparison/leopard/static/css/bootstrap*
tests/comparison/leopard/static/fonts/glyphicons-halflings*
tests/comparison/leopard/static/js/bootstrap*
-shell/ext-py/bitarray-0.9.0/*
+shell/ext-py/bitarray-1.2.1/*
shell/ext-py/prettytable-0.7.1/*
shell/ext-py/sasl-0.1.1/*
shell/ext-py/six-1.14.0/*
diff --git a/shell/.gitignore b/shell/.gitignore
index 97f2c41..0d96453 100644
--- a/shell/.gitignore
+++ b/shell/.gitignore
@@ -11,8 +11,8 @@ ext-py/prettytable-0.7.1/prettytable.egg-info
ext-py/sqlparse-0.3.1/dist/
ext-py/sqlparse-0.3.1/build/
ext-py/sqlparse-0.3.1/sqlparse.egg-info/
-ext-py/bitarray-0.9.0/bitarray.egg-info/
-ext-py/bitarray-0.9.0/dist/
+ext-py/bitarray-1.2.1/bitarray.egg-info/
+ext-py/bitarray-1.2.1/dist/
ext-py/thrift_sasl-0.4.2/dist/
ext-py/thrift_sasl-0.4.2/build/
ext-py/thrift_sasl-0.4.2/six.egg-info/
@@ -21,6 +21,7 @@ ext-py/thrift_sasl-0.4.2/six.egg-info/
# clean phase. Previous version of deps should be kept here for cleaning otherwise they
# may cause a build failure. Also the ignore path must be changed to the root folder
# so "git clean -Xdf" will work.
+ext-py/bitarray-0.9.0/
ext-py/six-1.11.0/
ext-py/sqlparse-0.1.7/
ext-py/sqlparse-0.1.19/
diff --git a/shell/ext-py/bitarray-0.9.0/PKG-INFO b/shell/ext-py/bitarray-0.9.0/PKG-INFO
deleted file mode 100644
index b867d86..0000000
--- a/shell/ext-py/bitarray-0.9.0/PKG-INFO
+++ /dev/null
@@ -1,593 +0,0 @@
-Metadata-Version: 1.1
-Name: bitarray
-Version: 0.9.0
-Summary: efficient arrays of booleans -- C extension
-Home-page: https://github.com/ilanschnell/bitarray
-Author: Ilan Schnell
-Author-email: ilanschnell@gmail.com
-License: PSF
-Description: ======================================
- bitarray: efficient arrays of booleans
- ======================================
-
- This module provides an object type which efficiently represents an array
- of booleans. Bitarrays are sequence types and behave very much like usual
- lists. Eight bits are represented by one byte in a contiguous block of
- memory. The user can select between two representations: little-endian
- and big-endian. All of the functionality is implemented in C.
- Methods for accessing the machine representation are provided.
- This can be useful when bit level access to binary files is required,
- such as portable bitmap image files (.pbm). Also, when dealing with
- compressed data which uses variable bit length encoding, you may find
- this module useful.
-
-
- Key features
- ------------
-
- * All functionality implemented in C.
-
- * Bitarray objects behave very much like a list object, in particular
- slicing (including slice assignment and deletion) is supported.
-
- * The bit endianness can be specified for each bitarray object, see below.
-
- * On 32bit systems, a bitarray object can contain up to 2^34 elements,
- that is 16 Gbits (on 64bit machines up to 2^63 elements in theory --
- on Python 2.4 only 2^31 elements,
- see `PEP 353 <http://www.python.org/dev/peps/pep-0353/>`_
- (added in Python 2.5)).
-
- * Packing and unpacking to other binary data formats,
- e.g. `numpy.ndarray <http://www.scipy.org/Tentative_NumPy_Tutorial>`_,
- is possible.
-
- * Fast methods for encoding and decoding variable bit length prefix codes
-
- * Sequential search (as list or iterator)
-
- * Bitwise operations: ``&, |, ^, &=, |=, ^=, ~``
-
- * Pickling and unpickling of bitarray objects possible.
-
- * Bitarray objects support the buffer protocol (Python 2.7 only)
-
-
- Installation
- ------------
-
- bitarray can be installed from source::
-
- $ tar xzf bitarray-0.9.0.tar.gz
- $ cd bitarray-0.9.0
- $ python setup.py install
-
- On Unix systems, the latter command may have to be executed with root
- privileges.
- If you have `distribute <http://pypi.python.org/pypi/distribute/>`_
- installed, you can easy_install bitarray.
- Once you have installed the package, you may want to test it::
-
- $ python -c 'import bitarray; bitarray.test()'
- bitarray is installed in: /usr/local/lib/python2.7/site-packages/bitarray
- bitarray version: 0.9.0
- 2.7.2 (r271:86832, Nov 29 2010) [GCC 4.2.1 (SUSE Linux)]
- .........................................................................
- ...........................................
- ----------------------------------------------------------------------
- Ran 134 tests in 1.396s
-
- OK
-
- You can always import the function test,
- and ``test().wasSuccessful()`` will return True when the test went well.
-
-
-
- Using the module
- ----------------
-
- As mentioned above, bitarray objects behave very much like lists, so
- there is not too much to learn. The biggest difference from list objects
- is the ability to access the machine representation of the object.
- When doing so, the bit endianness is of importance; this issue is
- explained in detail in the section below. Here, we demonstrate the
- basic usage of bitarray objects:
-
- >>> from bitarray import bitarray
- >>> a = bitarray() # create empty bitarray
- >>> a.append(True)
- >>> a.extend([False, True, True])
- >>> a
- bitarray('1011')
-
- Bitarray objects can be instantiated in different ways:
-
- >>> a = bitarray(2**20) # bitarray of length 1048576 (uninitialized)
- >>> bitarray('1001011') # from a string
- bitarray('1001011')
- >>> lst = [True, False, False, True, False, True, True]
- >>> bitarray(lst) # from list, tuple, iterable
- bitarray('1001011')
-
- Bits can be assigned from any Python object, if the value can be interpreted
- as a truth value. You can think of this as Python's built-in function bool()
- being applied, whenever casting an object:
-
- >>> a = bitarray([42, '', True, {}, 'foo', None])
- >>> a
- bitarray('101010')
- >>> a.append(a) # note that bool(a) is True
- >>> a.count(42) # counts occurrences of True (not 42)
- 4L
- >>> a.remove('') # removes first occurrence of False
- >>> a
- bitarray('110101')
-
- Like lists, bitarray objects support slice assignment and deletion:
-
- >>> a = bitarray(50)
- >>> a.setall(False)
- >>> a[11:37:3] = 9 * bitarray([True])
- >>> a
- bitarray('00000000000100100100100100100100100100000000000000')
- >>> del a[12::3]
- >>> a
- bitarray('0000000000010101010101010101000000000')
- >>> a[-6:] = bitarray('10011')
- >>> a
- bitarray('000000000001010101010101010100010011')
- >>> a += bitarray('000111')
- >>> a[9:]
- bitarray('001010101010101010100010011000111')
-
- In addition, slices can be assigned to booleans, which is easier (and
- faster) than assigning to a bitarray in which all values are the same:
-
- >>> a = 20 * bitarray('0')
- >>> a[1:15:3] = True
- >>> a
- bitarray('01001001001001000000')
-
- This is easier and faster than:
-
- >>> a = 20 * bitarray('0')
- >>> a[1:15:3] = 5 * bitarray('1')
- >>> a
- bitarray('01001001001001000000')
-
- Note that in the latter we have to create a temporary bitarray whose length
- must be known or calculated.
-
-
- Bit endianness
- --------------
-
- Since a bitarray allows addressing of individual bits, where the machine
- represents 8 bits in one byte, there are two obvious choices for this
- mapping: little- and big-endian.
- When creating a new bitarray object, the endianness can always be
- specified explicitly:
-
- >>> a = bitarray(endian='little')
- >>> a.frombytes(b'A')
- >>> a
- bitarray('10000010')
- >>> b = bitarray('11000010', endian='little')
- >>> b.tobytes()
- 'C'
-
- Here, the low-bit comes first because little-endian means that increasing
- numeric significance corresponds to an increasing address (index).
- So a[0] is the lowest and least significant bit, and a[7] is the highest
- and most significant bit.
-
- >>> a = bitarray(endian='big')
- >>> a.frombytes(b'A')
- >>> a
- bitarray('01000001')
- >>> a[6] = 1
- >>> a.tobytes()
- 'C'
-
- Here, the high-bit comes first because big-endian
- means "most-significant first".
- So a[0] is now the lowest and most significant bit, and a[7] is the highest
- and least significant bit.
-
- The bit endianness is a property attached to each bitarray object.
- When comparing bitarray objects, the endianness (and hence the machine
- representation) is irrelevant; what matters is the mapping from indices
- to bits:
-
- >>> bitarray('11001', endian='big') == bitarray('11001', endian='little')
- True
-
- Bitwise operations (``&, |, ^, &=, |=, ^=, ~``) are implemented efficiently
- using the corresponding byte operations in C, i.e. the operators act on the
- machine representation of the bitarray objects. Therefore, one has to be
- cautious when applying the operation to bitarrays with different endianness.
-
- When converting to and from machine representation, using
- the ``tobytes``, ``frombytes``, ``tofile`` and ``fromfile`` methods,
- the endianness matters:
-
- >>> a = bitarray(endian='little')
- >>> a.frombytes(b'\x01')
- >>> a
- bitarray('10000000')
- >>> b = bitarray(endian='big')
- >>> b.frombytes(b'\x80')
- >>> b
- bitarray('10000000')
- >>> a == b
- True
- >>> a.tobytes() == b.tobytes()
- False
-
- The endianness can not be changed once an object is created.
- However, since creating a bitarray from another bitarray just copies the
- memory representing the data, you can create a new bitarray with different
- endianness:
-
- >>> a = bitarray('11100000', endian='little')
- >>> a
- bitarray('11100000')
- >>> b = bitarray(a, endian='big')
- >>> b
- bitarray('00000111')
- >>> a == b
- False
- >>> a.tobytes() == b.tobytes()
- True
-
- The default bit endianness is currently big-endian; however, this may change
- in the future, and when dealing with the machine representation of bitarray
- objects, it is recommended to always explicitly specify the endianness.
-
- Unless explicitly converting to machine representation, using
- the ``tobytes``, ``frombytes``, ``tofile`` and ``fromfile`` methods,
- the bit endianness will have no effect on any computation, and one
- can safely ignore setting the endianness, and other details of this section.
-
-
- Buffer protocol
- ---------------
-
- Python 2.7 provides memoryview objects, which allow Python code to access
- the internal data of an object that supports the buffer protocol without
- copying. Bitarray objects support this protocol, with the memory being
- interpreted as simple bytes.
-
- >>> a = bitarray('01000001' '01000010' '01000011', endian='big')
- >>> v = memoryview(a)
- >>> len(v)
- 3
- >>> v[-1]
- 'C'
- >>> v[:2].tobytes()
- 'AB'
- >>> v.readonly # changing a bitarray's memory is also possible
- False
- >>> v[1] = 'o'
- >>> a
- bitarray('010000010110111101000011')
-
-
- Variable bit length prefix codes
- --------------------------------
-
- The method ``encode`` takes a dictionary mapping symbols to bitarrays
- and an iterable, and extends the bitarray object with the encoded symbols
- found while iterating. For example:
-
- >>> d = {'H':bitarray('111'), 'e':bitarray('0'),
- ... 'l':bitarray('110'), 'o':bitarray('10')}
- ...
- >>> a = bitarray()
- >>> a.encode(d, 'Hello')
- >>> a
- bitarray('111011011010')
-
- Note that the string ``'Hello'`` is an iterable, but the symbols are not
- limited to characters, in fact any immutable Python object can be a symbol.
- Taking the same dictionary, we can apply the ``decode`` method which will
- return a list of the symbols:
-
- >>> a.decode(d)
- ['H', 'e', 'l', 'l', 'o']
- >>> ''.join(a.decode(d))
- 'Hello'
-
- Since symbols are not limited to being characters, it is necessary to return
- them as elements of a list, rather than simply returning the joined string.
-
-
- Reference
- ---------
-
- **The bitarray class:**
-
- ``bitarray([initial], [endian=string])``
- Return a new bitarray object whose items are bits initialized from
- the optional initial, and endianness.
- If no object is provided, the bitarray is initialized to have length zero.
- The initial object may be of the following types:
-
- int, long
- Create bitarray of length given by the integer. The initial values
- in the array are random, because only the memory allocated.
-
- string
- Create bitarray from a string of '0's and '1's.
-
- list, tuple, iterable
- Create bitarray from a sequence, each element in the sequence is
- converted to a bit using truth value value.
-
- bitarray
- Create bitarray from another bitarray. This is done by copying the
- memory holding the bitarray data, and is hence very fast.
-
- The optional keyword arguments 'endian' specifies the bit endianness of the
- created bitarray object.
- Allowed values are 'big' and 'little' (default is 'big').
-
- Note that setting the bit endianness only has an effect when accessing the
- machine representation of the bitarray, i.e. when using the methods: tofile,
- fromfile, tobytes, frombytes.
-
-
- **A bitarray object supports the following methods:**
-
- ``all()`` -> bool
- Returns True when all bits in the array are True.
-
-
- ``any()`` -> bool
- Returns True when any bit in the array is True.
-
-
- ``append(item)``
- Append the value bool(item) to the end of the bitarray.
-
-
- ``buffer_info()`` -> tuple
- Return a tuple (address, size, endianness, unused, allocated) giving the
- current memory address, the size (in bytes) used to hold the bitarray's
- contents, the bit endianness as a string, the number of unused bits
- (e.g. a bitarray of length 11 will have a buffer size of 2 bytes and
- 5 unused bits), and the size (in bytes) of the allocated memory.
-
-
- ``bytereverse()``
- For all bytes representing the bitarray, reverse the bit order (in-place).
- Note: This method changes the actual machine values representing the
- bitarray; it does not change the endianness of the bitarray object.
-
-
- ``copy()`` -> bitarray
- Return a copy of the bitarray.
-
-
- ``count([value])`` -> int
- Return number of occurrences of value (defaults to True) in the bitarray.
-
-
- ``decode(code)`` -> list
- Given a prefix code (a dict mapping symbols to bitarrays),
- decode the content of the bitarray and return the list of symbols.
-
-
- ``encode(code, iterable)``
- Given a prefix code (a dict mapping symbols to bitarrays),
- iterate over the iterable object with symbols, and extend the bitarray
- with the corresponding bitarray for each symbols.
-
-
- ``endian()`` -> string
- Return the bit endianness as a string (either 'little' or 'big').
-
-
- ``extend(object)``
- Append bits to the end of the bitarray. The objects which can be passed
- to this method are the same iterable objects which can given to a bitarray
- object upon initialization.
-
-
- ``fill()`` -> int
- Adds zeros to the end of the bitarray, such that the length of the bitarray
- will be a multiple of 8. Returns the number of bits added (0..7).
-
-
- ``frombytes(bytes)``
- Append from a byte string, interpreted as machine values.
-
-
- ``fromfile(f, [n])``
- Read n bytes from the file object f and append them to the bitarray
- interpreted as machine values. When n is omitted, as many bytes are
- read until EOF is reached.
-
-
- ``fromstring(string)``
- Append from a string, interpreting the string as machine values.
- Deprecated since version 0.4.0, use ``frombytes()`` instead.
-
-
- ``index(value, [start, [stop]])`` -> int
- Return index of the first occurrence of bool(value) in the bitarray.
- Raises ValueError if the value is not present.
-
-
- ``insert(i, item)``
- Insert bool(item) into the bitarray before position i.
-
-
- ``invert()``
- Invert all bits in the array (in-place),
- i.e. convert each 1-bit into a 0-bit and vice versa.
-
-
- ``iterdecode(code)`` -> iterator
- Given a prefix code (a dict mapping symbols to bitarrays),
- decode the content of the bitarray and iterate over the symbols.
-
-
- ``itersearch(bitarray)`` -> iterator
- Searches for the given a bitarray in self, and return an iterator over
- the start positions where bitarray matches self.
-
-
- ``length()`` -> int
- Return the length, i.e. number of bits stored in the bitarray.
- This method is preferred over __len__ (used when typing ``len(a)``),
- since __len__ will fail for a bitarray object with 2^31 or more elements
- on a 32bit machine, whereas this method will return the correct value,
- on 32bit and 64bit machines.
-
-
- ``pack(bytes)``
- Extend the bitarray from a byte string, where each characters corresponds to
- a single bit. The character b'\x00' maps to bit 0 and all other characters
- map to bit 1.
- This method, as well as the unpack method, are meant for efficient
- transfer of data between bitarray objects to other python objects
- (for example NumPy's ndarray object) which have a different view of memory.
-
-
- ``pop([i])`` -> item
- Return the i-th (default last) element and delete it from the bitarray.
- Raises IndexError if bitarray is empty or index is out of range.
-
-
- ``remove(item)``
- Remove the first occurrence of bool(item) in the bitarray.
- Raises ValueError if item is not present.
-
-
- ``reverse()``
- Reverse the order of bits in the array (in-place).
-
-
- ``search(bitarray, [limit])`` -> list
- Searches for the given a bitarray in self, and returns the start positions
- where bitarray matches self as a list.
- The optional argument limits the number of search results to the integer
- specified. By default, all search results are returned.
-
-
- ``setall(value)``
- Set all bits in the bitarray to bool(value).
-
-
- ``sort(reverse=False)``
- Sort the bits in the array (in-place).
-
-
- ``to01()`` -> string
- Return a string containing '0's and '1's, representing the bits in the
- bitarray object.
- Note: To extend a bitarray from a string containing '0's and '1's,
- use the extend method.
-
-
- ``tobytes()`` -> bytes
- Return the byte representation of the bitarray.
- When the length of the bitarray is not a multiple of 8, the few remaining
- bits (1..7) are set to 0.
-
-
- ``tofile(f)``
- Write all bits (as machine values) to the file object f.
- When the length of the bitarray is not a multiple of 8,
- the remaining bits (1..7) are set to 0.
-
-
- ``tolist()`` -> list
- Return an ordinary list with the items in the bitarray.
- Note that the list object being created will require 32 or 64 times more
- memory than the bitarray object, which may cause a memory error if the
- bitarray is very large.
- Also note that to extend a bitarray with elements from a list,
- use the extend method.
-
-
- ``tostring()`` -> string
- Return the string representing (machine values) of the bitarray.
- When the length of the bitarray is not a multiple of 8, the few remaining
- bits (1..7) are set to 0.
- Deprecated since version 0.4.0, use ``tobytes()`` instead.
-
-
- ``unpack(zero=b'\x00', one=b'\xff')`` -> bytes
- Return a byte string containing one character for each bit in the bitarray,
- using the specified mapping.
- See also the pack method.
-
-
- **Functions defined in the module:**
-
- ``test(verbosity=1, repeat=1)`` -> TextTestResult
- Run self-test, and return unittest.runner.TextTestResult object.
-
-
- ``bitdiff(a, b)`` -> int
- Return the difference between two bitarrays a and b.
- This is function does the same as (a ^ b).count(), but is more memory
- efficient, as no intermediate bitarray object gets created
-
-
- ``bits2bytes(n)`` -> int
- Return the number of bytes necessary to store n bits.
-
-
- Change log
- ----------
-
- **0.9.0** (2019-04-22):
-
- * more efficient decode and iterdecode by using C-level binary tree
- instead of a python one, #54
- * added buffer protocol support for Python 3, #55
- * fixed invalid pointer exceptions in pypy, #47
- * made all examples Py3k compatible
- * add gene sequence example
- * add official Python 3.7 support
- * drop Python 2.4, 3.1 and 3.2 support
-
-
- **0.8.3** (2018-07-06):
-
- * add exception to setup.py when README.rst cannot be opened
-
-
- **0.8.2** (2018-05-30):
-
- * add official Python 3.6 support (although it was already working)
- * fix description of fill(), #52
- * handle extending self correctly, #28
- * copy_n: fast copy with memmove fixed, #43
- * minor clarity/wording changes to README, #23
-
-
- Please find the complete change log
- `here <https://github.com/ilanschnell/bitarray/blob/master/CHANGE_LOG>`_.
-
-Platform: UNKNOWN
-Classifier: License :: OSI Approved :: Python Software Foundation License
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: C
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.5
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Topic :: Utilities
diff --git a/shell/ext-py/bitarray-0.9.0/bitarray/__init__.py b/shell/ext-py/bitarray-0.9.0/bitarray/__init__.py
deleted file mode 100644
index 6a97795..0000000
--- a/shell/ext-py/bitarray-0.9.0/bitarray/__init__.py
+++ /dev/null
@@ -1,116 +0,0 @@
-"""
-This package defines an object type which can efficiently represent
-a bitarray. Bitarrays are sequence types and behave very much like lists.
-
-Please find a description of this package at:
-
- http://pypi.python.org/pypi/bitarray/
-
-Author: Ilan Schnell
-"""
-from bitarray._bitarray import _bitarray, bitdiff, bits2bytes, _sysinfo
-
-__version__ = '0.9.0'
-
-
-def _check_codedict(codedict):
- if not isinstance(codedict, dict):
- raise TypeError("dictionary expected")
- if len(codedict) == 0:
- raise ValueError("prefix code empty")
- for k, v in codedict.items():
- if not isinstance(v, bitarray):
- raise TypeError("bitarray expected for dictionary value")
- if v.length() == 0:
- raise ValueError("non-empty bitarray expected")
-
-
-class bitarray(_bitarray):
- """bitarray([initial], [endian=string])
-
-Return a new bitarray object whose items are bits initialized from
-the optional initial, and endianness.
-If no object is provided, the bitarray is initialized to have length zero.
-The initial object may be of the following types:
-
-int, long
- Create bitarray of length given by the integer. The initial values
- in the array are random, because only the memory allocated.
-
-string
- Create bitarray from a string of '0's and '1's.
-
-list, tuple, iterable
- Create bitarray from a sequence, each element in the sequence is
- converted to a bit using truth value value.
-
-bitarray
- Create bitarray from another bitarray. This is done by copying the
- memory holding the bitarray data, and is hence very fast.
-
-The optional keyword arguments 'endian' specifies the bit endianness of the
-created bitarray object.
-Allowed values are 'big' and 'little' (default is 'big').
-
-Note that setting the bit endianness only has an effect when accessing the
-machine representation of the bitarray, i.e. when using the methods: tofile,
-fromfile, tobytes, frombytes."""
-
- def fromstring(self, string):
- """fromstring(string)
-
-Append from a string, interpreting the string as machine values.
-Deprecated since version 0.4.0, use ``frombytes()`` instead."""
- return self.frombytes(string.encode())
-
- def tostring(self):
- """tostring() -> string
-
-Return the string representing (machine values) of the bitarray.
-When the length of the bitarray is not a multiple of 8, the few remaining
-bits (1..7) are set to 0.
-Deprecated since version 0.4.0, use ``tobytes()`` instead."""
- return self.tobytes().decode()
-
- def decode(self, codedict):
- """decode(code) -> list
-
-Given a prefix code (a dict mapping symbols to bitarrays),
-decode the content of the bitarray and return the list of symbols."""
- _check_codedict(codedict)
- return self._decode(codedict)
-
- def iterdecode(self, codedict):
- """iterdecode(code) -> iterator
-
-Given a prefix code (a dict mapping symbols to bitarrays),
-decode the content of the bitarray and iterate over the symbols."""
- _check_codedict(codedict)
- return self._iterdecode(codedict)
-
- def encode(self, codedict, iterable):
- """encode(code, iterable)
-
-Given a prefix code (a dict mapping symbols to bitarrays),
-iterate over the iterable object with symbols, and extend the bitarray
-with the corresponding bitarray for each symbols."""
- _check_codedict(codedict)
- self._encode(codedict, iterable)
-
- def __int__(self):
- raise TypeError("int() argument cannot be a bitarray")
-
- def __long__(self):
- raise TypeError("long() argument cannot be a bitarray")
-
- def __float__(self):
- raise TypeError("float() argument cannot be a bitarray")
-
-
-def test(verbosity=1, repeat=1):
- """test(verbosity=1, repeat=1) -> TextTestResult
-
-Run self-test, and return unittest.runner.TextTestResult object.
-"""
- from bitarray import test_bitarray
- return test_bitarray.run(verbosity=verbosity, repeat=repeat)
diff --git a/shell/ext-py/bitarray-1.2.1/AUTHORS b/shell/ext-py/bitarray-1.2.1/AUTHORS
new file mode 100644
index 0000000..bc87e4a
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/AUTHORS
@@ -0,0 +1,22 @@
+bitarray is written and maintained by
+Ilan Schnell <il...@gmail.com>
+
+The author would like to thank the following people for patches, feedback,
+suggestions, and discussions:
+ - Roland Puntaier (Porting to Python 3.x)
+ - Daniel Stutzbach (for help with reference counts)
+ - Lluís Pàmies (C level itersearch)
+ - Vangelis Koukis (Python 2.4 support)
+ - Kris Kennaway
+ - Travis Oliphant
+ - Gael Varoquaux
+ - David Ormsbee
+ - David Kammeyer
+ - Bryce Hendrix
+ - Judah De Paula
+ - Corran Webster
+ - Chris Mueller
+ - Koen van de Sande
+ - Paul McGuire
+ - Chris Gohlke
+ - Ushma Bhatt
diff --git a/shell/ext-py/bitarray-1.2.1/CHANGE_LOG b/shell/ext-py/bitarray-1.2.1/CHANGE_LOG
new file mode 100644
index 0000000..f274ffc
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/CHANGE_LOG
@@ -0,0 +1,254 @@
+2020-01-06 1.2.1:
+-------------------
+ * simplify markdown of readme so PyPI renders better
+ * make tests for bitarray.util required (instead of warning when
+ they cannot be imported)
+
+
+2019-12-06 1.2.0:
+-------------------
+ * add bitarray.util module which provides useful utility functions
+ * deprecate `bitarray.bitdiff` in favor of `bitarray.util.count_xor`
+ * use markdown for documentation
+ * fix bug in .count() on 32bit systems in special cases when array size
+ is 2^29 bits or larger
+ * simplified tests by using bytes syntax
+ * update smallints and sieve example to use new utility module
+ * simplified mandel example to use numba
+ * use file context managers in tests
+
+
+2019-11-07 1.1.0:
+-------------------
+ * add frozenbitarray object
+ * add optional start and stop parameters to .count() method
+ * add official Python 3.8 support
+ * optimize setrange() C-function by using memset
+ * fix issue #74, bitarray is hashable on Python 2
+ * fix issue #68, `unittest.TestCase.assert_` deprecated
+ * improved test suite - tests should run in about 1 second
+ * update documentation to use positional-only syntax in docstrings
+ * update readme to pass Python 3 doctest
+ * add utils module to examples
+
+
+2019-07-19 1.0.1:
+-------------------
+ * fix readme to pass `twine check`
+
+
+2019-07-15 1.0.0:
+-------------------
+ * fix bitarrays beings created from unicode in Python 2
+ * use `PyBytes_*` in C code, treating the Py3k function names as default,
+ which also removes all redefinitions of `PyString_*`
+ * handle negative arguments of .index() method consistently with how
+ they are treated for lists
+ * add a few more comments to the C code
+ * move imports outside tests: pickle, io, etc.
+ * drop Python 2.5 support
+
+
+2019-05-20 0.9.3:
+-------------------
+ * refactor resize() - only shrink allocated memory if new size falls
+ lower than half the allocated size
+ * improve error message when trying to initialize from float or complex
+
+
+2019-04-29 0.9.2:
+-------------------
+ * fix to compile on Windows with VS 2015, issue #72
+
+
+2019-04-28 0.9.1:
+-------------------
+ * fix types to actually be types, #29
+ * check for ambiguous prefix codes when building binary tree for decoding
+ * remove Python level methods: encode, decode, iterdecode (in favor of
+ having these implemented on the C-level along with check_codedict)
+ * fix self tests for Python 2.5 and 2.6
+ * move all Huffman code related example code into examples/huffman
+ * add code to generate graphviz .dot file of Huffman tree to examples
+
+
+2019-04-22 0.9.0:
+-------------------
+ * more efficient decode and iterdecode by using C-level binary tree
+ instead of a python one, #54
+ * added buffer protocol support for Python 3, #55
+ * fixed invalid pointer exceptions in pypy, #47
+ * made all examples Py3k compatible
+ * add gene sequence example
+ * add official Python 3.7 support
+ * drop Python 2.4, 3.1 and 3.2 support
+
+
+2018-07-06 0.8.3:
+-------------------
+ * add exception to setup.py when README.rst cannot be opened
+
+
+2018-05-30 0.8.2:
+-------------------
+ * add official Python 3.6 support (although it was already working)
+ * fix description of fill(), #52
+ * handle extending self correctly, #28
+ * copy_n: fast copy with memmove fixed, #43
+ * minor clarity/wording changes to README, #23
+
+
+2013-03-30 0.8.1:
+-------------------
+ * fix issue #10, i.e. int(bitarray()) segfault
+ * added tests for using a bitarray object as an argument to functions
+ like int, long (on Python 2), float, list, tuple, dict
+
+
+2012-04-04 0.8.0:
+-------------------
+ * add Python 2.4 support
+ * add (module level) function bitdiff for calculating the difference
+ between two bitarrays
+
+
+2012-02-15 0.7.0:
+-------------------
+ * add iterdecode method (C level), which returns an iterator but is
+ otherwise like the decode method
+ * improve memory efficiency and speed of pickling large bitarray objects
+
+
+2012-02-06 0.6.0:
+-------------------
+ * add buffer protocol to bitarray objects (Python 2.7 only)
+ * allow slice assignment to 0 or 1, e.g. a[::3] = 0 (in addition to
+ booleans)
+ * moved implementation of itersearch method to C level (Lluis Pamies)
+ * search, itersearch now only except bitarray objects,
+ whereas __contains__ excepts either booleans or bitarrays
+ * use a priority queue for Huffman tree example (thanks to Ushma Bhatt)
+ * improve documentation
+
+
+2012-02-02 0.5.2:
+-------------------
+ * fixed MSVC compile error on Python 3 (thanks to Chris Gohlke)
+ * add missing start and stop optional parameters to index() method
+ * add examples/compress.py
+
+
+2012-01-31 0.5.1:
+-------------------
+ * update documentation to use tobytes and frombytes, rather than tostring
+ and fromstring (which are now deprecated)
+ * simplified how tests are run
+
+
+2012-01-23 0.5.0:
+-------------------
+ * added itersearch method
+ * added Bloom filter example
+ * minor fixes in docstrings, added more tests
+
+
+2011-12-29 0.4.0:
+-------------------
+ * porting to Python 3.x (Roland Puntaier)
+ * introduced tobytes, frombytes (tostring, fromstring are now deprecated)
+ * updated development status
+ * added sieve prime number example
+ * moved project to github: https://github.com/ilanschnell/bitarray
+
+
+2009-04-06 0.3.5:
+-------------------
+ * fixed reference counts bugs
+ * added possibility to slice assign to True or False, e.g. a[::3] = True
+ will set every third element to True
+
+
+2009-01-15 0.3.4:
+-------------------
+ * Made C code less ambiguous, such that the package compiles on
+ Visual Studio, with all tests passing.
+
+
+2008-12-14 0.3.3:
+-------------------
+ * Made changes to the C code to allow compilation with more compilers.
+ Compiles on Visual Studio, although there are still a few tests failing.
+
+
+2008-10-19 0.3.2:
+-------------------
+ * Added sequential search method.
+ * The special method __contains__ now also takes advantage of the
+ sequential search.
+
+
+2008-10-12 0.3.1:
+-------------------
+ * Simplified state information for pickling. Argument for count is now
+ optional, defaults to True. Fixed typos.
+
+
+2008-09-30 0.3.0:
+-------------------
+ * Fixed a severe bug for 64-bit machines. Implemented all methods in C,
+ improved tests.
+ * Removed deprecated methods from01 and fromlist.
+
+
+2008-09-23 0.2.5:
+-------------------
+ * Added section in README about prefix codes. Implemented _multiply method
+ for faster __mul__ and __imul__. Fixed some typos.
+
+
+2008-09-22 0.2.4:
+-------------------
+ * Implemented encode and decode method (in C) for variable-length prefix
+ codes.
+ * Added more examples, wrote README for the examples.
+ * Added more tests, fixed some typos.
+
+
+2008-09-16 0.2.3:
+-------------------
+ * Fixed a memory leak, implemented a number of methods in C.
+ These include __getitem__, __setitem__, __delitem__, pop, remove,
+ insert. The methods implemented on the Python level is very limit now.
+ * Implemented bitwise operations.
+
+
+2008-09-09 0.2.2:
+-------------------
+ * Rewrote parts of the README
+ * Implemented memory efficient algorithm for the reverse method
+ * Fixed typos, added a few tests, more C refactoring.
+
+
+2008-09-07 0.2.1:
+-------------------
+ * Improved tests, in particular added checking for memory leaks.
+ * Refactored many things on the C level.
+ * Implemented a few more methods.
+
+
+2008-09-02 0.2.0:
+-------------------
+ * Added bit endianness property to the bitarray object
+ * Added the examples to the release package.
+
+
+2008-08-17 0.1.0:
+-------------------
+ * First official release; put project to
+ http://pypi.python.org/pypi/bitarray/
+
+
+May 2008:
+---------
+Wrote the initial code, and put it on my personal web-site:
+http://ilan.schnell-web.net/prog/
diff --git a/shell/ext-py/bitarray-1.2.1/LICENSE b/shell/ext-py/bitarray-1.2.1/LICENSE
new file mode 100644
index 0000000..2004a1f
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/LICENSE
@@ -0,0 +1,48 @@
+PYTHON SOFTWARE FOUNDATION LICENSE
+----------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python
+alone or in any derivative version, provided, however, that PSF's
+License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Python Software Foundation;
+All Rights Reserved" are retained in Python alone or in any derivative
+version prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee. This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
diff --git a/shell/ext-py/bitarray-1.2.1/README.md b/shell/ext-py/bitarray-1.2.1/README.md
new file mode 100644
index 0000000..b5ea6be
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/README.md
@@ -0,0 +1,695 @@
+bitarray: efficient arrays of booleans
+======================================
+
+This module provides an object type which efficiently represents an array
+of booleans. Bitarrays are sequence types and behave very much like usual
+lists. Eight bits are represented by one byte in a contiguous block of
+memory. The user can select between two representations: little-endian
+and big-endian. All of the functionality is implemented in C.
+Methods for accessing the machine representation are provided.
+This can be useful when bit level access to binary files is required,
+such as portable bitmap image files (.pbm). Also, when dealing with
+compressed data which uses variable bit length encoding, you may find
+this module useful.
+
+
+Key features
+------------
+
+ * All functionality implemented in C.
+ * Bitarray objects behave very much like a list object, in particular
+ slicing (including slice assignment and deletion) is supported.
+ * The bit endianness can be specified for each bitarray object, see below.
+ * Packing and unpacking to other binary data formats, e.g. numpy.ndarray
+ is possible.
+ * Fast methods for encoding and decoding variable bit length prefix codes
+ * Bitwise operations: `&`, `|`, `^`, `&=`, `|=`, `^=`, `~`
+ * Sequential search
+ * Pickling and unpickling of bitarray objects.
+ * Bitarray objects support the buffer protocol (Python 2.7 and above)
+ * On 32-bit systems, a bitarray object can contain up to 2^34 elements,
+ that is 16 Gbits (on 64-bit machines up to 2^63 elements in theory).
+
+
+Installation
+------------
+
+Bitarray can be installed from source:
+
+ $ tar xzf bitarray-1.2.1.tar.gz
+ $ cd bitarray-1.2.1
+ $ python setup.py install
+
+On Unix systems, the latter command may have to be executed with root
+privileges. You can also pip install bitarray.
+Once you have installed the package, you may want to test it:
+
+ $ python -c 'import bitarray; bitarray.test()'
+ bitarray is installed in: /usr/local/lib/python2.7/site-packages/bitarray
+ bitarray version: 1.2.1
+ 3.7.4 (r271:86832, Dec 29 2018) [GCC 4.2.1 (SUSE Linux)]
+ .........................................................................
+ .........................................................................
+ ..............................
+ ----------------------------------------------------------------------
+ Ran 199 tests in 1.144s
+
+ OK
+
+You can always import the function test,
+and `test().wasSuccessful()` will return `True` when the test went well.
+
+
+Using the module
+----------------
+
+As mentioned above, bitarray objects behave very much like lists, so
+there is not too much to learn. The biggest difference from list objects
+is the ability to access the machine representation of the object.
+When doing so, the bit endianness is of importance; this issue is
+explained in detail in the section below. Here, we demonstrate the
+basic usage of bitarray objects:
+
+ >>> from bitarray import bitarray
+ >>> a = bitarray() # create empty bitarray
+ >>> a.append(True)
+ >>> a.extend([False, True, True])
+ >>> a
+ bitarray('1011')
+
+Bitarray objects can be instantiated in different ways:
+
+ >>> a = bitarray(2**20) # bitarray of length 1048576 (uninitialized)
+ >>> bitarray('1001011') # from a string
+ bitarray('1001011')
+ >>> lst = [True, False, False, True, False, True, True]
+ >>> bitarray(lst) # from list, tuple, iterable
+ bitarray('1001011')
+
+Bits can be assigned from any Python object, if the value can be interpreted
+as a truth value. You can think of this as Python's built-in function bool()
+being applied, whenever casting an object:
+
+ >>> a = bitarray([42, '', True, {}, 'foo', None])
+ >>> a
+ bitarray('101010')
+ >>> a.append(a) # note that bool(a) is True
+ >>> a.count(42) # counts occurrences of True (not 42)
+ 4
+ >>> a.remove('') # removes first occurrence of False
+ >>> a
+ bitarray('110101')
+
+Like lists, bitarray objects support slice assignment and deletion:
+
+ >>> a = bitarray(50)
+ >>> a.setall(False)
+ >>> a[11:37:3] = 9 * bitarray([True])
+ >>> a
+ bitarray('00000000000100100100100100100100100100000000000000')
+ >>> del a[12::3]
+ >>> a
+ bitarray('0000000000010101010101010101000000000')
+ >>> a[-6:] = bitarray('10011')
+ >>> a
+ bitarray('000000000001010101010101010100010011')
+ >>> a += bitarray('000111')
+ >>> a[9:]
+ bitarray('001010101010101010100010011000111')
+
+In addition, slices can be assigned to booleans, which is easier (and
+faster) than assigning to a bitarray in which all values are the same:
+
+ >>> a = 20 * bitarray('0')
+ >>> a[1:15:3] = True
+ >>> a
+ bitarray('01001001001001000000')
+
+This is easier and faster than:
+
+ >>> a = 20 * bitarray('0')
+ >>> a[1:15:3] = 5 * bitarray('1')
+ >>> a
+ bitarray('01001001001001000000')
+
+Note that in the latter we have to create a temporary bitarray whose length
+must be known or calculated.
+
+
+Bit endianness
+--------------
+
+Since a bitarray allows addressing of individual bits, where the machine
+represents 8 bits in one byte, there are two obvious choices for this
+mapping: little- and big-endian.
+When creating a new bitarray object, the endianness can always be
+specified explicitly:
+
+ >>> a = bitarray(endian='little')
+ >>> a.frombytes(b'A')
+ >>> a
+ bitarray('10000010')
+ >>> b = bitarray('11000010', endian='little')
+ >>> b.tobytes()
+ b'C'
+
+Here, the low-bit comes first because little-endian means that increasing
+numeric significance corresponds to an increasing address (index).
+So a[0] is the lowest and least significant bit, and a[7] is the highest
+and most significant bit.
+
+ >>> a = bitarray(endian='big')
+ >>> a.frombytes(b'A')
+ >>> a
+ bitarray('01000001')
+ >>> a[6] = 1
+ >>> a.tobytes()
+ b'C'
+
+Here, the high-bit comes first because big-endian
+means "most-significant first".
+So a[0] is now the lowest and most significant bit, and a[7] is the highest
+and least significant bit.
+
+The bit endianness is a property attached to each bitarray object.
+When comparing bitarray objects, the endianness (and hence the machine
+representation) is irrelevant; what matters is the mapping from indices
+to bits:
+
+ >>> bitarray('11001', endian='big') == bitarray('11001', endian='little')
+ True
+
+Bitwise operations (`&`, `|`, `^`, `&=`, `|=`, `^=`, `~`) are implemented
+efficiently using the corresponding byte operations in C, i.e. the operators
+act on the machine representation of the bitarray objects.
+Therefore, one has to be cautious when applying the operation to bitarrays
+with different endianness.
+
+When converting to and from machine representation, using
+the `tobytes`, `frombytes`, `tofile` and `fromfile` methods,
+the endianness matters:
+
+ >>> a = bitarray(endian='little')
+ >>> a.frombytes(b'\x01')
+ >>> a
+ bitarray('10000000')
+ >>> b = bitarray(endian='big')
+ >>> b.frombytes(b'\x80')
+ >>> b
+ bitarray('10000000')
+ >>> a == b
+ True
+ >>> a.tobytes() == b.tobytes()
+ False
+
+The endianness can not be changed once an object is created.
+However, since creating a bitarray from another bitarray just copies the
+memory representing the data, you can create a new bitarray with different
+endianness:
+
+ >>> a = bitarray('11100000', endian='little')
+ >>> a
+ bitarray('11100000')
+ >>> b = bitarray(a, endian='big')
+ >>> b
+ bitarray('00000111')
+ >>> a == b
+ False
+ >>> a.tobytes() == b.tobytes()
+ True
+
+The default bit endianness is currently big-endian, however this may change
+in the future, and when dealing with the machine representation of bitarray
+objects, it is recommended to always explicitly specify the endianness.
+
+Unless explicitly converting to machine representation, using
+the `tobytes`, `frombytes`, `tofile` and `fromfile` methods,
+the bit endianness will have no effect on any computation, and one
+can safely ignore setting the endianness, and other details of this section.
+
+
+Buffer protocol
+---------------
+
+Python 2.7 provides memoryview objects, which allow Python code to access
+the internal data of an object that supports the buffer protocol without
+copying. Bitarray objects support this protocol, with the memory being
+interpreted as simple bytes.
+
+ >>> a = bitarray('01000001' '01000010' '01000011', endian='big')
+ >>> v = memoryview(a)
+ >>> len(v)
+ 3
+ >>> v[-1]
+ 67
+ >>> v[:2].tobytes()
+ b'AB'
+ >>> v.readonly # changing a bitarray's memory is also possible
+ False
+ >>> v[1] = 111
+ >>> a
+ bitarray('010000010110111101000011')
+
+
+Variable bit length prefix codes
+--------------------------------
+
+The method `encode` takes a dictionary mapping symbols to bitarrays
+and an iterable, and extends the bitarray object with the encoded symbols
+found while iterating. For example:
+
+ >>> d = {'H':bitarray('111'), 'e':bitarray('0'),
+ ... 'l':bitarray('110'), 'o':bitarray('10')}
+ ...
+ >>> a = bitarray()
+ >>> a.encode(d, 'Hello')
+ >>> a
+ bitarray('111011011010')
+
+Note that the string `'Hello'` is an iterable, but the symbols are not
+limited to characters, in fact any immutable Python object can be a symbol.
+Taking the same dictionary, we can apply the `decode` method which will
+return a list of the symbols:
+
+ >>> a.decode(d)
+ ['H', 'e', 'l', 'l', 'o']
+ >>> ''.join(a.decode(d))
+ 'Hello'
+
+Since symbols are not limited to being characters, it is necessary to return
+them as elements of a list, rather than simply returning the joined string.
+
+
+Reference
+=========
+
+The bitarray object:
+--------------------
+
+`bitarray(initial=0, /, endian='big')`
+
+Return a new bitarray object whose items are bits initialized from
+the optional initial object, and endianness.
+If no initial object is provided, an empty bitarray (length zero) is created.
+The initial object may be of the following types:
+
+`int`: Create a bitarray of given integer length. The initial values are
+arbitrary. If you want all values to be set, use the .setall() method.
+
+`str`: Create bitarray from a string of `0` and `1`.
+
+`list`, `tuple`, `iterable`: Create bitarray from a sequence, each
+element in the sequence is converted to a bit using its truth value.
+
+`bitarray`: Create bitarray from another bitarray. This is done by
+copying the memory holding the bitarray data, and is hence very fast.
+
+The optional keyword arguments `endian` specifies the bit endianness of the
+created bitarray object.
+Allowed values are the strings `big` and `little` (default is `big`).
+
+Note that setting the bit endianness only has an effect when accessing the
+machine representation of the bitarray, i.e. when using the methods: tofile,
+fromfile, tobytes, frombytes.
+
+
+**A bitarray object supports the following methods:**
+
+`all()` -> bool
+
+Returns True when all bits in the array are True.
+
+
+`any()` -> bool
+
+Returns True when any bit in the array is True.
+
+
+`append(item, /)`
+
+Append the value `bool(item)` to the end of the bitarray.
+
+
+`buffer_info()` -> tuple
+
+Return a tuple (address, size, endianness, unused, allocated) giving the
+current memory address, the size (in bytes) used to hold the bitarray's
+contents, the bit endianness as a string, the number of unused bits
+(e.g. a bitarray of length 11 will have a buffer size of 2 bytes and
+5 unused bits), and the size (in bytes) of the allocated memory.
+
+
+`bytereverse()`
+
+For all bytes representing the bitarray, reverse the bit order (in-place).
+Note: This method changes the actual machine values representing the
+bitarray; it does not change the endianness of the bitarray object.
+
+
+`copy()` -> bitarray
+
+Return a copy of the bitarray.
+
+
+`count(value=True, start=0, stop=<end of array>, /)` -> int
+
+Count the number of occurrences of bool(value) in the bitarray.
+
+
+`decode(code, /)` -> list
+
+Given a prefix code (a dict mapping symbols to bitarrays),
+decode the content of the bitarray and return it as a list of symbols.
+
+
+`encode(code, iterable, /)`
+
+Given a prefix code (a dict mapping symbols to bitarrays),
+iterate over the iterable object with symbols, and extend the bitarray
+with the corresponding bitarray for each symbols.
+
+
+`endian()` -> str
+
+Return the bit endianness as a string (either `little` or `big`).
+
+
+`extend(iterable, /)`
+
+Append bits to the end of the bitarray. The objects which can be passed
+to this method are the same iterable objects which can given to a bitarray
+object upon initialization.
+
+
+`fill()` -> int
+
+Adds zeros to the end of the bitarray, such that the length of the bitarray
+will be a multiple of 8. Returns the number of bits added (0..7).
+
+
+`frombytes(bytes, /)`
+
+Append from a byte string, interpreted as machine values.
+
+
+`fromfile(f, n=<till EOF>, /)`
+
+Read n bytes from the file object f and append them to the bitarray
+interpreted as machine values. When n is omitted, as many bytes are
+read until EOF is reached.
+
+
+`fromstring(str)`
+
+Append from a string, interpreting the string as machine values.
+Deprecated since version 0.4.0, use `.frombytes()` instead.
+
+
+`index(value, start=0, stop=<end of array>, /)` -> int
+
+Return index of the first occurrence of `bool(value)` in the bitarray.
+Raises `ValueError` if the value is not present.
+
+
+`insert(index, value, /)`
+
+Insert `bool(value)` into the bitarray before index.
+
+
+`invert()`
+
+Invert all bits in the array (in-place),
+i.e. convert each 1-bit into a 0-bit and vice versa.
+
+
+`iterdecode(code, /)` -> iterator
+
+Given a prefix code (a dict mapping symbols to bitarrays),
+decode the content of the bitarray and return an iterator over
+the symbols.
+
+
+`itersearch(bitarray, /)` -> iterator
+
+Searches for the given a bitarray in self, and return an iterator over
+the start positions where bitarray matches self.
+
+
+`length()` -> int
+
+Return the length, i.e. number of bits stored in the bitarray.
+This method is preferred over `__len__` (used when typing `len(a)`),
+since `__len__` will fail for a bitarray object with 2^31 or more elements
+on a 32bit machine, whereas this method will return the correct value,
+on 32bit and 64bit machines.
+
+
+`pack(bytes, /)`
+
+Extend the bitarray from bytes, where each byte corresponds to a single
+bit. The byte `b'\x00'` maps to bit 0 and all other characters map to
+bit 1.
+This method, as well as the unpack method, are meant for efficient
+transfer of data between bitarray objects to other python objects
+(for example NumPy's ndarray object) which have a different memory view.
+
+
+`pop(index=-1, /)` -> item
+
+Return the i-th (default last) element and delete it from the bitarray.
+Raises `IndexError` if bitarray is empty or index is out of range.
+
+
+`remove(value, /)`
+
+Remove the first occurrence of `bool(value)` in the bitarray.
+Raises `ValueError` if item is not present.
+
+
+`reverse()`
+
+Reverse the order of bits in the array (in-place).
+
+
+`search(bitarray, limit=<none>, /)` -> list
+
+Searches for the given bitarray in self, and return the list of start
+positions.
+The optional argument limits the number of search results to the integer
+specified. By default, all search results are returned.
+
+
+`setall(value, /)`
+
+Set all bits in the bitarray to `bool(value)`.
+
+
+`sort(reverse=False)`
+
+Sort the bits in the array (in-place).
+
+
+`to01()` -> str
+
+Return a string containing '0's and '1's, representing the bits in the
+bitarray object.
+Note: To extend a bitarray from a string containing '0's and '1's,
+use the extend method.
+
+
+`tobytes()` -> bytes
+
+Return the byte representation of the bitarray.
+When the length of the bitarray is not a multiple of 8, the few remaining
+bits (1..7) are considered to be 0.
+
+
+`tofile(f, /)`
+
+Write all bits (as machine values) to the file object f.
+When the length of the bitarray is not a multiple of 8,
+the remaining bits (1..7) are set to 0.
+
+
+`tolist()` -> list
+
+Return an ordinary list with the items in the bitarray.
+Note that the list object being created will require 32 or 64 times more
+memory than the bitarray object, which may cause a memory error if the
+bitarray is very large.
+Also note that to extend a bitarray with elements from a list,
+use the extend method.
+
+
+`tostring()` -> str
+
+Return the string representing (machine values) of the bitarray.
+When the length of the bitarray is not a multiple of 8, the few remaining
+bits (1..7) are set to 0.
+Deprecated since version 0.4.0, use `.tobytes()` instead.
+
+
+`unpack(zero=b'\x00', one=b'\xff')` -> bytes
+
+Return bytes containing one character for each bit in the bitarray,
+using the specified mapping.
+
+
+The frozenbitarray object:
+--------------------------
+
+`frozenbitarray(initial=0, /, endian='big')`
+
+Return a frozenbitarray object, which is initialized the same way a bitarray
+object is initialized. A frozenbitarray is immutable and hashable.
+Its contents cannot be altered after is created; however, it can be used as
+a dictionary key.
+
+
+Functions defined in the module:
+--------------------------------
+
+`test(verbosity=1, repeat=1)` -> TextTestResult
+
+Run self-test, and return unittest.runner.TextTestResult object.
+
+
+`bitdiff(a, b, /)` -> int
+
+Return the difference between two bitarrays a and b.
+This is function does the same as (a ^ b).count(), but is more memory
+efficient, as no intermediate bitarray object gets created.
+Deprecated since version 1.2.0, use `bitarray.util.count_xor()` instead.
+
+
+`bits2bytes(n, /)` -> int
+
+Return the number of bytes necessary to store n bits.
+
+
+Functions defined in bitarray.util:
+-----------------------------------
+
+`zeros(length, /, endian='big')` -> bitarray
+
+Create a bitarray of length, with all values 0.
+
+
+`rindex(bitarray, value=True, /)` -> int
+
+Return the rightmost index of `bool(value)` in bitarray.
+Raises `ValueError` if the value is not present.
+
+
+`strip(bitarray, mode='right', /)` -> bitarray
+
+Strip zeros from left, right or both ends.
+Allowed values for mode are the strings: `left`, `right`, `both`
+
+
+`count_n(a, n, /)` -> int
+
+Find the smallest index `i` for which `a[:i].count() == n`.
+Raises `ValueError`, when n exceeds the `a.count()`.
+
+
+`count_and(a, b, /)` -> int
+
+Returns `(a & b).count()`, but is more memory efficient,
+as no intermediate bitarray object gets created.
+
+
+`count_or(a, b, /)` -> int
+
+Returns `(a | b).count()`, but is more memory efficient,
+as no intermediate bitarray object gets created.
+
+
+`count_xor(a, b, /)` -> int
+
+Returns `(a ^ b).count()`, but is more memory efficient,
+as no intermediate bitarray object gets created.
+
+
+`subset(a, b, /)` -> bool
+
+Return True if bitarray `a` is a subset of bitarray `b` (False otherwise).
+`subset(a, b)` is equivalent to `(a & b).count() == a.count()` but is more
+efficient since we can stop as soon as one mismatch is found, and no
+intermediate bitarray object gets created.
+
+
+`ba2hex(bitarray, /)` -> hexstr
+
+Return a bytes object containing with hexadecimal representation of
+the bitarray (which has to be multiple of 4 in length).
+
+
+`hex2ba(hexstr, /)` -> bitarray
+
+Bitarray of hexadecimal representation.
+hexstr may contain any number of hex digits (upper or lower case).
+
+
+`ba2int(bitarray, /)` -> int
+
+Convert the given bitarray into an integer.
+The bit-endianness of the bitarray is respected.
+
+
+`int2ba(int, /, length=None, endian='big')` -> bitarray
+
+Convert the given integer into a bitarray (with given endianness,
+and no leading (big-endian) / trailing (little-endian) zeros).
+If length is provided, the result will be of this length, and an
+`OverflowError` will be raised, if the integer cannot be represented
+within length bits.
+
+
+`huffman_code(dict, /, endian='big')` -> dict
+
+Given a frequency map, a dictionary mapping symbols to thier frequency,
+calculate the Huffman code, i.e. a dict mapping those symbols to
+bitarrays (with given endianness). Note that the symbols may be any
+hashable object (including `None`).
+
+
+Change log
+----------
+
+*1.2.1* (2020-01-06):
+
+ * simplify markdown of readme so PyPI renders better
+ * make tests for bitarray.util required (instead of warning when
+ they cannot be imported)
+
+
+*1.2.0* (2019-12-06):
+
+ * add bitarray.util module which provides useful utility functions
+ * deprecate `bitarray.bitdiff` in favor of `bitarray.util.count_xor`
+ * use markdown for documentation
+ * fix bug in .count() on 32bit systems in special cases when array size
+ is 2^29 bits or larger
+ * simplified tests by using bytes syntax
+ * update smallints and sieve example to use new utility module
+ * simplified mandel example to use numba
+ * use file context managers in tests
+
+
+*1.1.0* (2019-11-07):
+
+ * add frozenbitarray object
+ * add optional start and stop parameters to .count() method
+ * add official Python 3.8 support
+ * optimize setrange() C-function by using memset
+ * fix issue #74, bitarray is hashable on Python 2
+ * fix issue #68, `unittest.TestCase.assert_` deprecated
+ * improved test suite - tests should run in about 1 second
+ * update documentation to use positional-only syntax in docstrings
+ * update readme to pass Python 3 doctest
+ * add utils module to examples
+
+
+Please find the complete change log
+<a href="https://github.com/ilanschnell/bitarray/blob/master/CHANGE_LOG">here</a>.
diff --git a/shell/ext-py/bitarray-1.2.1/TODO b/shell/ext-py/bitarray-1.2.1/TODO
new file mode 100644
index 0000000..7ea9550
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/TODO
@@ -0,0 +1,95 @@
+* compute the lexicographically next bit permutation, see
+ http://www-graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation
+
+* Write special tests for really large bitarrays, for which the length
+ exceeds 2**31 bits
+
+
+--------------------------- RANDOM NOTES ---------------------------------
+
+#!/bin/bash
+for PY in py26 py26d py27 py32 py33
+do
+ export PYTHON=$HOME/$PY/bin/python
+ make clean
+ make test || exit 1
+done
+
+#!/bin/bash
+for PY in 2.4 2.5 2.6 2.7 3.1 3.2 3.3
+do
+ PYBIN=$HOME/$PY/bin/python
+ rm -rf $HOME/$PY/lib/python$PY/site-packages
+ $PYBIN -V
+ rm -rf build dist
+ $PYBIN setup.py install >/dev/null 2>&1 || exit 1
+ pushd /tmp
+ $PYBIN -c "import bitarray; assert bitarray.test(repeat=1).wasSuccessful()" || \
+ exit 1
+ popd
+done
+
+
+
+# checking the growth pattern:
+a = bitarray()
+sizes = set()
+for i in xrange(1000000):
+ sizes.add(a.buffer_info()[4])
+ a.append(0)
+print sorted(sizes)
+
+
+/* walk the binary tree, and display information for each node */
+static void
+display_binode_tree(binode *tree)
+{
+ int k;
+
+ printf("id: %p child0: %14p child1: %14p symbol: %s\n",
+ tree,
+ tree->child[0],
+ tree->child[1],
+ tree->symbol ? PyString_AsString(tree->symbol) : "NULL");
+
+ for (k = 0; k < 2; k++)
+ if (tree->child[k])
+ display_binode_tree(tree->child[k]);
+}
+
+
+# If I should ever decide to use pre-calculated tables:
+static char bytereverse_trans[256] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
diff --git a/shell/ext-py/bitarray-1.2.1/bitarray/__init__.py b/shell/ext-py/bitarray-1.2.1/bitarray/__init__.py
new file mode 100644
index 0000000..1b99326
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/bitarray/__init__.py
@@ -0,0 +1,91 @@
+"""
+This package defines an object type which can efficiently represent
+a bitarray. Bitarrays are sequence types and behave very much like lists.
+
+Please find a description of this package at:
+
+ http://pypi.python.org/pypi/bitarray/
+
+Author: Ilan Schnell
+"""
+from bitarray._bitarray import _bitarray, bitdiff, bits2bytes, _sysinfo
+
+__version__ = '1.2.1'
+
+
+class bitarray(_bitarray):
+ """bitarray(initial=0, /, endian='big')
+
+Return a new bitarray object whose items are bits initialized from
+the optional initial object, and endianness.
+If no initial object is provided, an empty bitarray (length zero) is created.
+The initial object may be of the following types:
+
+`int`: Create a bitarray of given integer length. The initial values are
+arbitrary. If you want all values to be set, use the .setall() method.
+
+`str`: Create bitarray from a string of `0` and `1`.
+
+`list`, `tuple`, `iterable`: Create bitarray from a sequence, each
+element in the sequence is converted to a bit using its truth value.
+
+`bitarray`: Create bitarray from another bitarray. This is done by
+copying the memory holding the bitarray data, and is hence very fast.
+
+The optional keyword arguments `endian` specifies the bit endianness of the
+created bitarray object.
+Allowed values are the strings `big` and `little` (default is `big`).
+
+Note that setting the bit endianness only has an effect when accessing the
+machine representation of the bitarray, i.e. when using the methods: tofile,
+fromfile, tobytes, frombytes."""
+
+ def fromstring(self, string):
+ """fromstring(str)
+
+Append from a string, interpreting the string as machine values.
+Deprecated since version 0.4.0, use `.frombytes()` instead."""
+ return self.frombytes(string.encode())
+
+ def tostring(self):
+ """tostring() -> str
+
+Return the string representing (machine values) of the bitarray.
+When the length of the bitarray is not a multiple of 8, the few remaining
+bits (1..7) are set to 0.
+Deprecated since version 0.4.0, use `.tobytes()` instead."""
+ return self.tobytes().decode()
+
+
+class frozenbitarray(_bitarray):
+ """frozenbitarray(initial=0, /, endian='big')
+
+Return a frozenbitarray object, which is initialized the same way a bitarray
+object is initialized. A frozenbitarray is immutable and hashable.
+Its contents cannot be altered after is created; however, it can be used as
+a dictionary key.
+"""
+ def __repr__(self):
+ return 'frozen' + _bitarray.__repr__(self)
+
+ def __hash__(self):
+ if getattr(self, '_hash', None) is None:
+ self._hash = hash((self.length(), self.tobytes()))
+ return self._hash
+
+ def __delitem__(self, *args, **kwargs):
+ raise TypeError("'frozenbitarray' is immutable")
+
+ append = bytereverse = extend = encode = fill = __delitem__
+ frombytes = fromfile = insert = invert = pack = pop = __delitem__
+ remove = reverse = setall = sort = __setitem__ = __delitem__
+ __iand__ = __iadd__ = __imul__ = __ior__ = __ixor__ = __delitem__
+
+
+def test(verbosity=1, repeat=1):
+ """test(verbosity=1, repeat=1) -> TextTestResult
+
+Run self-test, and return unittest.runner.TextTestResult object.
+"""
+ from bitarray import test_bitarray
+ return test_bitarray.run(verbosity=verbosity, repeat=repeat)
diff --git a/shell/ext-py/bitarray-0.9.0/bitarray/_bitarray.c b/shell/ext-py/bitarray-1.2.1/bitarray/_bitarray.c
similarity index 83%
rename from shell/ext-py/bitarray-0.9.0/bitarray/_bitarray.c
rename to shell/ext-py/bitarray-1.2.1/bitarray/_bitarray.c
index d605f4c..c9ce6ba 100644
--- a/shell/ext-py/bitarray-0.9.0/bitarray/_bitarray.c
+++ b/shell/ext-py/bitarray-1.2.1/bitarray/_bitarray.c
@@ -1,6 +1,9 @@
/*
- This file is the C part of the bitarray package. Almost all
- functionality is implemented here.
+ Copyright (c) 2008 - 2019, Ilan Schnell
+ bitarray is published under the PSF license.
+
+ This file is the C part of the bitarray package.
+ All functionality is implemented here.
Author: Ilan Schnell
*/
@@ -13,22 +16,9 @@
#endif
#ifdef IS_PY3K
-#include "bytesobject.h"
-#define PyString_FromStringAndSize PyBytes_FromStringAndSize
-#define PyString_FromString PyBytes_FromString
-#define PyString_Check PyBytes_Check
-#define PyString_Size PyBytes_Size
-#define PyString_AsString PyBytes_AsString
-#define PyString_ConcatAndDel PyBytes_ConcatAndDel
#define Py_TPFLAGS_HAVE_WEAKREFS 0
#endif
-#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 6
-/* backward compatibility with Python 2.5 */
-#define Py_TYPE(ob) (((PyObject *) (ob))->ob_type)
-#define Py_SIZE(ob) (((PyVarObject *) (ob))->ob_size)
-#endif
-
#if PY_MAJOR_VERSION == 3 || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 7)
/* (new) buffer protocol */
#define WITH_BUFFER
@@ -48,15 +38,17 @@ typedef long long int idx_t;
/* throughout: 0 = little endian 1 = big endian */
#define DEFAULT_ENDIAN 1
+/* Unlike the normal convention, ob_size is the byte count, not the number
+ of elements. The reason for doing this is that we can use our own
+ special idx_t for the number of bits (which can exceed 2^32 on a 32 bit
+ machine. */
typedef struct {
PyObject_VAR_HEAD
-#ifdef WITH_BUFFER
- int ob_exports; /* how many buffer exports */
-#endif
char *ob_item;
Py_ssize_t allocated; /* how many bytes allocated */
- idx_t nbits; /* length og bitarray */
+ idx_t nbits; /* length of bitarray, i.e. elements */
int endian; /* bit endianness of bitarray */
+ int ob_exports; /* how many buffer exports */
PyObject *weakreflist; /* list of weak references */
} bitarrayobject;
@@ -64,22 +56,31 @@ static PyTypeObject Bitarraytype;
#define bitarray_Check(obj) PyObject_TypeCheck(obj, &Bitarraytype)
-#define BITS(bytes) (((idx_t) 8) * ((idx_t) (bytes)))
+#define BITS(bytes) ((idx_t) (bytes) << 3)
+/* number of bytes necessary to store given bits */
#define BYTES(bits) (((bits) == 0) ? 0 : (((bits) - 1) / 8 + 1))
#define BITMASK(endian, i) (((char) 1) << ((endian) ? (7 - (i)%8) : (i)%8))
/* ------------ low level access to bits in bitarrayobject ------------- */
+#ifndef NDEBUG
+static int GETBIT(bitarrayobject *self, idx_t i) {
+ assert(0 <= i && i < self->nbits);
+ return ((self)->ob_item[(i) / 8] & BITMASK((self)->endian, i) ? 1 : 0);
+}
+#else
#define GETBIT(self, i) \
((self)->ob_item[(i) / 8] & BITMASK((self)->endian, i) ? 1 : 0)
+#endif
static void
setbit(bitarrayobject *self, idx_t i, int bit)
{
char *cp, mask;
+ assert(0 <= i && i < BITS(Py_SIZE(self)));
mask = BITMASK(self->endian, i);
cp = self->ob_item + i / 8;
if (bit)
@@ -91,11 +92,9 @@ setbit(bitarrayobject *self, idx_t i, int bit)
static int
check_overflow(idx_t nbits)
{
- idx_t max_bits;
-
assert(nbits >= 0);
- if (sizeof(void *) == 4) { /* 32bit machine */
- max_bits = ((idx_t) 1) << 34; /* 2^34 = 16 Gbits*/
+ if (sizeof(void *) == 4) { /* 32bit system */
+ const idx_t max_bits = ((idx_t) 1) << 34; /* 2^34 = 16 Gbits*/
if (nbits > max_bits) {
char buff[256];
sprintf(buff, "cannot create bitarray of size %lld, "
@@ -111,50 +110,46 @@ static int
resize(bitarrayobject *self, idx_t nbits)
{
Py_ssize_t newsize;
- size_t _new_size; /* for allocation */
+ size_t new_allocated;
+ Py_ssize_t allocated = self->allocated;
if (check_overflow(nbits) < 0)
return -1;
-
newsize = (Py_ssize_t) BYTES(nbits);
/* Bypass realloc() when a previous overallocation is large enough
- to accommodate the newsize. If the newsize is 16 smaller than the
- current size, then proceed with the realloc() to shrink the list.
+ to accommodate the newsize. If the newsize falls lower than half
+ the allocated size, then proceed with the realloc() to shrink.
*/
- if (self->allocated >= newsize &&
- Py_SIZE(self) < newsize + 16 &&
- self->ob_item != NULL)
- {
+ if (allocated >= newsize && newsize >= (allocated >> 1)) {
+ assert(self->ob_item != NULL || newsize == 0);
Py_SIZE(self) = newsize;
self->nbits = nbits;
return 0;
}
- if (newsize >= Py_SIZE(self) + 65536)
- /* Don't overallocate when the size increase is very large. */
- _new_size = newsize;
- else
- /* This over-allocates proportional to the bitarray size, making
- room for additional growth. The over-allocation is mild, but is
- enough to give linear-time amortized behavior over a long
- sequence of appends() in the presence of a poorly-performing
- system realloc().
+ new_allocated = (size_t) newsize;
+ if (newsize < Py_SIZE(self) + 65536)
+ /* Over-allocate unless the size increase is very large.
+ This over-allocates proportional to the bitarray size, making
+ room for additional growth.
The growth pattern is: 0, 4, 8, 16, 25, 34, 44, 54, 65, 77, ...
Note, the pattern starts out the same as for lists but then
grows at a smaller rate so that larger bitarrays only overallocate
by about 1/16th -- this is done because bitarrays are assumed
to be memory critical.
*/
- _new_size = (newsize >> 4) + (Py_SIZE(self) < 8 ? 3 : 7) + newsize;
+ new_allocated += (newsize >> 4) + (newsize < 8 ? 3 : 7);
- self->ob_item = PyMem_Realloc(self->ob_item, _new_size);
+ if (newsize == 0)
+ new_allocated = 0;
+ self->ob_item = PyMem_Realloc(self->ob_item, new_allocated);
if (self->ob_item == NULL) {
PyErr_NoMemory();
return -1;
}
Py_SIZE(self) = newsize;
- self->allocated = _new_size;
+ self->allocated = new_allocated;
self->nbits = nbits;
return 0;
}
@@ -181,7 +176,7 @@ newbitarrayobject(PyTypeObject *type, idx_t nbits, int endian)
obj->ob_item = NULL;
}
else {
- obj->ob_item = PyMem_Malloc((size_t) nbytes);
+ obj->ob_item = (char *) PyMem_Malloc((size_t) nbytes);
if (obj->ob_item == NULL) {
PyObject_Del(obj);
PyErr_NoMemory();
@@ -215,30 +210,34 @@ copy_n(bitarrayobject *self, idx_t a,
assert(0 <= n && n <= self->nbits && n <= other->nbits);
assert(0 <= a && a <= self->nbits - n);
assert(0 <= b && b <= other->nbits - n);
- if (n == 0) {
+ if (n == 0)
return;
- }
+ /* When the start positions are at byte positions, we can copy whole
+ bytes using memmove, and copy the remaining few bits individually.
+ Note that the order of these two operations matters when copying
+ self to self. */
if (self->endian == other->endian && a % 8 == 0 && b % 8 == 0 && n >= 8)
{
const Py_ssize_t bytes = (Py_ssize_t) n / 8;
- const idx_t bits = bytes * 8;
+ const idx_t bits = BITS(bytes);
- if (a <= b) {
+ assert(bits <= n && n < bits + 8);
+ if (a <= b)
memmove(self->ob_item + a / 8, other->ob_item + b / 8, bytes);
- }
- if (n != bits) {
+
+ if (n != bits)
copy_n(self, bits + a, other, bits + b, n - bits);
- }
- if (a > b) {
+
+ if (a > b)
memmove(self->ob_item + a / 8, other->ob_item + b / 8, bytes);
- }
+
return;
}
- /* the different type of looping is only relevant when other and self
- are the same object, i.e. when copying a piece of an bitarrayobject
- onto itself */
+ /* The two different types of looping are only relevant when copying
+ self to self, i.e. when copying a piece of an bitarrayobject onto
+ itself. */
if (a <= b) {
for (i = 0; i < n; i++) /* loop forward (delete) */
setbit(self, i + a, GETBIT(other, i + b));
@@ -282,10 +281,10 @@ insert_n(bitarrayobject *self, idx_t start, idx_t n)
static int
setunused(bitarrayobject *self)
{
- idx_t i, n;
+ const idx_t n = BITS(Py_SIZE(self));
+ idx_t i;
int res = 0;
- n = BITS(Py_SIZE(self));
for (i = self->nbits; i < n; i++) {
setbit(self, i, 0);
res++;
@@ -321,7 +320,7 @@ enum op_type {
OP_xor,
};
-/* perform bitwise operation */
+/* perform bitwise in-place operation */
static int
bitwise(bitarrayobject *self, PyObject *arg, enum op_type oper)
{
@@ -354,6 +353,8 @@ bitwise(bitarrayobject *self, PyObject *arg, enum op_type oper)
for (i = 0; i < Py_SIZE(self); i++)
self->ob_item[i] ^= other->ob_item[i];
break;
+ default: /* should never happen */
+ return -1;
}
return 0;
}
@@ -366,8 +367,24 @@ setrange(bitarrayobject *self, idx_t start, idx_t stop, int val)
assert(0 <= start && start <= self->nbits);
assert(0 <= stop && stop <= self->nbits);
- for (i = start; i < stop; i++)
- setbit(self, i, val);
+
+ if (self->nbits == 0 || start >= stop)
+ return;
+
+ if (stop >= start + 8) {
+ const Py_ssize_t byte_start = BYTES(start);
+ const Py_ssize_t byte_stop = (Py_ssize_t) stop / 8;
+ for (i = start; i < BITS(byte_start); i++)
+ setbit(self, i, val);
+ memset(self->ob_item + byte_start, val ? 0xff : 0x00,
+ byte_stop - byte_start);
+ for (i = BITS(byte_stop); i < stop; i++)
+ setbit(self, i, val);
+ }
+ else {
+ for (i = start; i < stop; i++)
+ setbit(self, i, val);
+ }
}
static void
@@ -430,18 +447,38 @@ static int bitcount_lookup[256] = {
/* returns number of 1 bits */
static idx_t
-count(bitarrayobject *self)
+count(bitarrayobject *self, int vi, idx_t start, idx_t stop)
{
- Py_ssize_t i;
- idx_t res = 0;
+ idx_t i, res = 0;
unsigned char c;
- setunused(self);
- for (i = 0; i < Py_SIZE(self); i++) {
- c = self->ob_item[i];
- res += bitcount_lookup[c];
+ assert(0 <= start && start <= self->nbits);
+ assert(0 <= stop && stop <= self->nbits);
+ assert(0 <= vi && vi <= 1);
+ assert(BYTES(stop) <= Py_SIZE(self));
+
+ if (self->nbits == 0 || start >= stop)
+ return 0;
+
+ if (stop >= start + 8) {
+ const Py_ssize_t byte_start = BYTES(start);
+ const Py_ssize_t byte_stop = (Py_ssize_t) (stop / 8);
+ Py_ssize_t j;
+
+ for (i = start; i < BITS(byte_start); i++)
+ res += GETBIT(self, i);
+ for (j = byte_start; j < byte_stop; j++) {
+ c = self->ob_item[j];
+ res += bitcount_lookup[c];
+ }
+ for (i = BITS(byte_stop); i < stop; i++)
+ res += GETBIT(self, i);
}
- return res;
+ else {
+ for (i = start; i < stop; i++)
+ res += GETBIT(self, i);
+ }
+ return vi ? res : stop - start - res;
}
/* return index of first occurrence of vi, -1 when x is not in found. */
@@ -450,31 +487,25 @@ findfirst(bitarrayobject *self, int vi, idx_t start, idx_t stop)
{
Py_ssize_t j;
idx_t i;
- char c;
- if (Py_SIZE(self) == 0)
- return -1;
- if (start < 0 || start > self->nbits)
- start = 0;
- if (stop < 0 || stop > self->nbits)
- stop = self->nbits;
- if (start >= stop)
+ assert(0 <= start && start <= self->nbits);
+ assert(0 <= stop && stop <= self->nbits);
+ assert(0 <= vi && vi <= 1);
+ assert(BYTES(stop) <= Py_SIZE(self));
+
+ if (self->nbits == 0 || start >= stop)
return -1;
- if (stop > start + 8) {
+ if (stop >= start + 8) {
/* seraching for 1 means: break when byte is not 0x00
searching for 0 means: break when byte is not 0xff */
- c = vi ? 0x00 : 0xff;
+ const char c = vi ? 0x00 : 0xff;
/* skip ahead by checking whole bytes */
for (j = (Py_ssize_t) (start / 8); j < BYTES(stop); j++)
if (c ^ self->ob_item[j])
break;
- if (j == Py_SIZE(self))
- j--;
- assert(0 <= j && j < Py_SIZE(self));
-
if (start < BITS(j))
start = BITS(j);
}
@@ -487,8 +518,8 @@ findfirst(bitarrayobject *self, int vi, idx_t start, idx_t stop)
return -1;
}
-/* search for the first occurrence bitarray xa (in self), starting at p,
- and return its position (-1 when not found)
+/* search for the first occurrence of bitarray xa (in self), starting at p,
+ and return its position (or -1 when not found)
*/
static idx_t
search(bitarrayobject *self, bitarrayobject *xa, idx_t p)
@@ -532,7 +563,7 @@ append_item(bitarrayobject *self, PyObject *item)
static PyObject *
unpack(bitarrayobject *self, char zero, char one)
{
- PyObject *res;
+ PyObject *result;
Py_ssize_t i;
char *str;
@@ -540,7 +571,7 @@ unpack(bitarrayobject *self, char zero, char one)
PyErr_SetString(PyExc_OverflowError, "bitarray too large to unpack");
return NULL;
}
- str = PyMem_Malloc((size_t) self->nbits);
+ str = (char *) PyMem_Malloc((size_t) self->nbits);
if (str == NULL) {
PyErr_NoMemory();
return NULL;
@@ -548,9 +579,9 @@ unpack(bitarrayobject *self, char zero, char one)
for (i = 0; i < self->nbits; i++) {
*(str + i) = GETBIT(self, i) ? one : zero;
}
- res = PyString_FromStringAndSize(str, (Py_ssize_t) self->nbits);
+ result = PyBytes_FromStringAndSize(str, (Py_ssize_t) self->nbits);
PyMem_Free((void *) str);
- return res;
+ return result;
}
static int
@@ -562,10 +593,8 @@ extend_bitarray(bitarrayobject *self, bitarrayobject *other)
if (other->nbits == 0)
return 0;
- /*
- Note: other may be self. Thus we take the size before we resize,
- ensuring we only copy the right parts of the array.
- */
+ /* Note that other may be self. Thus we take the size before we resize,
+ ensuring we only copy the right parts of the array. */
n_other_bits = other->nbits;
n_sum = self->nbits + other->nbits;
@@ -643,36 +672,35 @@ extend_tuple(bitarrayobject *self, PyObject *tuple)
return 0;
}
-/* extend_string(): extend the bitarray from a string, where each whole
- characters is converted to a single bit
-*/
-enum conv_tp {
- STR_01, /* '0' -> 0 '1' -> 1 no other characters allowed */
- STR_RAW, /* 0x00 -> 0 other -> 1 */
+/* extend_bytes(): extend the bitarray from a PyBytes object, where each
+ whole character is converted to a single bit */
+enum conv_t {
+ BYTES_01, /* '0' -> 0 '1' -> 1 no other characters allowed */
+ BYTES_RAW, /* 0x00 -> 0 other -> 1 */
};
static int
-extend_string(bitarrayobject *self, PyObject *string, enum conv_tp conv)
+extend_bytes(bitarrayobject *self, PyObject *bytes, enum conv_t conv)
{
Py_ssize_t strlen, i;
char c, *str;
int vi = 0;
- assert(PyString_Check(string));
- strlen = PyString_Size(string);
+ assert(PyBytes_Check(bytes));
+ strlen = PyBytes_Size(bytes);
if (strlen == 0)
return 0;
if (resize(self, self->nbits + strlen) < 0)
return -1;
- str = PyString_AsString(string);
+ str = PyBytes_AsString(bytes);
for (i = 0; i < strlen; i++) {
c = *(str + i);
/* depending on conv, map c to bit */
switch (conv) {
- case STR_01:
+ case BYTES_01:
switch (c) {
case '0': vi = 0; break;
case '1': vi = 1; break;
@@ -682,9 +710,11 @@ extend_string(bitarrayobject *self, PyObject *string, enum conv_tp conv)
return -1;
}
break;
- case STR_RAW:
+ case BYTES_RAW:
vi = c ? 1 : 0;
break;
+ default: /* should never happen */
+ return -1;
}
setbit(self, self->nbits - strlen + i, vi);
}
@@ -692,20 +722,20 @@ extend_string(bitarrayobject *self, PyObject *string, enum conv_tp conv)
}
static int
-extend_rawstring(bitarrayobject *self, PyObject *string)
+extend_rawbytes(bitarrayobject *self, PyObject *bytes)
{
Py_ssize_t strlen;
char *str;
- assert(PyString_Check(string) && self->nbits % 8 == 0);
- strlen = PyString_Size(string);
+ assert(PyBytes_Check(bytes) && self->nbits % 8 == 0);
+ strlen = PyBytes_Size(bytes);
if (strlen == 0)
return 0;
if (resize(self, self->nbits + BITS(strlen)) < 0)
return -1;
- str = PyString_AsString(string);
+ str = PyBytes_AsString(bytes);
memcpy(self->ob_item + (Py_SIZE(self) - strlen), str, strlen);
return 0;
}
@@ -726,18 +756,16 @@ extend_dispatch(bitarrayobject *self, PyObject *obj)
if (PyTuple_Check(obj)) /* tuple */
return extend_tuple(self, obj);
- if (PyString_Check(obj)) /* str01 */
- return extend_string(self, obj, STR_01);
+ if (PyBytes_Check(obj)) /* bytes 01 */
+ return extend_bytes(self, obj, BYTES_01);
-#ifdef IS_PY3K
- if (PyUnicode_Check(obj)) { /* str01 */
- PyObject *string;
- string = PyUnicode_AsEncodedString(obj, NULL, NULL);
- ret = extend_string(self, string, STR_01);
- Py_DECREF(string);
+ if (PyUnicode_Check(obj)) { /* (unicode) string 01 */
+ PyObject *bytes;
+ bytes = PyUnicode_AsEncodedString(obj, NULL, NULL);
+ ret = extend_bytes(self, bytes, BYTES_01);
+ Py_DECREF(bytes);
return ret;
}
-#endif
if (PyIter_Check(obj)) /* iter */
return extend_iter(self, obj);
@@ -760,7 +788,7 @@ extend_dispatch(bitarrayobject *self, PyObject *obj)
#ifdef IS_PY3K
#define IS_INDEX(x) (PyLong_Check(x) || PyIndex_Check(x))
#define IS_INT_OR_BOOL(x) (PyBool_Check(x) || PyLong_Check(x))
-#else
+#else /* Py 2 */
#define IS_INDEX(x) (PyInt_Check(x) || PyLong_Check(x) || PyIndex_Check(x))
#define IS_INT_OR_BOOL(x) (PyBool_Check(x) || PyInt_Check(x) || \
PyLong_Check(x))
@@ -798,6 +826,19 @@ IntBool_AsInt(PyObject *v)
return (int) x;
}
+/* Normalize index (which may be negative), such that 0 <= i <= n */
+static void
+normalize_index(idx_t n, idx_t *i)
+{
+ if (*i < 0) {
+ *i += n;
+ if (*i < 0)
+ *i = 0;
+ }
+ if (*i > n)
+ *i = n;
+}
+
/* Extract a slice index from a PyInt or PyLong or an object with the
nb_index slot defined, and store in *i.
However, this function returns -1 on error and 0 on success.
@@ -902,8 +943,8 @@ PyDoc_STRVAR(length_doc,
"length() -> int\n\
\n\
Return the length, i.e. number of bits stored in the bitarray.\n\
-This method is preferred over __len__ (used when typing ``len(a)``),\n\
-since __len__ will fail for a bitarray object with 2^31 or more elements\n\
+This method is preferred over `__len__` (used when typing `len(a)`),\n\
+since `__len__` will fail for a bitarray object with 2^31 or more elements\n\
on a 32bit machine, whereas this method will return the correct value,\n\
on 32bit and 64bit machines.");
@@ -937,27 +978,34 @@ Return a copy of the bitarray.");
static PyObject *
bitarray_count(bitarrayobject *self, PyObject *args)
{
- idx_t n1;
- long x = 1;
+ PyObject *x = Py_True;
+ idx_t start = 0, stop = self->nbits;
+ long vi;
- if (!PyArg_ParseTuple(args, "|i:count", &x))
+ if (!PyArg_ParseTuple(args, "|OLL:count", &x, &start, &stop))
return NULL;
- n1 = count(self);
- return PyLong_FromLongLong(x ? n1 : (self->nbits - n1));
+ vi = PyObject_IsTrue(x);
+ if (vi < 0)
+ return NULL;
+
+ normalize_index(self->nbits, &start);
+ normalize_index(self->nbits, &stop);
+
+ return PyLong_FromLongLong(count(self, vi, start, stop));
}
PyDoc_STRVAR(count_doc,
-"count([value]) -> int\n\
+"count(value=True, start=0, stop=<end of array>, /) -> int\n\
\n\
-Return number of occurrences of value (defaults to True) in the bitarray.");
+Count the number of occurrences of bool(value) in the bitarray.");
static PyObject *
bitarray_index(bitarrayobject *self, PyObject *args)
{
PyObject *x;
- idx_t i, start = 0, stop = -1;
+ idx_t i, start = 0, stop = self->nbits;
long vi;
if (!PyArg_ParseTuple(args, "O|LL:index", &x, &start, &stop))
@@ -967,6 +1015,9 @@ bitarray_index(bitarrayobject *self, PyObject *args)
if (vi < 0)
return NULL;
+ normalize_index(self->nbits, &start);
+ normalize_index(self->nbits, &stop);
+
i = findfirst(self, vi, start, stop);
if (i < 0) {
PyErr_SetString(PyExc_ValueError, "index(x): x not in bitarray");
@@ -976,10 +1027,10 @@ bitarray_index(bitarrayobject *self, PyObject *args)
}
PyDoc_STRVAR(index_doc,
-"index(value, [start, [stop]]) -> int\n\
+"index(value, start=0, stop=<end of array>, /) -> int\n\
\n\
-Return index of the first occurrence of bool(value) in the bitarray.\n\
-Raises ValueError if the value is not present.");
+Return index of the first occurrence of `bool(value)` in the bitarray.\n\
+Raises `ValueError` if the value is not present.");
static PyObject *
@@ -991,7 +1042,7 @@ bitarray_extend(bitarrayobject *self, PyObject *obj)
}
PyDoc_STRVAR(extend_doc,
-"extend(object)\n\
+"extend(iterable, /)\n\
\n\
Append bits to the end of the bitarray. The objects which can be passed\n\
to this method are the same iterable objects which can given to a bitarray\n\
@@ -1009,7 +1060,7 @@ bitarray_contains(bitarrayobject *self, PyObject *x)
vi = IntBool_AsInt(x);
if (vi < 0)
return NULL;
- res = findfirst(self, vi, 0, -1) >= 0;
+ res = findfirst(self, vi, 0, self->nbits) >= 0;
}
else if (bitarray_Check(x)) {
res = search(self, (bitarrayobject *) x, 0) >= 0;
@@ -1022,10 +1073,10 @@ bitarray_contains(bitarrayobject *self, PyObject *x)
}
PyDoc_STRVAR(contains_doc,
-"__contains__(x) -> bool\n\
+"__contains__(value, /) -> bool\n\
\n\
-Return True if bitarray contains x, False otherwise.\n\
-The value x may be a boolean (or integer between 0 and 1), or a bitarray.");
+Return True if bitarray contains value, False otherwise.\n\
+The value may be a boolean (or integer between 0 and 1), or a bitarray.");
static PyObject *
@@ -1075,10 +1126,10 @@ bitarray_search(bitarrayobject *self, PyObject *args)
}
PyDoc_STRVAR(search_doc,
-"search(bitarray, [limit]) -> list\n\
+"search(bitarray, limit=<none>, /) -> list\n\
\n\
-Searches for the given a bitarray in self, and returns the start positions\n\
-where bitarray matches self as a list.\n\
+Searches for the given bitarray in self, and return the list of start\n\
+positions.\n\
The optional argument limits the number of search results to the integer\n\
specified. By default, all search results are returned.");
@@ -1120,9 +1171,9 @@ bitarray_endian(bitarrayobject *self)
}
PyDoc_STRVAR(endian_doc,
-"endian() -> string\n\
+"endian() -> str\n\
\n\
-Return the bit endianness as a string (either 'little' or 'big').");
+Return the bit endianness as a string (either `little` or `big`).");
static PyObject *
@@ -1135,15 +1186,15 @@ bitarray_append(bitarrayobject *self, PyObject *v)
}
PyDoc_STRVAR(append_doc,
-"append(item)\n\
+"append(item, /)\n\
\n\
-Append the value bool(item) to the end of the bitarray.");
+Append the value `bool(item)` to the end of the bitarray.");
static PyObject *
bitarray_all(bitarrayobject *self)
{
- if (findfirst(self, 0, 0, -1) >= 0)
+ if (findfirst(self, 0, 0, self->nbits) >= 0)
Py_RETURN_FALSE;
else
Py_RETURN_TRUE;
@@ -1158,7 +1209,7 @@ Returns True when all bits in the array are True.");
static PyObject *
bitarray_any(bitarrayobject *self)
{
- if (findfirst(self, 1, 0, -1) >= 0)
+ if (findfirst(self, 1, 0, self->nbits) >= 0)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
@@ -1184,14 +1235,14 @@ bitarray_reduce(bitarrayobject *self)
}
/* the first byte indicates the number of unused bits at the end, and
the rest of the bytes consist of the raw binary data */
- str = PyMem_Malloc(Py_SIZE(self) + 1);
+ str = (char *) PyMem_Malloc(Py_SIZE(self) + 1);
if (str == NULL) {
PyErr_NoMemory();
goto error;
}
str[0] = (char) setunused(self);
memcpy(str + 1, self->ob_item, Py_SIZE(self));
- repr = PyString_FromStringAndSize(str, Py_SIZE(self) + 1);
+ repr = PyBytes_FromStringAndSize(str, Py_SIZE(self) + 1);
if (repr == NULL)
goto error;
PyMem_Free((void *) str);
@@ -1307,9 +1358,9 @@ bitarray_setall(bitarrayobject *self, PyObject *v)
}
PyDoc_STRVAR(setall_doc,
-"setall(value)\n\
+"setall(value, /)\n\
\n\
-Set all bits in the bitarray to bool(value).");
+Set all bits in the bitarray to `bool(value)`.");
static PyObject *
@@ -1317,13 +1368,13 @@ bitarray_sort(bitarrayobject *self, PyObject *args, PyObject *kwds)
{
idx_t n, n0, n1;
int reverse = 0;
- static char* kwlist[] = {"reverse", NULL};
+ static char *kwlist[] = {"reverse", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:sort", kwlist, &reverse))
return NULL;
n = self->nbits;
- n1 = count(self);
+ n1 = count(self, 1, 0, n);
if (reverse) {
setrange(self, 0, n1, 1);
@@ -1343,6 +1394,10 @@ PyDoc_STRVAR(sort_doc,
Sort the bits in the array (in-place).");
+/* since too many details differ between the Python 2 and 3 implementation
+ of this function, we choose to have two separate function implementation,
+ even though this means some of the code is duplicated in the two versions
+*/
#ifdef IS_PY3K
static PyObject *
bitarray_fromfile(bitarrayobject *self, PyObject *args)
@@ -1381,7 +1436,6 @@ bitarray_fromfile(bitarrayobject *self, PyObject *args)
Py_DECREF(reader);
return NULL;
}
-
nread = PyBytes_Size(result);
t = self->nbits;
@@ -1396,7 +1450,6 @@ bitarray_fromfile(bitarrayobject *self, PyObject *args)
Py_DECREF(reader);
return NULL;
}
-
memcpy(self->ob_item + (Py_SIZE(self) - nread),
PyBytes_AS_STRING(result), nread);
@@ -1411,10 +1464,9 @@ bitarray_fromfile(bitarrayobject *self, PyObject *args)
Py_DECREF(rargs);
Py_DECREF(reader);
-
Py_RETURN_NONE;
}
-#else
+#else /* Python 2 */
static PyObject *
bitarray_fromfile(bitarrayobject *self, PyObject *args)
{
@@ -1478,13 +1530,16 @@ bitarray_fromfile(bitarrayobject *self, PyObject *args)
#endif
PyDoc_STRVAR(fromfile_doc,
-"fromfile(f, [n])\n\
+"fromfile(f, n=<till EOF>, /)\n\
\n\
Read n bytes from the file object f and append them to the bitarray\n\
interpreted as machine values. When n is omitted, as many bytes are\n\
read until EOF is reached.");
+/* since too many details differ between the Python 2 and 3 implementation
+ of this function, we choose to have two separate function implementation
+*/
#ifdef IS_PY3K
static PyObject *
bitarray_tofile(bitarrayobject *self, PyObject *f)
@@ -1522,7 +1577,7 @@ bitarray_tofile(bitarrayobject *self, PyObject *f)
Py_DECREF(result);
Py_RETURN_NONE;
}
-#else
+#else /* Python 2 */
static PyObject *
bitarray_tofile(bitarrayobject *self, PyObject *f)
{
@@ -1549,7 +1604,7 @@ bitarray_tofile(bitarrayobject *self, PyObject *f)
#endif
PyDoc_STRVAR(tofile_doc,
-"tofile(f)\n\
+"tofile(f, /)\n\
\n\
Write all bits (as machine values) to the file object f.\n\
When the length of the bitarray is not a multiple of 8,\n\
@@ -1585,19 +1640,25 @@ use the extend method.");
static PyObject *
-bitarray_frombytes(bitarrayobject *self, PyObject *string)
+bitarray_frombytes(bitarrayobject *self, PyObject *bytes)
{
idx_t t, p;
- if (!PyString_Check(string)) {
- PyErr_SetString(PyExc_TypeError, "byte string expected");
+ if (!PyBytes_Check(bytes)) {
+ PyErr_SetString(PyExc_TypeError, "bytes expected");
return NULL;
}
+
+ /* Before we extend the raw bytes with the new data, we need to store
+ the current size and pad the last byte, as our bitarray size might
+ not be a multiple of 8. After extending, we remove the padding
+ bits again. The same is done in bitarray_fromfile().
+ */
t = self->nbits;
p = setunused(self);
self->nbits += p;
- if (extend_rawstring(self, string) < 0)
+ if (extend_rawbytes(self, bytes) < 0)
return NULL;
if (delete_n(self, t, p) < 0)
return NULL;
@@ -1605,7 +1666,7 @@ bitarray_frombytes(bitarrayobject *self, PyObject *string)
}
PyDoc_STRVAR(frombytes_doc,
-"frombytes(bytes)\n\
+"frombytes(bytes, /)\n\
\n\
Append from a byte string, interpreted as machine values.");
@@ -1614,7 +1675,7 @@ static PyObject *
bitarray_tobytes(bitarrayobject *self)
{
setunused(self);
- return PyString_FromStringAndSize(self->ob_item, Py_SIZE(self));
+ return PyBytes_FromStringAndSize(self->ob_item, Py_SIZE(self));
}
PyDoc_STRVAR(tobytes_doc,
@@ -1622,16 +1683,19 @@ PyDoc_STRVAR(tobytes_doc,
\n\
Return the byte representation of the bitarray.\n\
When the length of the bitarray is not a multiple of 8, the few remaining\n\
-bits (1..7) are set to 0.");
+bits (1..7) are considered to be 0.");
static PyObject *
bitarray_to01(bitarrayobject *self)
{
#ifdef IS_PY3K
- PyObject *string, *unpacked;
+ PyObject *string;
+ PyObject *unpacked;
unpacked = unpack(self, '0', '1');
+ if (unpacked == NULL)
+ return NULL;
string = PyUnicode_FromEncodedObject(unpacked, NULL, NULL);
Py_DECREF(unpacked);
return string;
@@ -1641,7 +1705,7 @@ bitarray_to01(bitarrayobject *self)
}
PyDoc_STRVAR(to01_doc,
-"to01() -> string\n\
+"to01() -> str\n\
\n\
Return a string containing '0's and '1's, representing the bits in the\n\
bitarray object.\n\
@@ -1653,7 +1717,7 @@ static PyObject *
bitarray_unpack(bitarrayobject *self, PyObject *args, PyObject *kwds)
{
char zero = 0x00, one = 0xff;
- static char* kwlist[] = {"zero", "one", NULL};
+ static char *kwlist[] = {"zero", "one", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|cc:unpack", kwlist,
&zero, &one))
@@ -1665,61 +1729,61 @@ bitarray_unpack(bitarrayobject *self, PyObject *args, PyObject *kwds)
PyDoc_STRVAR(unpack_doc,
"unpack(zero=b'\\x00', one=b'\\xff') -> bytes\n\
\n\
-Return a byte string containing one character for each bit in the bitarray,\n\
-using the specified mapping.\n\
-See also the pack method.");
+Return bytes containing one character for each bit in the bitarray,\n\
+using the specified mapping.");
static PyObject *
-bitarray_pack(bitarrayobject *self, PyObject *string)
+bitarray_pack(bitarrayobject *self, PyObject *bytes)
{
- if (!PyString_Check(string)) {
- PyErr_SetString(PyExc_TypeError, "byte string expected");
+ if (!PyBytes_Check(bytes)) {
+ PyErr_SetString(PyExc_TypeError, "bytes expected");
return NULL;
}
- if (extend_string(self, string, STR_RAW) < 0)
+ if (extend_bytes(self, bytes, BYTES_RAW) < 0)
return NULL;
Py_RETURN_NONE;
}
PyDoc_STRVAR(pack_doc,
-"pack(bytes)\n\
+"pack(bytes, /)\n\
\n\
-Extend the bitarray from a byte string, where each characters corresponds to\n\
-a single bit. The character b'\\x00' maps to bit 0 and all other characters\n\
-map to bit 1.\n\
+Extend the bitarray from bytes, where each byte corresponds to a single\n\
+bit. The byte `b'\\x00'` maps to bit 0 and all other characters map to\n\
+bit 1.\n\
This method, as well as the unpack method, are meant for efficient\n\
transfer of data between bitarray objects to other python objects\n\
-(for example NumPy's ndarray object) which have a different view of memory.");
+(for example NumPy's ndarray object) which have a different memory view.");
static PyObject *
bitarray_repr(bitarrayobject *self)
{
- PyObject *string;
+ PyObject *bytes;
+ PyObject *unpacked;
#ifdef IS_PY3K
PyObject *decoded;
#endif
if (self->nbits == 0) {
- string = PyString_FromString("bitarray()");
- if (string == NULL)
- return NULL;
+ bytes = PyBytes_FromString("bitarray()");
}
else {
- string = PyString_FromString("bitarray(\'");
- if (string == NULL)
+ bytes = PyBytes_FromString("bitarray(\'");
+ unpacked = unpack(self, '0', '1');
+ if (unpacked == NULL)
return NULL;
- PyString_ConcatAndDel(&string, unpack(self, '0', '1'));
- PyString_ConcatAndDel(&string, PyString_FromString("\')"));
+ PyBytes_ConcatAndDel(&bytes, unpacked);
+ PyBytes_ConcatAndDel(&bytes, PyBytes_FromString("\')"));
}
#ifdef IS_PY3K
- decoded = PyUnicode_FromEncodedObject(string, NULL, NULL);
- Py_DECREF(string);
- string = decoded;
+ decoded = PyUnicode_FromEncodedObject(bytes, NULL, NULL);
+ Py_DECREF(bytes);
+ return decoded;
+#else
+ return bytes; /* really a string in Python 2 */
#endif
- return string;
}
@@ -1732,13 +1796,7 @@ bitarray_insert(bitarrayobject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "LO:insert", &i, &v))
return NULL;
- if (i < 0) {
- i += self->nbits;
- if (i < 0)
- i = 0;
- }
- if (i > self->nbits)
- i = self->nbits;
+ normalize_index(self->nbits, &i);
if (insert_n(self, i, 1) < 0)
return NULL;
@@ -1748,9 +1806,9 @@ bitarray_insert(bitarrayobject *self, PyObject *args)
}
PyDoc_STRVAR(insert_doc,
-"insert(i, item)\n\
+"insert(index, value, /)\n\
\n\
-Insert bool(item) into the bitarray before position i.");
+Insert `bool(value)` into the bitarray before index.");
static PyObject *
@@ -1781,10 +1839,10 @@ bitarray_pop(bitarrayobject *self, PyObject *args)
}
PyDoc_STRVAR(pop_doc,
-"pop([i]) -> item\n\
+"pop(index=-1, /) -> item\n\
\n\
Return the i-th (default last) element and delete it from the bitarray.\n\
-Raises IndexError if bitarray is empty or index is out of range.");
+Raises `IndexError` if bitarray is empty or index is out of range.");
static PyObject *
@@ -1797,7 +1855,7 @@ bitarray_remove(bitarrayobject *self, PyObject *v)
if (vi < 0)
return NULL;
- i = findfirst(self, vi, 0, -1);
+ i = findfirst(self, vi, 0, self->nbits);
if (i < 0) {
PyErr_SetString(PyExc_ValueError, "remove(x): x not in bitarray");
return NULL;
@@ -1808,10 +1866,10 @@ bitarray_remove(bitarrayobject *self, PyObject *v)
}
PyDoc_STRVAR(remove_doc,
-"remove(item)\n\
+"remove(value, /)\n\
\n\
-Remove the first occurrence of bool(item) in the bitarray.\n\
-Raises ValueError if item is not present.");
+Remove the first occurrence of `bool(value)` in the bitarray.\n\
+Raises `ValueError` if item is not present.");
/* --------- special methods ----------- */
@@ -2097,12 +2155,43 @@ BITWISE_IFUNC(xor)
/******************* variable length encoding and decoding ***************/
+static int
+check_codedict(PyObject *codedict)
+{
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+
+ if (!PyDict_Check(codedict)) {
+ PyErr_SetString(PyExc_TypeError, "dict expected");
+ return -1;
+ }
+ if (PyDict_Size(codedict) == 0) {
+ PyErr_SetString(PyExc_ValueError, "prefix code dict empty");
+ return -1;
+ }
+ while (PyDict_Next(codedict, &pos, &key, &value)) {
+ if (!bitarray_Check(value)) {
+ PyErr_SetString(PyExc_TypeError,
+ "bitarray expected for dict value");
+ return -1;
+ }
+ if (((bitarrayobject *) value)->nbits == 0) {
+ PyErr_SetString(PyExc_ValueError, "non-empty bitarray expected");
+ return -1;
+ }
+ }
+ return 0;
+}
+
static PyObject *
bitarray_encode(bitarrayobject *self, PyObject *args)
{
PyObject *codedict, *iterable, *iter, *symbol, *bits;
- if (!PyArg_ParseTuple(args, "OO:_encode", &codedict, &iterable))
+ if (!PyArg_ParseTuple(args, "OO:encode", &codedict, &iterable))
+ return NULL;
+
+ if (check_codedict(codedict) < 0)
return NULL;
iter = PyObject_GetIter(iterable);
@@ -2115,7 +2204,8 @@ bitarray_encode(bitarrayobject *self, PyObject *args)
bits = PyDict_GetItem(codedict, symbol);
Py_DECREF(symbol);
if (bits == NULL) {
- PyErr_SetString(PyExc_ValueError, "symbol not in prefix code");
+ PyErr_SetString(PyExc_ValueError,
+ "symbol not defined in prefix code");
goto error;
}
if (extend_bitarray(self, (bitarrayobject *) bits) < 0)
@@ -2131,16 +2221,18 @@ error:
}
PyDoc_STRVAR(encode_doc,
-"_encode(code, iterable)\n\
+"encode(code, iterable, /)\n\
\n\
-like the encode method without code checking");
+Given a prefix code (a dict mapping symbols to bitarrays),\n\
+iterate over the iterable object with symbols, and extend the bitarray\n\
+with the corresponding bitarray for each symbols.");
-/* Binary Tree definition */
+/* Binary tree definition */
typedef struct _bin_node
{
- PyObject *symbol;
struct _bin_node *child[2];
+ PyObject *symbol;
} binode;
@@ -2149,39 +2241,44 @@ new_binode(void)
{
binode *nd;
- nd = PyMem_Malloc(sizeof *nd);
+ nd = (binode *) PyMem_Malloc(sizeof(binode));
if (nd == NULL) {
PyErr_NoMemory();
return NULL;
}
- nd->symbol = NULL;
nd->child[0] = NULL;
nd->child[1] = NULL;
+ nd->symbol = NULL;
return nd;
}
static void
-delete_binode_tree(binode *root)
+delete_binode_tree(binode *tree)
{
- if (root == NULL)
+ if (tree == NULL)
return;
- delete_binode_tree(root->child[0]);
- delete_binode_tree(root->child[1]);
- PyMem_Free(root);
+ delete_binode_tree(tree->child[0]);
+ delete_binode_tree(tree->child[1]);
+ PyMem_Free(tree);
}
static int
-insert_symbol(binode *root, bitarrayobject *self, PyObject *symbol)
+insert_symbol(binode *tree, bitarrayobject *ba, PyObject *symbol)
{
- binode *nd = root, *prev;
+ binode *nd = tree, *prev;
Py_ssize_t i;
int k;
- for (i = 0; i < self->nbits; i++) {
- k = GETBIT(self, i);
+ for (i = 0; i < ba->nbits; i++) {
+ k = GETBIT(ba, i);
prev = nd;
nd = nd->child[k];
+
+ /* we cannot have already a symbol when branching to the new leaf */
+ if (nd && nd->symbol)
+ goto ambiguity;
+
if (!nd) {
nd = new_binode();
if (nd == NULL)
@@ -2189,43 +2286,52 @@ insert_symbol(binode *root, bitarrayobject *self, PyObject *symbol)
prev->child[k] = nd;
}
}
+ /* the new leaf node cannot already have a symbol or children */
+ if (nd->symbol || nd->child[0] || nd->child[1])
+ goto ambiguity;
- if (nd->symbol) {
- PyErr_SetString(PyExc_ValueError, "prefix code ambiguous");
- return -1;
- }
nd->symbol = symbol;
return 0;
+
+ ambiguity:
+ PyErr_SetString(PyExc_ValueError, "prefix code ambiguous");
+ return -1;
}
static binode *
make_tree(PyObject *codedict)
{
- binode *root;
+ binode *tree;
PyObject *symbol, *array;
Py_ssize_t pos = 0;
- root = new_binode();
- if (root == NULL)
+ tree = new_binode();
+ if (tree == NULL)
return NULL;
while (PyDict_Next(codedict, &pos, &symbol, &array)) {
- if (insert_symbol(root, (bitarrayobject *) array, symbol) < 0) {
- delete_binode_tree(root);
+ if (insert_symbol(tree, (bitarrayobject *) array, symbol) < 0) {
+ delete_binode_tree(tree);
return NULL;
}
}
- return root;
+ return tree;
}
+/*
+ Traverse tree using the branches corresponding to the bitarray `ba`,
+ starting at *indexp. Return the symbol at the leaf node, or NULL
+ when the end of the bitarray has been reached, or on error (in which
+ case the appropriate PyErr_SetString is set.
+*/
static PyObject *
-tree_traverse(bitarrayobject *self, idx_t *indexp, binode *tree)
+traverse_tree(binode *tree, bitarrayobject *ba, idx_t *indexp)
{
binode *nd = tree;
int k;
- while (*indexp < self->nbits) {
- k = GETBIT(self, *indexp);
+ while (*indexp < ba->nbits) {
+ k = GETBIT(ba, *indexp);
(*indexp)++;
nd = nd->child[k];
if (nd == NULL) {
@@ -2250,6 +2356,9 @@ bitarray_decode(bitarrayobject *self, PyObject *codedict)
Py_ssize_t i;
int k;
+ if (check_codedict(codedict) < 0)
+ return NULL;
+
tree = make_tree(codedict);
if (tree == NULL || PyErr_Occurred())
return NULL;
@@ -2260,6 +2369,7 @@ bitarray_decode(bitarrayobject *self, PyObject *codedict)
delete_binode_tree(tree);
return NULL;
}
+ /* traverse tree (just like above) */
for (i = 0; i < self->nbits; i++) {
k = GETBIT(self, i);
nd = nd->child[k];
@@ -2288,10 +2398,10 @@ error:
}
PyDoc_STRVAR(decode_doc,
-"_decode(codedict) -> list\n\
+"decode(code, /) -> list\n\
\n\
-Given a code dictionary, decode the content of the bitarray and return\n\
-the list of symbols.");
+Given a prefix code (a dict mapping symbols to bitarrays),\n\
+decode the content of the bitarray and return it as a list of symbols.");
/*********************** (Bitarray) Decode Iterator *********************/
@@ -2316,6 +2426,9 @@ bitarray_iterdecode(bitarrayobject *self, PyObject *codedict)
decodeiterobject *it; /* iterator to be returned */
binode *tree;
+ if (check_codedict(codedict) < 0)
+ return NULL;
+
tree = make_tree(codedict);
if (tree == NULL || PyErr_Occurred())
return NULL;
@@ -2334,10 +2447,11 @@ bitarray_iterdecode(bitarrayobject *self, PyObject *codedict)
}
PyDoc_STRVAR(iterdecode_doc,
-"_iterdecode(codedict) -> iterator\n\
+"iterdecode(code, /) -> iterator\n\
\n\
-Given a code dictionary, decode the content of the bitarray and iterate\n\
-over the represented symbols.");
+Given a prefix code (a dict mapping symbols to bitarrays),\n\
+decode the content of the bitarray and return an iterator over\n\
+the symbols.");
static PyObject *
decodeiter_next(decodeiterobject *it)
@@ -2345,7 +2459,7 @@ decodeiter_next(decodeiterobject *it)
PyObject *symbol;
assert(DecodeIter_Check(it));
- symbol = tree_traverse(it->bao, &(it->index), it->tree);
+ symbol = traverse_tree(it->tree, it->bao, &(it->index));
if (symbol == NULL) /* stop iteration OR error occured */
return NULL;
Py_INCREF(symbol);
@@ -2370,7 +2484,7 @@ decodeiter_traverse(decodeiterobject *it, visitproc visit, void *arg)
static PyTypeObject DecodeIter_Type = {
#ifdef IS_PY3K
- PyVarObject_HEAD_INIT(&DecodeIter_Type, 0)
+ PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
@@ -2449,7 +2563,7 @@ bitarray_itersearch(bitarrayobject *self, PyObject *x)
}
PyDoc_STRVAR(itersearch_doc,
-"itersearch(bitarray) -> iterator\n\
+"itersearch(bitarray, /) -> iterator\n\
\n\
Searches for the given a bitarray in self, and return an iterator over\n\
the start positions where bitarray matches self.");
@@ -2485,7 +2599,7 @@ searchiter_traverse(searchiterobject *it, visitproc visit, void *arg)
static PyTypeObject SearchIter_Type = {
#ifdef IS_PY3K
- PyVarObject_HEAD_INIT(&SearchIter_Type, 0)
+ PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
@@ -2538,11 +2652,11 @@ bitarray_methods[] = {
copy_doc},
{"count", (PyCFunction) bitarray_count, METH_VARARGS,
count_doc},
- {"_decode", (PyCFunction) bitarray_decode, METH_O,
+ {"decode", (PyCFunction) bitarray_decode, METH_O,
decode_doc},
- {"_iterdecode", (PyCFunction) bitarray_iterdecode, METH_O,
+ {"iterdecode", (PyCFunction) bitarray_iterdecode, METH_O,
iterdecode_doc},
- {"_encode", (PyCFunction) bitarray_encode, METH_VARARGS,
+ {"encode", (PyCFunction) bitarray_encode, METH_VARARGS,
encode_doc},
{"endian", (PyCFunction) bitarray_endian, METH_NOARGS,
endian_doc},
@@ -2633,7 +2747,7 @@ bitarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject *initial = NULL;
char *endian_str = NULL;
int endian;
- static char* kwlist[] = {"initial", "endian", NULL};
+ static char *kwlist[] = {"initial", "endian", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds,
"|Os:bitarray", kwlist, &initial, &endian_str))
@@ -2684,16 +2798,16 @@ bitarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return a;
}
- /* string */
- if (PyString_Check(initial)) {
+ /* bytes */
+ if (PyBytes_Check(initial)) {
Py_ssize_t strlen;
char *str;
- strlen = PyString_Size(initial);
+ strlen = PyBytes_Size(initial);
if (strlen == 0) /* empty string */
return newbitarrayobject(type, 0, endian);
- str = PyString_AsString(initial);
+ str = PyBytes_AsString(initial);
if (0 <= str[0] && str[0] < 8) {
/* when the first character is smaller than 8, it indicates the
number of unused bits at the end, and rest of the bytes
@@ -2712,6 +2826,16 @@ bitarray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
}
+#define CHECK_TYPE(type) \
+ if (Py ## type ## _Check(initial)) { \
+ PyErr_SetString(PyExc_TypeError, \
+ "cannot create bitarray from " #type " object"); \
+ return NULL; \
+ }
+CHECK_TYPE(Float)
+CHECK_TYPE(Complex)
+#undef CHECK_TYPE
+
/* leave remaining type dispatch to the extend method */
a = newbitarrayobject(type, 0, endian);
if (a == NULL)
@@ -2849,7 +2973,7 @@ bitarrayiter_traverse(bitarrayiterobject *it, visitproc visit, void *arg)
static PyTypeObject BitarrayIter_Type = {
#ifdef IS_PY3K
- PyVarObject_HEAD_INIT(&BitarrayIter_Type, 0)
+ PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
@@ -2887,7 +3011,7 @@ static PyTypeObject BitarrayIter_Type = {
/********************* Bitarray Buffer Interface ************************/
#ifdef WITH_BUFFER
-#if PY_MAJOR_VERSION == 2
+#if PY_MAJOR_VERSION == 2 /* old buffer protocol */
static Py_ssize_t
bitarray_buffer_getreadbuf(bitarrayobject *self,
Py_ssize_t index, const void **ptr)
@@ -2976,7 +3100,7 @@ static PyBufferProcs bitarray_as_buffer = {
static PyTypeObject Bitarraytype = {
#ifdef IS_PY3K
- PyVarObject_HEAD_INIT(&Bitarraytype, 0)
+ PyVarObject_HEAD_INIT(NULL, 0)
#else
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
@@ -2994,7 +3118,7 @@ static PyTypeObject Bitarraytype = {
0, /* tp_as_number*/
0, /* tp_as_sequence */
0, /* tp_as_mapping */
- 0, /* tp_hash */
+ PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
@@ -3066,11 +3190,12 @@ bitdiff(PyObject *self, PyObject *args)
}
PyDoc_STRVAR(bitdiff_doc,
-"bitdiff(a, b) -> int\n\
+"bitdiff(a, b, /) -> int\n\
\n\
Return the difference between two bitarrays a and b.\n\
This is function does the same as (a ^ b).count(), but is more memory\n\
-efficient, as no intermediate bitarray object gets created");
+efficient, as no intermediate bitarray object gets created.\n\
+Deprecated since version 1.2.0, use `bitarray.util.count_xor()` instead.");
static PyObject *
@@ -3085,14 +3210,14 @@ bits2bytes(PyObject *self, PyObject *v)
if (getIndex(v, &n) < 0)
return NULL;
if (n < 0) {
- PyErr_SetString(PyExc_ValueError, "positive value expected");
+ PyErr_SetString(PyExc_ValueError, "non-negative integer expected");
return NULL;
}
return PyLong_FromLongLong(BYTES(n));
}
PyDoc_STRVAR(bits2bytes_doc,
-"bits2bytes(n) -> int\n\
+"bits2bytes(n, /) -> int\n\
\n\
Return the number of bytes necessary to store n bits.");
@@ -3117,7 +3242,12 @@ tuple(sizeof(void *),\n\
sizeof(idx_t),\n\
PY_SSIZE_T_MAX)");
-
+/*
+ In retrospect, I wish I had never added any modules functions here.
+ These, and possibly many others should be part of a separate utility
+ module. Anyway, at this point (2019) it is too late to remove them,
+ so I will just leave them here, but not any new ones.
+*/
static PyMethodDef module_functions[] = {
{"bitdiff", (PyCFunction) bitdiff, METH_VARARGS, bitdiff_doc },
{"bits2bytes", (PyCFunction) bits2bytes, METH_O, bits2bytes_doc},
diff --git a/shell/ext-py/bitarray-1.2.1/bitarray/_util.c b/shell/ext-py/bitarray-1.2.1/bitarray/_util.c
new file mode 100644
index 0000000..5ed5920
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/bitarray/_util.c
@@ -0,0 +1,422 @@
+/*
+ Copyright (c) 2019, Ilan Schnell
+ bitarray is published under the PSF license.
+
+ This file contains the C implementation of some useful utility functions.
+
+ Author: Ilan Schnell
+*/
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+
+#if PY_MAJOR_VERSION >= 3
+#define IS_PY3K
+#endif
+
+#ifdef STDC_HEADERS
+#include <stddef.h>
+#else /* !STDC_HEADERS */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h> /* For size_t */
+#endif /* HAVE_SYS_TYPES_H */
+#endif /* !STDC_HEADERS */
+
+
+typedef long long int idx_t;
+
+typedef struct {
+ PyObject_VAR_HEAD
+ char *ob_item;
+ Py_ssize_t allocated; /* how many bytes allocated */
+ idx_t nbits; /* length of bitarray, i.e. elements */
+ int endian; /* bit endianness of bitarray */
+ int ob_exports; /* how many buffer exports */
+ PyObject *weakreflist; /* list of weak references */
+} bitarrayobject;
+
+#define BITS(bytes) ((idx_t) (bytes) << 3)
+
+#define BYTES(bits) (((bits) == 0) ? 0 : (((bits) - 1) / 8 + 1))
+
+#define BITMASK(endian, i) (((char) 1) << ((endian) ? (7 - (i)%8) : (i)%8))
+
+/* ------------ low level access to bits in bitarrayobject ------------- */
+
+#ifndef NDEBUG
+static int GETBIT(bitarrayobject *self, idx_t i) {
+ assert(0 <= i && i < self->nbits);
+ return ((self)->ob_item[(i) / 8] & BITMASK((self)->endian, i) ? 1 : 0);
+}
+#else
+#define GETBIT(self, i) \
+ ((self)->ob_item[(i) / 8] & BITMASK((self)->endian, i) ? 1 : 0)
+#endif
+
+static void
+setbit(bitarrayobject *self, idx_t i, int bit)
+{
+ char *cp, mask;
+
+ assert(0 <= i && i < BITS(Py_SIZE(self)));
+ mask = BITMASK(self->endian, i);
+ cp = self->ob_item + i / 8;
+ if (bit)
+ *cp |= mask;
+ else
+ *cp &= ~mask;
+}
+
+/* set using the Python module function _set_babt() */
+static PyObject *bitarray_basetype = NULL;
+
+/* return 1 if obj is a bitarray, 0 otherwise */
+static int
+bitarray_Check(PyObject *obj)
+{
+ if (bitarray_basetype == NULL) /* fallback */
+ return PyObject_HasAttrString(obj, "endian");
+ return PyObject_IsInstance(obj, bitarray_basetype);
+}
+
+static void
+setunused(bitarrayobject *self)
+{
+ const idx_t n = BITS(Py_SIZE(self));
+ idx_t i;
+
+ for (i = self->nbits; i < n; i++)
+ setbit(self, i, 0);
+}
+
+static int bitcount_lookup[256] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
+};
+
+/* return the smallest index i for which a.count(1, 0, i) == n, or when
+ n exceeds the total count return -1 */
+static idx_t
+count_to_n(bitarrayobject *a, idx_t n)
+{
+ idx_t i = 0, j = 0, m; /* i is the index, j the total count up to i */
+ Py_ssize_t block_start, block_stop, k;
+ unsigned char c;
+
+ if (n == 0)
+ return 0;
+
+#define BLOCK_BITS 8192
+ /* by counting big blocks we save comparisons */
+ while (i + BLOCK_BITS < a->nbits) {
+ m = 0;
+ assert(i % 8 == 0);
+ block_start = (Py_ssize_t) (i / 8);
+ block_stop = block_start + (BLOCK_BITS / 8);
+ for (k = block_start; k < block_stop; k++) {
+ assert(k < Py_SIZE(a));
+ c = a->ob_item[k];
+ m += bitcount_lookup[c];
+ }
+ if (j + m >= n)
+ break;
+ j += m;
+ i += BLOCK_BITS;
+ }
+#undef BLOCK_SIZE
+
+ while (i + 8 < a->nbits) {
+ k = (Py_ssize_t) (i / 8);
+ assert(k < Py_SIZE(a));
+ c = a->ob_item[k];
+ m = bitcount_lookup[c];
+ if (j + m >= n)
+ break;
+ j += m;
+ i += 8;
+ }
+
+ while (j < n && i < a->nbits ) {
+ j += GETBIT(a, i);
+ i++;
+ }
+ if (j < n)
+ return -1;
+
+ return i;
+}
+
+/* return index of last occurrence of vi, -1 when x is not in found. */
+static idx_t
+find_last(bitarrayobject *self, int vi)
+{
+ Py_ssize_t j;
+ idx_t i;
+ char c;
+
+ if (self->nbits == 0)
+ return -1;
+
+ /* search within top byte */
+ for (i = self->nbits - 1; i >= BITS(self->nbits / 8); i--)
+ if (GETBIT(self, i) == vi)
+ return i;
+
+ if (i < 0) /* not found within top byte */
+ return -1;
+ assert((i + 1) % 8 == 0);
+
+ /* seraching for 1 means: break when byte is not 0x00
+ searching for 0 means: break when byte is not 0xff */
+ c = vi ? 0x00 : 0xff;
+
+ /* skip ahead by checking whole bytes */
+ for (j = BYTES(i) - 1; j >= 0; j--)
+ if (c ^ self->ob_item[j])
+ break;
+
+ if (j < 0) /* not found within bytes */
+ return -1;
+
+ /* search within byte found */
+ for (i = BITS(j + 1) - 1; i >= BITS(j); i--)
+ if (GETBIT(self, i) == vi)
+ return i;
+
+ return -1;
+}
+
+/*************************** Module functions **********************/
+
+static PyObject *
+count_n(PyObject *self, PyObject *args)
+{
+ PyObject *a;
+ idx_t n, i;
+
+ if (!PyArg_ParseTuple(args, "OL:count_n", &a, &n))
+ return NULL;
+
+ if (!bitarray_Check(a)) {
+ PyErr_SetString(PyExc_TypeError, "bitarray object expected");
+ return NULL;
+ }
+ if (n < 0) {
+ PyErr_SetString(PyExc_ValueError, "non-negative integer expected");
+ return NULL;
+ }
+#define aa ((bitarrayobject *) a)
+ if (n > aa->nbits) {
+ PyErr_SetString(PyExc_ValueError, "n larger than bitarray size");
+ return NULL;
+ }
+ i = count_to_n(aa, n); /* do actual work here */
+#undef aa
+ if (i < 0) {
+ PyErr_SetString(PyExc_ValueError, "n exceeds total count");
+ return NULL;
+ }
+ return PyLong_FromLongLong(i);
+}
+
+PyDoc_STRVAR(count_n_doc,
+"count_n(a, n, /) -> int\n\
+\n\
+Find the smallest index `i` for which `a[:i].count() == n`.\n\
+Raises `ValueError`, when n exceeds the `a.count()`.");
+
+
+static PyObject *
+r_index(PyObject *self, PyObject *args)
+{
+ PyObject *a, *x = Py_True;
+ idx_t i;
+ long vi;
+
+ if (!PyArg_ParseTuple(args, "O|O:rindex", &a, &x))
+ return NULL;
+
+ if (!bitarray_Check(a)) {
+ PyErr_SetString(PyExc_TypeError, "bitarray object expected");
+ return NULL;
+ }
+ vi = PyObject_IsTrue(x);
+ if (vi < 0)
+ return NULL;
+
+ i = find_last((bitarrayobject *) a, vi);
+ if (i < 0) {
+ PyErr_SetString(PyExc_ValueError, "index(x): x not in bitarray");
+ return NULL;
+ }
+ return PyLong_FromLongLong(i);
+}
+
+PyDoc_STRVAR(rindex_doc,
+"rindex(bitarray, value=True, /) -> int\n\
+\n\
+Return the rightmost index of `bool(value)` in bitarray.\n\
+Raises `ValueError` if the value is not present.");
+
+
+enum kernel_type {
+ KERN_cand, /* count bitwise and -> int */
+ KERN_cor, /* count bitwise or -> int */
+ KERN_cxor, /* count bitwise xor -> int */
+ KERN_subset, /* is subset -> bool */
+};
+
+static PyObject *
+two_bitarray_func(PyObject *args, enum kernel_type kern, char *format)
+{
+ PyObject *a, *b;
+ Py_ssize_t i;
+ idx_t res = 0;
+ unsigned char c;
+
+ if (!PyArg_ParseTuple(args, format, &a, &b))
+ return NULL;
+ if (!(bitarray_Check(a) && bitarray_Check(b))) {
+ PyErr_SetString(PyExc_TypeError, "bitarray object expected");
+ return NULL;
+ }
+#define aa ((bitarrayobject *) a)
+#define bb ((bitarrayobject *) b)
+ if (aa->nbits != bb->nbits) {
+ PyErr_SetString(PyExc_ValueError,
+ "bitarrays of equal length expected");
+ return NULL;
+ }
+ if (aa->endian != bb->endian) {
+ PyErr_SetString(PyExc_ValueError,
+ "bitarrays of equal endianness expected");
+ return NULL;
+ }
+ setunused(aa);
+ setunused(bb);
+ switch (kern) {
+ case KERN_cand:
+ for (i = 0; i < Py_SIZE(aa); i++) {
+ c = aa->ob_item[i] & bb->ob_item[i];
+ res += bitcount_lookup[c];
+ }
+ break;
+ case KERN_cor:
+ for (i = 0; i < Py_SIZE(aa); i++) {
+ c = aa->ob_item[i] | bb->ob_item[i];
+ res += bitcount_lookup[c];
+ }
+ break;
+ case KERN_cxor:
+ for (i = 0; i < Py_SIZE(aa); i++) {
+ c = aa->ob_item[i] ^ bb->ob_item[i];
+ res += bitcount_lookup[c];
+ }
+ break;
+ case KERN_subset:
+ for (i = 0; i < Py_SIZE(aa); i++)
+ if ((aa->ob_item[i] & bb->ob_item[i]) != aa->ob_item[i])
+ Py_RETURN_FALSE;
+ Py_RETURN_TRUE;
+ default: /* should never happen */
+ return NULL;
+ }
+#undef aa
+#undef bb
+ return PyLong_FromLongLong(res);
+}
+
+#define COUNT_FUNC(oper, ochar) \
+static PyObject * \
+count_ ## oper (bitarrayobject *self, PyObject *args) \
+{ \
+ return two_bitarray_func(args, KERN_c ## oper, "OO:count_" #oper); \
+} \
+PyDoc_STRVAR(count_ ## oper ## _doc, \
+"count_" #oper "(a, b, /) -> int\n\
+\n\
+Returns `(a " ochar " b).count()`, but is more memory efficient,\n\
+as no intermediate bitarray object gets created.")
+
+COUNT_FUNC(and, "&");
+COUNT_FUNC(or, "|");
+COUNT_FUNC(xor, "^");
+
+
+static PyObject *
+subset(PyObject *self, PyObject *args)
+{
+ return two_bitarray_func(args, KERN_subset, "OO:subset");
+}
+
+PyDoc_STRVAR(subset_doc,
+"subset(a, b, /) -> bool\n\
+\n\
+Return True if bitarray `a` is a subset of bitarray `b` (False otherwise).\n\
+`subset(a, b)` is equivalent to `(a & b).count() == a.count()` but is more\n\
+efficient since we can stop as soon as one mismatch is found, and no\n\
+intermediate bitarray object gets created.");
+
+
+/* set bitarray_basetype (babt) */
+static PyObject *
+set_babt(PyObject *self, PyObject *obj)
+{
+ bitarray_basetype = obj;
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef module_functions[] = {
+ {"count_n", (PyCFunction) count_n, METH_VARARGS, count_n_doc},
+ {"rindex", (PyCFunction) r_index, METH_VARARGS, rindex_doc},
+ {"count_and", (PyCFunction) count_and, METH_VARARGS, count_and_doc},
+ {"count_or", (PyCFunction) count_or, METH_VARARGS, count_or_doc},
+ {"count_xor", (PyCFunction) count_xor, METH_VARARGS, count_xor_doc},
+ {"subset", (PyCFunction) subset, METH_VARARGS, subset_doc},
+ {"_set_babt", (PyCFunction) set_babt, METH_O, ""},
+ {NULL, NULL} /* sentinel */
+};
+
+/*********************** Install Module **************************/
+
+#ifdef IS_PY3K
+static PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT, "_util", 0, -1, module_functions,
+};
+PyMODINIT_FUNC
+PyInit__util(void)
+#else
+PyMODINIT_FUNC
+init_util(void)
+#endif
+{
+ PyObject *m;
+
+#ifdef IS_PY3K
+ m = PyModule_Create(&moduledef);
+ if (m == NULL)
+ return NULL;
+#else
+ m = Py_InitModule3("_util", module_functions, 0);
+ if (m == NULL)
+ return;
+#endif
+
+#ifdef IS_PY3K
+ return m;
+#endif
+}
diff --git a/shell/ext-py/bitarray-0.9.0/bitarray/test_bitarray.py b/shell/ext-py/bitarray-1.2.1/bitarray/test_bitarray.py
similarity index 68%
rename from shell/ext-py/bitarray-0.9.0/bitarray/test_bitarray.py
rename to shell/ext-py/bitarray-1.2.1/bitarray/test_bitarray.py
index 3e66bff..93eb5ab 100644
--- a/shell/ext-py/bitarray-0.9.0/bitarray/test_bitarray.py
+++ b/shell/ext-py/bitarray-1.2.1/bitarray/test_bitarray.py
@@ -12,57 +12,65 @@ from random import randint
is_py3k = bool(sys.version_info[0] == 3)
+# imports needed inside tests
+import copy
+import pickle
+import itertools
+
+try:
+ import shelve, hashlib
+except ImportError:
+ shelve = hashlib = None
+
if is_py3k:
from io import StringIO
+ unicode = str
else:
from cStringIO import StringIO
-from bitarray import bitarray, bitdiff, bits2bytes, __version__
+from bitarray import (bitarray, frozenbitarray,
+ bitdiff, bits2bytes, __version__)
tests = []
-if sys.version_info[:2] < (2, 6):
- def next(x):
- return x.next()
-
-
-def to_bytes(s):
- if is_py3k:
- return bytes(s.encode('latin1'))
- elif sys.version_info[:2] >= (2, 6):
- return bytes(s)
- else:
- return s
-
class Util(object):
- def randombitarrays(self):
- for n in list(range(25)) + [randint(1000, 2000)]:
+ @staticmethod
+ def randombitarrays(start=1):
+ for n in list(range(start, 25)) + [randint(1000, 2000)]:
a = bitarray(endian=['little', 'big'][randint(0, 1)])
a.frombytes(os.urandom(bits2bytes(n)))
del a[n:]
yield a
- def randomlists(self):
+ @staticmethod
+ def randomlists():
for n in list(range(25)) + [randint(1000, 2000)]:
yield [bool(randint(0, 1)) for d in range(n)]
- def rndsliceidx(self, length):
+ @staticmethod
+ def rndsliceidx(length):
if randint(0, 1):
return None
else:
- return randint(-2 * length, 2 * length - 1)
+ return randint(-length-5, length+5)
- def slicelen(self, r, length):
- return getIndicesEx(r, length)[-1]
+ @staticmethod
+ def slicelen(s, length):
+ assert isinstance(s, slice)
+ start, stop, step = s.indices(length)
+ slicelength = (stop - start + (1 if step < 0 else -1)) // step + 1
+ if slicelength < 0:
+ slicelength = 0
+ return slicelength
def check_obj(self, a):
self.assertEqual(repr(type(a)), "<class 'bitarray.bitarray'>")
unused = 8 * a.buffer_info()[1] - len(a)
- self.assert_(0 <= unused < 8)
+ self.assertTrue(0 <= unused < 8)
self.assertEqual(unused, a.buffer_info()[3])
def assertEQUAL(self, a, b):
@@ -76,51 +84,9 @@ class Util(object):
return
self.assertRaises(StopIteration, it.next)
-
-def getIndicesEx(r, length):
- if not isinstance(r, slice):
- raise TypeError("slice object expected")
- start = r.start
- stop = r.stop
- step = r.step
- if r.step is None:
- step = 1
- else:
- if step == 0:
- raise ValueError("slice step cannot be zero")
-
- if step < 0:
- defstart = length - 1
- defstop = -1
- else:
- defstart = 0
- defstop = length
-
- if r.start is None:
- start = defstart
- else:
- if start < 0: start += length
- if start < 0: start = [0, -1][step < 0]
- if start >= length: start = [length, length - 1][step < 0]
-
- if r.stop is None:
- stop = defstop
- else:
- if stop < 0: stop += length
- if stop < 0: stop = -1
- if stop > length: stop = length
-
- if (step < 0 and stop >= length) or (step > 0 and start >= stop):
- slicelength = 0
- elif step < 0:
- slicelength = (stop - start + 1) / step + 1
- else:
- slicelength = (stop - start - 1) / step + 1
-
- if slicelength < 0:
- slicelength = 0
-
- return start, stop, step, slicelength
+ if sys.version_info[:2] == (2, 6):
+ def assertIsInstance(self, o, t):
+ self.assertTrue(isinstance(o, t))
# ---------------------------------------------------------------------------
@@ -150,6 +116,8 @@ class TestsModuleFunctions(unittest.TestCase, Util):
for arg in ['foo', [], None, {}]:
self.assertRaises(TypeError, bits2bytes, arg)
+ self.assertRaises(TypeError, bits2bytes, 187.0)
+ self.assertRaises(TypeError, bits2bytes, -4.0)
self.assertRaises(TypeError, bits2bytes)
self.assertRaises(TypeError, bits2bytes, 1, 2)
@@ -157,12 +125,11 @@ class TestsModuleFunctions(unittest.TestCase, Util):
self.assertRaises(ValueError, bits2bytes, -924)
self.assertEqual(bits2bytes(0), 0)
- for n in range(1, 1000):
+ for n in range(1, 100):
self.assertEqual(bits2bytes(n), (n - 1) // 8 + 1)
for n, m in [(0, 0), (1, 1), (2, 1), (7, 1), (8, 1), (9, 2),
(10, 2), (15, 2), (16, 2), (64, 8), (65, 9),
- (0, 0), (1, 1), (65, 9), (2**29, 2**26),
(2**31, 2**28), (2**32, 2**29), (2**34, 2**31),
(2**34+793, 2**31+100), (2**35-8, 2**32-1),
(2**62, 2**59), (2**63-8, 2**60-1)]:
@@ -185,11 +152,13 @@ class CreateObjectTests(unittest.TestCase, Util):
a = bitarray(endian='little')
a.fromstring('A')
self.assertEqual(a.endian(), 'little')
+ self.assertIsInstance(a.endian(), str)
self.check_obj(a)
b = bitarray(endian='big')
b.fromstring('A')
self.assertEqual(b.endian(), 'big')
+ self.assertIsInstance(a.endian(), str)
self.check_obj(b)
self.assertEqual(a.tostring(), b.tostring())
@@ -265,6 +234,13 @@ class CreateObjectTests(unittest.TestCase, Util):
self.assertEqual(a, bitarray(lst))
self.check_obj(a)
+ def test_iter3(self):
+ a = bitarray(itertools.repeat(False, 10))
+ self.assertEqual(a, bitarray(10 * '0'))
+ # Note that the through value of '0' is True: bool('0') -> True
+ a = bitarray(itertools.repeat('0', 10))
+ self.assertEqual(a, bitarray(10 * '1'))
+
def test_01(self):
a = bitarray('0010111')
self.assertEqual(a.tolist(), [0, 0, 1, 0, 1, 1, 1])
@@ -280,20 +256,20 @@ class CreateObjectTests(unittest.TestCase, Util):
self.assertRaises(ValueError, bitarray.__new__, bitarray, '01012100')
def test_rawbytes(self): # this representation is used for pickling
- for s, r in [('\x00', ''), ('\x07\xff', '1'), ('\x03\xff', '11111'),
- ('\x01\x87\xda', '10000111' '1101101')]:
- self.assertEqual(bitarray(to_bytes(s), endian='big'),
+ for s, r in [(b'\x00', ''), (b'\x07\xff', '1'), (b'\x03\xff', '11111'),
+ (b'\x01\x87\xda', '10000111' '1101101')]:
+ self.assertEqual(bitarray(s, endian='big'),
bitarray(r))
for i in range(1, 8):
self.assertRaises(ValueError, bitarray.__new__,
- bitarray, to_bytes(chr(i)))
+ bitarray, bytes(bytearray([i])))
def test_bitarray(self):
- for n in range(50):
+ for n in range(10):
a = bitarray(n)
b = bitarray(a)
- self.assert_(a is not b)
+ self.assertFalse(a is b)
self.assertEQUAL(a, b)
for end in ('little', 'big'):
@@ -330,19 +306,11 @@ tests.append(CreateObjectTests)
class ToObjectsTests(unittest.TestCase, Util):
- def test_int(self):
- a = bitarray()
- self.assertRaises(TypeError, int, a)
- if not is_py3k:
- self.assertRaises(TypeError, long, a)
-
- def test_float(self):
+ def test_numeric(self):
a = bitarray()
- self.assertRaises(TypeError, float, a)
-
- def test_complext(self):
- a = bitarray()
- self.assertRaises(TypeError, complex, a)
+ self.assertRaises(Exception, int, a)
+ self.assertRaises(Exception, float, a)
+ self.assertRaises(Exception, complex, a)
def test_list(self):
for a in self.randombitarrays():
@@ -357,7 +325,7 @@ tests.append(ToObjectsTests)
# ---------------------------------------------------------------------------
-class MetaDataTests(unittest.TestCase):
+class MetaDataTests(unittest.TestCase, Util):
def test_buffer_info1(self):
a = bitarray('0000111100001', endian='little')
@@ -367,23 +335,23 @@ class MetaDataTests(unittest.TestCase):
self.assertRaises(TypeError, a.buffer_info, 42)
bi = a.buffer_info()
- self.assert_(isinstance(bi, tuple))
+ self.assertIsInstance(bi, tuple)
self.assertEqual(len(bi), 5)
- self.assert_(isinstance(bi[0], int))
+ self.assertIsInstance(bi[0], int)
if is_py3k:
- self.assert_(isinstance(bi[1], int))
- self.assert_(isinstance(bi[2], str))
- self.assert_(isinstance(bi[3], int))
+ self.assertIsInstance(bi[1], int)
+ self.assertIsInstance(bi[2], str)
+ self.assertIsInstance(bi[3], int)
if is_py3k:
- self.assert_(isinstance(bi[4], int))
+ self.assertIsInstance(bi[4], int)
def test_buffer_info2(self):
for n in range(50):
bi = bitarray(n).buffer_info()
self.assertEqual(bi[1], bits2bytes(n))
self.assertEqual(bi[3] + n, 8 * bi[1])
- self.assert_(bi[4] >= bi[1])
+ self.assertTrue(bi[4] >= bi[1])
def test_buffer_info3(self):
a = bitarray(endian='little')
@@ -402,7 +370,7 @@ class MetaDataTests(unittest.TestCase):
def test_length(self):
- for n in range(1000):
+ for n in range(100):
a = bitarray(n)
self.assertEqual(len(a), n)
self.assertEqual(a.length(), n)
@@ -421,7 +389,6 @@ class SliceTests(unittest.TestCase, Util):
self.assertEqual(a[0], True)
self.assertRaises(IndexError, a.__getitem__, 1)
self.assertRaises(IndexError, a.__getitem__, -2)
-
a.append(False)
self.assertEqual(a[1], False)
self.assertRaises(IndexError, a.__getitem__, 2)
@@ -438,7 +405,7 @@ class SliceTests(unittest.TestCase, Util):
def test_getitem3(self):
a = bitarray('0100000100001')
self.assertEQUAL(a[:], a)
- self.assert_(a[:] is not a)
+ self.assertFalse(a[:] is a)
aa = a.tolist()
self.assertEQUAL(a[11:2:-3], bitarray(aa[11:2:-3]))
self.check_obj(a[:])
@@ -447,38 +414,33 @@ class SliceTests(unittest.TestCase, Util):
self.assertRaises(TypeError, a.__getitem__, (1, 2))
def test_getitem4(self):
- for a in self.randombitarrays():
+ for a in self.randombitarrays(start=1):
aa = a.tolist()
la = len(a)
- if la == 0: continue
for dum in range(10):
- step = self.rndsliceidx(la)
- if step == 0: step = None
- s = slice(self.rndsliceidx(la),
- self.rndsliceidx(la), step)
+ step = self.rndsliceidx(la) or None
+ s = slice(self.rndsliceidx(la), self.rndsliceidx(la), step)
self.assertEQUAL(a[s], bitarray(aa[s], endian=a.endian()))
def test_setitem1(self):
a = bitarray([False])
a[0] = 1
- self.assertEqual(a.tolist(), [True])
+ self.assertEqual(a, bitarray('1'))
a = bitarray(2)
a[0] = 0
a[1] = 1
- self.assertEqual(a.tolist(), [False, True])
+ self.assertEqual(a, bitarray('01'))
a[-1] = 0
a[-2] = 1
- self.assertEqual(a.tolist(), [True, False])
+ self.assertEqual(a, bitarray('10'))
self.assertRaises(IndexError, a.__setitem__, 2, True)
self.assertRaises(IndexError, a.__setitem__, -3, False)
def test_setitem2(self):
- for a in self.randombitarrays():
+ for a in self.randombitarrays(start=1):
la = len(a)
- if la == 0:
- continue
i = randint(0, la - 1)
aa = a.tolist()
ida = id(a)
@@ -504,61 +466,96 @@ class SliceTests(unittest.TestCase, Util):
self.assertEqual(a.tolist()[::-1], b.tolist())
def test_setitem3(self):
- a = bitarray(5 * [False])
+ a = bitarray('00000')
a[0] = 1
a[-2] = 1
self.assertEqual(a, bitarray('10010'))
- self.assertRaises(IndexError, a.__setitem__, 5, 'foo')
+ self.assertRaises(IndexError, a.__setitem__, 5, 'foo')
self.assertRaises(IndexError, a.__setitem__, -6, 'bar')
def test_setitem4(self):
- for a in self.randombitarrays():
+ for a in self.randombitarrays(start=1):
la = len(a)
- if la == 0: continue
- for dum in range(50):
- step = self.rndsliceidx(la)
- if step == 0: step = None
- s = slice(self.rndsliceidx(la),
- self.rndsliceidx(la), step)
- for b in self.randombitarrays():
- if len(b) == self.slicelen(s, len(a)) or step is None:
- c = bitarray(a)
- d = c
- c[s] = b
- self.assert_(c is d)
- self.check_obj(c)
- cc = a.tolist()
- cc[s] = b.tolist()
- self.assertEqual(c, bitarray(cc))
+ for dum in range(10):
+ step = self.rndsliceidx(la) or None
+ s = slice(self.rndsliceidx(la), self.rndsliceidx(la), step)
+ lb = randint(0, 10) if step is None else self.slicelen(s, la)
+ b = bitarray(lb)
+ c = bitarray(a)
+ c[s] = b
+ self.check_obj(c)
+ cc = a.tolist()
+ cc[s] = b.tolist()
+ self.assertEqual(c, bitarray(cc))
+ def test_setslice_to_bitarray(self):
+ a = bitarray('11111111' '1111')
+ a[2:6] = bitarray('0010')
+ self.assertEqual(a, bitarray('11001011' '1111'))
+ a.setall(0)
+ a[::2] = bitarray('111001')
+ self.assertEqual(a, bitarray('10101000' '0010'))
+ a.setall(0)
+ a[3:] = bitarray('111')
+ self.assertEqual(a, bitarray('000111'))
+ a = bitarray(12)
+ a.setall(0)
+ a[1:11:2] = bitarray('11101')
+ self.assertEqual(a, bitarray('01010100' '0100'))
+ a = bitarray(12)
+ a.setall(0)
+ a[:-6:-1] = bitarray('10111')
+ self.assertEqual(a, bitarray('00000001' '1101'))
+ a = bitarray('1111')
+ a[3:3] = bitarray('000') # insert
+ self.assertEqual(a, bitarray('1110001'))
+ a[2:5] = bitarray() # remove
+ self.assertEqual(a, bitarray('1101'))
+ a = bitarray('1111')
+ a[1:3] = bitarray('0000')
+ self.assertEqual(a, bitarray('100001'))
+ a[:] = bitarray('010') # replace all values
+ self.assertEqual(a, bitarray('010'))
def test_setslice_to_bool(self):
a = bitarray('11111111')
a[::2] = False
self.assertEqual(a, bitarray('01010101'))
- a[4::] = True
+ a[4::] = True # ^^^^
self.assertEqual(a, bitarray('01011111'))
- a[-2:] = False
+ a[-2:] = False # ^^
self.assertEqual(a, bitarray('01011100'))
- a[:2:] = True
+ a[:2:] = True # ^^
self.assertEqual(a, bitarray('11011100'))
- a[:] = True
+ a[:] = True # ^^^^^^^^
self.assertEqual(a, bitarray('11111111'))
+ a[2:5] = False # ^^^
+ self.assertEqual(a, bitarray('11000111'))
+ a[1::3] = False # ^ ^ ^
+ self.assertEqual(a, bitarray('10000110'))
+ a[1:6:2] = True # ^ ^ ^
+ self.assertEqual(a, bitarray('11010110'))
def test_setslice_to_int(self):
a = bitarray('11111111')
- a[::2] = 0
+ a[::2] = 0 # ^ ^ ^ ^
self.assertEqual(a, bitarray('01010101'))
- a[4::] = 1
+ a[4::] = 1 # ^^^^
self.assertEqual(a, bitarray('01011111'))
a.__setitem__(slice(-2, None, None), 0)
self.assertEqual(a, bitarray('01011100'))
+ self.assertRaises(ValueError, a.__setitem__, slice(None, None, 2), 3)
+ self.assertRaises(ValueError, a.__setitem__, slice(None, 2, None), -1)
- self.assertRaises(ValueError, a.__setitem__,
- slice(None, None, 2), 3)
- self.assertRaises(ValueError, a.__setitem__,
- slice(None, 2, None), -1)
-
+ def test_sieve(self): # Sieve of Eratosthenes
+ a = bitarray(50)
+ a.setall(1)
+ for i in range(2, 8):
+ if a[i]:
+ a[i*i::i] = 0
+ primes = [i for i in range(2, 50) if a[i]]
+ self.assertEqual(primes, [2, 3, 5, 7, 11, 13, 17, 19,
+ 23, 29, 31, 37, 41, 43, 47])
def test_delitem1(self):
a = bitarray('100110')
@@ -569,20 +566,25 @@ class SliceTests(unittest.TestCase, Util):
self.assertEqual(a, bitarray('100'))
self.assertRaises(IndexError, a.__delitem__, 3)
self.assertRaises(IndexError, a.__delitem__, -4)
+ a = bitarray('10101100' '10110')
+ del a[3:9] # ^^^^^ ^
+ self.assertEqual(a, bitarray('1010110'))
+ del a[::3] # ^ ^ ^
+ self.assertEqual(a, bitarray('0111'))
+ a = bitarray('10101100' '1011011')
+ del a[:-9:-2] # ^ ^ ^ ^
+ self.assertEqual(a, bitarray('10101100' '011'))
def test_delitem2(self):
- for a in self.randombitarrays():
+ for a in self.randombitarrays(start=1):
la = len(a)
- if la == 0: continue
- for dum in range(50):
- step = self.rndsliceidx(la)
- if step == 0: step = None
- s = slice(self.rndsliceidx(la),
- self.rndsliceidx(la), step)
+ for dum in range(10):
+ step = self.rndsliceidx(la) or None
+ s = slice(self.rndsliceidx(la), self.rndsliceidx(la), step)
c = bitarray(a)
d = c
del c[s]
- self.assert_(c is d)
+ self.assertTrue(c is d)
self.check_obj(c)
cc = a.tolist()
del cc[s]
@@ -597,7 +599,7 @@ class MiscTests(unittest.TestCase, Util):
def test_instancecheck(self):
a = bitarray('011')
- self.assertTrue(isinstance(a, bitarray))
+ self.assertIsInstance(a, bitarray)
self.assertFalse(isinstance(a, str))
def test_booleanness(self):
@@ -605,6 +607,15 @@ class MiscTests(unittest.TestCase, Util):
self.assertEqual(bool(bitarray('0')), True)
self.assertEqual(bool(bitarray('1')), True)
+ def test_to01(self):
+ a = bitarray()
+ self.assertEqual(a.to01(), '')
+ self.assertIsInstance(a.to01(), str)
+
+ a = bitarray('101')
+ self.assertEqual(a.to01(), '101')
+ self.assertIsInstance(a.to01(), str)
+
def test_iterate(self):
for lst in self.randomlists():
acc = []
@@ -635,7 +646,6 @@ class MiscTests(unittest.TestCase, Util):
def test_compare(self):
for a in self.randombitarrays():
aa = a.tolist()
-
for b in self.randombitarrays():
bb = b.tolist()
self.assertEqual(a == b, aa == bb)
@@ -657,28 +667,26 @@ class MiscTests(unittest.TestCase, Util):
def __getitem__(self, i):
return bitarray.__getitem__(self, i - self.offset)
- for a in self.randombitarrays():
- if len(a) == 0:
- continue
+ for a in self.randombitarrays(start=1):
b = ExaggeratingBitarray(a, 1234)
for i in range(len(a)):
self.assertEqual(a[i], b[i+1234])
def test_endianness1(self):
a = bitarray(endian='little')
- a.frombytes(to_bytes('\x01'))
+ a.frombytes(b'\x01')
self.assertEqual(a.to01(), '10000000')
b = bitarray(endian='little')
- b.frombytes(to_bytes('\x80'))
+ b.frombytes(b'\x80')
self.assertEqual(b.to01(), '00000001')
c = bitarray(endian='big')
- c.frombytes(to_bytes('\x80'))
+ c.frombytes(b'\x80')
self.assertEqual(c.to01(), '10000000')
d = bitarray(endian='big')
- d.frombytes(to_bytes('\x01'))
+ d.frombytes(b'\x01')
self.assertEqual(d.to01(), '00000001')
self.assertEqual(a, c)
@@ -688,29 +696,29 @@ class MiscTests(unittest.TestCase, Util):
a = bitarray(8, endian='little')
a.setall(False)
a[0] = True
- self.assertEqual(a.tobytes(), to_bytes('\x01'))
+ self.assertEqual(a.tobytes(), b'\x01')
a[1] = True
- self.assertEqual(a.tobytes(), to_bytes('\x03'))
- a.frombytes(to_bytes(' '))
- self.assertEqual(a.tobytes(), to_bytes('\x03 '))
+ self.assertEqual(a.tobytes(), b'\x03')
+ a.frombytes(b' ')
+ self.assertEqual(a.tobytes(), b'\x03 ')
self.assertEqual(a.to01(), '1100000000000100')
def test_endianness3(self):
a = bitarray(8, endian='big')
a.setall(False)
a[7] = True
- self.assertEqual(a.tobytes(), to_bytes('\x01'))
+ self.assertEqual(a.tobytes(), b'\x01')
a[6] = True
- self.assertEqual(a.tobytes(), to_bytes('\x03'))
- a.frombytes(to_bytes(' '))
- self.assertEqual(a.tobytes(), to_bytes('\x03 '))
+ self.assertEqual(a.tobytes(), b'\x03')
+ a.frombytes(b' ')
+ self.assertEqual(a.tobytes(), b'\x03 ')
self.assertEqual(a.to01(), '0000001100100000')
def test_endianness4(self):
a = bitarray('00100000', endian='big')
- self.assertEqual(a.tobytes(), to_bytes(' '))
+ self.assertEqual(a.tobytes(), b' ')
b = bitarray('00000100', endian='little')
- self.assertEqual(b.tobytes(), to_bytes(' '))
+ self.assertEqual(b.tobytes(), b' ')
self.assertNotEqual(a, b)
def test_endianness5(self):
@@ -720,27 +728,14 @@ class MiscTests(unittest.TestCase, Util):
self.assertEqual(a.tobytes(), b.tobytes())
def test_pickle(self):
- from pickle import loads, dumps
- for v in range(3):
- for a in self.randombitarrays():
- b = loads(dumps(a, v))
- self.assert_(b is not a)
- self.assertEQUAL(a, b)
-
- def test_cPickle(self):
- if is_py3k:
- return
for v in range(3):
- from cPickle import loads, dumps
for a in self.randombitarrays():
- b = loads(dumps(a, v))
- self.assert_(b is not a)
+ b = pickle.loads(pickle.dumps(a, v))
+ self.assertFalse(b is a)
self.assertEQUAL(a, b)
def test_overflow(self):
- from platform import architecture
-
- if architecture()[0] == '64bit':
+ if tuple.__itemsize__ == 8:
return
self.assertRaises(OverflowError, bitarray.__new__,
@@ -749,6 +744,35 @@ class MiscTests(unittest.TestCase, Util):
a = bitarray(10 ** 6)
self.assertRaises(OverflowError, a.__imul__, 17180)
+ def test_unicode1(self):
+ a = bitarray(unicode())
+ self.assertEqual(a, bitarray())
+
+ a = bitarray(unicode('111001'))
+ self.assertEqual(a, bitarray('111001'))
+
+ for a in self.randombitarrays():
+ b = bitarray(unicode(a.to01()))
+ self.assertEqual(a, b)
+
+ def test_unicode2(self):
+ a = bitarray()
+ a.extend(unicode())
+ self.assertEqual(a, bitarray())
+
+ a = bitarray()
+ a.extend(unicode('001011'))
+ self.assertEqual(a, bitarray('001011'))
+
+ for a in self.randombitarrays():
+ b = bitarray()
+ b.extend(unicode(a.to01()))
+ self.assertEqual(a, b)
+
+ def test_unhashable(self):
+ a = bitarray()
+ self.assertRaises(TypeError, hash, a)
+ self.assertRaises(TypeError, dict, [(a, 'foo')])
tests.append(MiscTests)
@@ -759,54 +783,52 @@ class SpecialMethodTests(unittest.TestCase, Util):
def test_all(self):
a = bitarray()
self.assertTrue(a.all())
-
- if sys.version_info[:2] < (2, 5):
- return
+ for s, r in ('0', False), ('1', True), ('01', False):
+ self.assertEqual(bitarray(s).all(), r)
for a in self.randombitarrays():
- self.assertEqual(all(a), a.all())
+ self.assertEqual(all(a), a.all())
self.assertEqual(all(a.tolist()), a.all())
-
def test_any(self):
a = bitarray()
self.assertFalse(a.any())
-
- if sys.version_info[:2] < (2, 5):
- return
+ for s, r in ('0', False), ('1', True), ('01', True):
+ self.assertEqual(bitarray(s).any(), r)
for a in self.randombitarrays():
- self.assertEqual(any(a), a.any())
+ self.assertEqual(any(a), a.any())
self.assertEqual(any(a.tolist()), a.any())
def test_repr(self):
- a = bitarray()
- self.assertEqual(repr(a), "bitarray()")
+ r = repr(bitarray())
+ self.assertEqual(r, "bitarray()")
+ self.assertIsInstance(r, str)
- a = bitarray('10111')
- self.assertEqual(repr(a), "bitarray('10111')")
+ r = repr(bitarray('10111'))
+ self.assertEqual(r, "bitarray('10111')")
+ self.assertIsInstance(r, str)
for a in self.randombitarrays():
b = eval(repr(a))
- self.assert_(b is not a)
+ self.assertFalse(b is a)
self.assertEqual(a, b)
self.check_obj(b)
def test_copy(self):
- import copy
for a in self.randombitarrays():
b = a.copy()
- self.assert_(b is not a)
+ self.assertFalse(b is a)
self.assertEQUAL(a, b)
b = copy.copy(a)
- self.assert_(b is not a)
+ self.assertFalse(b is a)
self.assertEQUAL(a, b)
b = copy.deepcopy(a)
- self.assert_(b is not a)
+ self.assertFalse(b is a)
self.assertEQUAL(a, b)
@@ -883,7 +905,7 @@ class NumberTests(unittest.TestCase, Util):
d = c
d += b
self.assertEqual(d, a + b)
- self.assert_(c is d)
+ self.assertTrue(c is d)
self.assertEQUAL(c, d)
self.assertEqual(d.endian(), a.endian())
self.check_obj(d)
@@ -978,12 +1000,19 @@ class BitwiseTests(unittest.TestCase, Util):
def test_or(self):
a = bitarray('11001')
b = bitarray('10011')
+ aa = a.copy()
+ bb = b.copy()
self.assertEQUAL(a | b, bitarray('11011'))
+ self.assertEQUAL(a, aa)
+ self.assertEQUAL(b, bb)
def test_ior(self):
- a = bitarray('110010110')
- a |= bitarray('100110011')
+ a = bitarray('110010110')
+ b = bitarray('100110011')
+ bb = b.copy()
+ a |= b
self.assertEQUAL(a, bitarray('110110111'))
+ self.assertEQUAL(b, bb)
def test_xor(self):
a = bitarray('11001')
@@ -1008,24 +1037,17 @@ class BitwiseTests(unittest.TestCase, Util):
b = ~a
self.assertEQUAL(b, bitarray('00100'))
self.assertEQUAL(a, bitarray('11011'))
- self.assert_(a is not b)
+ self.assertFalse(a is b)
for a in self.randombitarrays():
- aa = a.tolist()
b = bitarray(a)
b.invert()
for i in range(len(a)):
- self.assertEqual(b[i], not aa[i])
+ self.assertEqual(b[i], not a[i])
self.check_obj(b)
-
c = ~a
- self.assert_(c is not a)
- self.assertEQUAL(a, bitarray(aa, endian=a.endian()))
-
- for i in range(len(a)):
- self.assertEqual(c[i], not aa[i])
-
- self.check_obj(b)
+ self.assertEQUAL(c, b)
+ self.check_obj(c)
tests.append(BitwiseTests)
@@ -1036,21 +1058,21 @@ class SequenceTests(unittest.TestCase, Util):
def test_contains1(self):
a = bitarray()
- self.assert_(False not in a)
- self.assert_(True not in a)
- self.assert_(bitarray() in a)
+ self.assertFalse(False in a)
+ self.assertFalse(True in a)
+ self.assertTrue(bitarray() in a)
a.append(True)
- self.assert_(True in a)
- self.assert_(False not in a)
+ self.assertTrue(True in a)
+ self.assertFalse(False in a)
a = bitarray([False])
- self.assert_(False in a)
- self.assert_(True not in a)
+ self.assertTrue(False in a)
+ self.assertFalse(True in a)
a.append(True)
- self.assert_(0 in a)
- self.assert_(1 in a)
+ self.assertTrue(0 in a)
+ self.assertTrue(1 in a)
if not is_py3k:
- self.assert_(long(0) in a)
- self.assert_(long(1) in a)
+ self.assertTrue(long(0) in a)
+ self.assertTrue(long(1) in a)
def test_contains2(self):
a = bitarray()
@@ -1067,20 +1089,20 @@ class SequenceTests(unittest.TestCase, Util):
self.assertRaises(ValueError, a.__contains__, long(2))
def test_contains3(self):
- for n in range(2, 100):
+ for n in range(2, 50):
a = bitarray(n)
a.setall(0)
- self.assert_(False in a)
- self.assert_(True not in a)
+ self.assertTrue(False in a)
+ self.assertFalse(True in a)
a[randint(0, n - 1)] = 1
- self.assert_(True in a)
- self.assert_(False in a)
+ self.assertTrue(True in a)
+ self.assertTrue(False in a)
a.setall(1)
- self.assert_(True in a)
- self.assert_(False not in a)
+ self.assertTrue(True in a)
+ self.assertFalse(False in a)
a[randint(0, n - 1)] = 0
- self.assert_(True in a)
- self.assert_(False in a)
+ self.assertTrue(True in a)
+ self.assertTrue(False in a)
def test_contains4(self):
a = bitarray('011010000001')
@@ -1189,10 +1211,6 @@ class ExtendTests(unittest.TestCase, Util):
self.check_obj(c)
def test_iterator2(self):
- try:
- import itertools
- except ImportError:
- return
a = bitarray()
a.extend(itertools.repeat(True, 23))
self.assertEqual(a, bitarray(23 * '1'))
@@ -1242,12 +1260,19 @@ class MethodTests(unittest.TestCase, Util):
a.append(False)
a.append(False)
self.assertEQUAL(a, bitarray('100'))
+ a.append(0)
+ a.append(1)
+ a.append(2)
+ a.append(None)
+ a.append('')
+ a.append('a')
+ self.assertEQUAL(a, bitarray('100011001'))
for a in self.randombitarrays():
aa = a.tolist()
b = a
b.append(1)
- self.assert_(a is b)
+ self.assertTrue(a is b)
self.check_obj(b)
self.assertEQUAL(b, bitarray(aa+[1], endian=a.endian()))
b.append('')
@@ -1258,7 +1283,7 @@ class MethodTests(unittest.TestCase, Util):
a = bitarray()
b = a
a.insert(0, True)
- self.assert_(a is b)
+ self.assertTrue(a is b)
self.assertEqual(a, bitarray('1'))
self.assertRaises(TypeError, a.insert)
self.assertRaises(TypeError, a.insert, None)
@@ -1274,15 +1299,26 @@ class MethodTests(unittest.TestCase, Util):
self.check_obj(a)
- def test_index(self):
+ def test_index1(self):
a = bitarray()
for i in (True, False, 1, 0):
self.assertRaises(ValueError, a.index, i)
a = bitarray(100 * [False])
self.assertRaises(ValueError, a.index, True)
+ self.assertRaises(TypeError, a.index)
+ self.assertRaises(TypeError, a.index, 1, 'a')
+ self.assertRaises(TypeError, a.index, 1, 0, 'a')
+ self.assertRaises(TypeError, a.index, 1, 0, 100, 1)
a[20] = a[27] = 1
self.assertEqual(a.index(42), 20)
+ self.assertEqual(a.index(1, 21), 27)
+ self.assertEqual(a.index(1, 27), 27)
+ self.assertEqual(a.index(1, -73), 27)
+ self.assertRaises(ValueError, a.index, 1, 5, 17)
+ self.assertRaises(ValueError, a.index, 1, 5, -83)
+ self.assertRaises(ValueError, a.index, 1, 21, 27)
+ self.assertRaises(ValueError, a.index, 1, 28)
self.assertEqual(a.index(0), 0)
a = bitarray(200 * [True])
@@ -1291,6 +1327,7 @@ class MethodTests(unittest.TestCase, Util):
self.assertEqual(a.index(False), 173)
self.assertEqual(a.index(True), 0)
+ def test_index2(self):
for n in range(50):
for m in range(n):
a = bitarray(n)
@@ -1304,7 +1341,7 @@ class MethodTests(unittest.TestCase, Util):
a[m] = 0
self.assertEqual(a.index(0), m)
- def test_index2(self):
+ def test_index3(self):
a = bitarray('00001000' '00000000' '0010000')
self.assertEqual(a.index(1), 4)
self.assertEqual(a.index(1, 1), 4)
@@ -1313,7 +1350,16 @@ class MethodTests(unittest.TestCase, Util):
self.assertRaises(ValueError, a.index, 1, 5, 18)
self.assertRaises(ValueError, a.index, 1, 19)
- def test_index3(self):
+ def test_index4(self):
+ a = bitarray('11110111' '11111111' '1101111')
+ self.assertEqual(a.index(0), 4)
+ self.assertEqual(a.index(0, 1), 4)
+ self.assertEqual(a.index(1, 4), 5)
+ self.assertEqual(a.index(0, 5), 18)
+ self.assertRaises(ValueError, a.index, 0, 5, 18)
+ self.assertRaises(ValueError, a.index, 0, 19)
+
+ def test_index5(self):
a = bitarray(2000)
a.setall(0)
for _ in range(3):
@@ -1332,25 +1378,80 @@ class MethodTests(unittest.TestCase, Util):
res2 = None
self.assertEqual(res1, res2)
-
- def test_count(self):
+ def test_index6(self):
+ for n in range(1, 50):
+ a = bitarray(n)
+ i = randint(0, 1)
+ a.setall(i)
+ for unused in range(randint(1, 4)):
+ a[randint(0, n-1)] = 1-i
+ aa = a.tolist()
+ for unused in range(100):
+ start = randint(-50, n+50)
+ stop = randint(-50, n+50)
+ try:
+ res1 = a.index(1-i, start, stop)
+ except ValueError:
+ res1 = None
+ try:
+ res2 = aa.index(1-i, start, stop)
+ except ValueError:
+ res2 = None
+ self.assertEqual(res1, res2)
+
+
+ def test_count1(self):
a = bitarray('10011')
self.assertEqual(a.count(), 3)
self.assertEqual(a.count(True), 3)
self.assertEqual(a.count(False), 2)
self.assertEqual(a.count(1), 3)
self.assertEqual(a.count(0), 2)
- self.assertRaises(TypeError, a.count, 'A')
+ self.assertEqual(a.count(None), 2)
+ self.assertEqual(a.count(''), 2)
+ self.assertEqual(a.count('A'), 3)
+ self.assertRaises(TypeError, a.count, 0, 'A')
+ self.assertRaises(TypeError, a.count, 0, 0, 'A')
+ def test_count2(self):
for i in range(0, 256):
a = bitarray()
- a.frombytes(to_bytes(chr(i)))
+ a.frombytes(bytes(bytearray([i])))
self.assertEqual(a.count(), a.to01().count('1'))
+ def test_count3(self):
+ for a in self.randombitarrays():
+ s = a.to01()
+ self.assertEqual(a.count(1), s.count('1'))
+ self.assertEqual(a.count(0), s.count('0'))
+
+ def test_count4(self):
+ N = 37
+ a = bitarray(N)
+ a.setall(1)
+ for i in range(N):
+ for j in range(i, N):
+ self.assertEqual(a.count(1, i, j), j - i)
+
+ def test_count5(self):
+ for endian in 'big', 'little':
+ a = bitarray('01001100' '01110011' '01', endian)
+ self.assertEqual(a.count(), 9)
+ self.assertEqual(a.count(0, 12), 3)
+ self.assertEqual(a.count(1, -5), 3)
+ self.assertEqual(a.count(1, 2, 17), 7)
+ self.assertEqual(a.count(1, 6, 11), 2)
+ self.assertEqual(a.count(0, 7, -3), 4)
+ self.assertEqual(a.count(1, 1, -1), 8)
+ self.assertEqual(a.count(1, 17, 14), 0)
+
+ def test_count6(self):
for a in self.randombitarrays():
- self.assertEqual(a.count(), a.count(1))
- self.assertEqual(a.count(1), a.to01().count('1'))
- self.assertEqual(a.count(0), a.to01().count('0'))
+ s = a.to01()
+ i = randint(-3, len(a)+1)
+ j = randint(-3, len(a)+1)
+ self.assertEqual(a.count(1, i, j), s[i:j].count('1'))
+ self.assertEqual(a.count(0, i, j), s[i:j].count('0'))
def test_search(self):
@@ -1406,6 +1507,21 @@ class MethodTests(unittest.TestCase, Util):
self.assertEqual(list(a.itersearch(b)), res)
self.assertEqual([p for p in a.itersearch(b)], res)
+ def test_search4(self):
+ for a in self.randombitarrays():
+ aa = a.to01()
+ for sub in '0', '1', '01', '01', '11', '101', '1111111':
+ sr = a.search(bitarray(sub), 1)
+ try:
+ p = sr[0]
+ except IndexError:
+ p = -1
+ self.assertEqual(p, aa.find(sub))
+
+ def test_search_type(self):
+ a = bitarray('10011')
+ it = a.itersearch(bitarray('1'))
+ self.assertIsInstance(type(it), type)
def test_fill(self):
a = bitarray('')
@@ -1422,21 +1538,21 @@ class MethodTests(unittest.TestCase, Util):
aa = a.tolist()
la = len(a)
b = a
- self.assert_(0 <= b.fill() < 8)
+ self.assertTrue(0 <= b.fill() < 8)
self.assertEqual(b.endian(), a.endian())
bb = b.tolist()
lb = len(b)
- self.assert_(a is b)
+ self.assertTrue(a is b)
self.check_obj(b)
if la % 8 == 0:
self.assertEqual(bb, aa)
self.assertEqual(lb, la)
else:
- self.assert_(lb % 8 == 0)
+ self.assertTrue(lb % 8 == 0)
self.assertNotEqual(bb, aa)
self.assertEqual(bb[:la], aa)
self.assertEqual(b[la:], (lb-la)*bitarray('0'))
- self.assert_(0 < lb-la < 8)
+ self.assertTrue(0 < lb-la < 8)
def test_sort(self):
@@ -1456,11 +1572,20 @@ class MethodTests(unittest.TestCase, Util):
self.assertRaises(TypeError, a.sort, 'A')
+ N = 100000
+ a = bitarray(randint(N, N + 100))
+ for dum in range(100):
+ a[randint(0, N - 1)] = randint(0, 1)
+ b = a.tolist()
+ a.sort()
+ self.assertEqual(a, bitarray(sorted(b)))
+
for a in self.randombitarrays():
+ b = a.tolist()
ida = id(a)
rev = randint(0, 1)
a.sort(rev)
- self.assertEqual(a, bitarray(sorted(a.tolist(), reverse=rev)))
+ self.assertEqual(a, bitarray(sorted(b, reverse=rev)))
self.assertEqual(id(a), ida)
@@ -1480,10 +1605,12 @@ class MethodTests(unittest.TestCase, Util):
for a in self.randombitarrays():
aa = a.tolist()
+ b = bitarray(a)
ida = id(a)
a.reverse()
self.assertEqual(ida, id(a))
self.assertEQUAL(a, bitarray(aa[::-1], endian=a.endian()))
+ self.assertEqual(a, b[::-1])
def test_tolist(self):
@@ -1519,7 +1646,7 @@ class MethodTests(unittest.TestCase, Util):
a = bitarray('0010011')
b = a
b.remove('1')
- self.assert_(b is a)
+ self.assertTrue(b is a)
self.assertEQUAL(b, bitarray('000011'))
@@ -1547,9 +1674,7 @@ class MethodTests(unittest.TestCase, Util):
self.check_obj(a)
self.assertEqual(a.endian(), enda)
- for a in self.randombitarrays():
- if len(a) == 0:
- continue
+ for a in self.randombitarrays(start=1):
n = randint(-len(a), len(a)-1)
aa = a.tolist()
self.assertEqual(a.pop(n), aa[n])
@@ -1568,7 +1693,7 @@ class MethodTests(unittest.TestCase, Util):
b = a
b.setall(val)
self.assertEqual(b, bitarray(len(b) * [val]))
- self.assert_(a is b)
+ self.assertTrue(a is b)
self.check_obj(b)
@@ -1587,12 +1712,12 @@ class MethodTests(unittest.TestCase, Util):
for i in range(256):
a = bitarray()
- a.frombytes(to_bytes(chr(i)))
+ a.frombytes(bytes(bytearray([i])))
aa = a.tolist()
b = a
b.bytereverse()
self.assertEqual(b, bitarray(aa[::-1]))
- self.assert_(a is b)
+ self.assertTrue(a is b)
self.check_obj(b)
@@ -1604,102 +1729,99 @@ class StringTests(unittest.TestCase, Util):
def randombytes(self):
for n in range(1, 20):
- yield to_bytes(''.join(chr(randint(0, 255))
- for x in range(n)))
+ yield os.urandom(n)
def test_frombytes(self):
a = bitarray(endian='big')
- a.frombytes(to_bytes('A'))
+ a.frombytes(b'A')
self.assertEqual(a, bitarray('01000001'))
b = a
- b.frombytes(to_bytes('BC'))
+ b.frombytes(b'BC')
self.assertEQUAL(b, bitarray('01000001' '01000010' '01000011',
endian='big'))
- self.assert_(b is a)
+ self.assertTrue(b is a)
for b in self.randombitarrays():
- c = b.__copy__()
- b.frombytes(to_bytes(''))
+ c = b.copy()
+ b.frombytes(b'')
self.assertEQUAL(b, c)
for b in self.randombitarrays():
for s in self.randombytes():
a = bitarray(endian=b.endian())
a.frombytes(s)
- c = b.__copy__()
+ c = b.copy()
b.frombytes(s)
self.assertEQUAL(b[-len(a):], a)
self.assertEQUAL(b[:-len(a)], c)
- self.assertEQUAL(c + a, b)
+ self.assertEQUAL(b, c + a)
def test_tobytes(self):
a = bitarray()
- self.assertEqual(a.tobytes(), to_bytes(''))
+ self.assertEqual(a.tobytes(), b'')
for end in ('big', 'little'):
a = bitarray(endian=end)
- a.frombytes(to_bytes('foo'))
- self.assertEqual(a.tobytes(), to_bytes('foo'))
+ a.frombytes(b'foo')
+ self.assertEqual(a.tobytes(), b'foo')
for s in self.randombytes():
a = bitarray(endian=end)
a.frombytes(s)
self.assertEqual(a.tobytes(), s)
- for n, s in [(1, '\x01'), (2, '\x03'), (3, '\x07'), (4, '\x0f'),
- (5, '\x1f'), (6, '\x3f'), (7, '\x7f'), (8, '\xff'),
- (12, '\xff\x0f'), (15, '\xff\x7f'), (16, '\xff\xff'),
- (17, '\xff\xff\x01'), (24, '\xff\xff\xff')]:
+ for n, s in [(1, b'\x01'), (2, b'\x03'), (3, b'\x07'), (4, b'\x0f'),
+ (5, b'\x1f'), (6, b'\x3f'), (7, b'\x7f'), (8, b'\xff'),
+ (12, b'\xff\x0f'), (15, b'\xff\x7f'), (16, b'\xff\xff'),
+ (17, b'\xff\xff\x01'), (24, b'\xff\xff\xff')]:
a = bitarray(n, endian='little')
a.setall(1)
- self.assertEqual(a.tobytes(), to_bytes(s))
+ self.assertEqual(a.tobytes(), s)
def test_unpack(self):
a = bitarray('01')
- self.assertEqual(a.unpack(), to_bytes('\x00\xff'))
- self.assertEqual(a.unpack(to_bytes('A')), to_bytes('A\xff'))
- self.assertEqual(a.unpack(to_bytes('0'), to_bytes('1')),
- to_bytes('01'))
- self.assertEqual(a.unpack(one=to_bytes('\x01')),
- to_bytes('\x00\x01'))
- self.assertEqual(a.unpack(zero=to_bytes('A')),
- to_bytes('A\xff'))
- self.assertEqual(a.unpack(one=to_bytes('t'), zero=to_bytes('f')),
- to_bytes('ft'))
-
- self.assertRaises(TypeError, a.unpack,
- to_bytes('a'), zero=to_bytes('b'))
- self.assertRaises(TypeError, a.unpack, foo=to_bytes('b'))
+ if is_py3k:
+ self.assertIsInstance(a.unpack(), bytes)
+ else:
+ self.assertIsInstance(a.unpack(), str)
+ self.assertEqual(a.unpack(), b'\x00\xff')
+ self.assertEqual(a.unpack(b'A'), b'A\xff')
+ self.assertEqual(a.unpack(b'0', b'1'), b'01')
+ self.assertEqual(a.unpack(one=b'\x01'), b'\x00\x01')
+ self.assertEqual(a.unpack(zero=b'A'), b'A\xff')
+ self.assertEqual(a.unpack(one=b't', zero=b'f'), b'ft')
+
+ self.assertRaises(TypeError, a.unpack, b'a', zero=b'b')
+ self.assertRaises(TypeError, a.unpack, foo=b'b')
for a in self.randombitarrays():
- self.assertEqual(a.unpack(to_bytes('0'), to_bytes('1')),
- to_bytes(a.to01()))
+ self.assertEqual(a.unpack(b'0', b'1'), a.to01().encode())
b = bitarray()
b.pack(a.unpack())
self.assertEqual(b, a)
b = bitarray()
- b.pack(a.unpack(to_bytes('\x01'), to_bytes('\x00')))
+ b.pack(a.unpack(b'\x01', b'\x00'))
b.invert()
self.assertEqual(b, a)
def test_pack(self):
a = bitarray()
- a.pack(to_bytes('\x00'))
+ a.pack(b'\x00')
self.assertEqual(a, bitarray('0'))
- a.pack(to_bytes('\xff'))
+ a.pack(b'\xff')
self.assertEqual(a, bitarray('01'))
- a.pack(to_bytes('\x01\x00\x7a'))
+ a.pack(b'\x01\x00\x7a')
self.assertEqual(a, bitarray('01101'))
a = bitarray()
for n in range(256):
- a.pack(to_bytes(chr(n)))
+ a.pack(bytes(bytearray([n])))
self.assertEqual(a, bitarray('0' + 255 * '1'))
self.assertRaises(TypeError, a.pack, 0)
@@ -1724,35 +1846,17 @@ class FileTests(unittest.TestCase, Util):
def test_pickle(self):
- from pickle import load, dump
-
- for v in range(3):
- for a in self.randombitarrays():
- fo = open(self.tmpfname, 'wb')
- dump(a, fo, v)
- fo.close()
- b = load(open(self.tmpfname, 'rb'))
- self.assert_(b is not a)
- self.assertEQUAL(a, b)
-
- def test_cPickle(self):
- if is_py3k:
- return
- from cPickle import load, dump
-
for v in range(3):
for a in self.randombitarrays():
- fo = open(self.tmpfname, 'wb')
- dump(a, fo, v)
- fo.close()
- b = load(open(self.tmpfname, 'rb'))
- self.assert_(b is not a)
+ with open(self.tmpfname, 'wb') as fo:
+ pickle.dump(a, fo, v)
+ b = pickle.load(open(self.tmpfname, 'rb'))
+ self.assertFalse(b is a)
self.assertEQUAL(a, b)
def test_shelve(self):
- if sys.version_info[:2] < (2, 5):
+ if not shelve or hasattr(sys, 'gettotalrefcount'):
return
- import shelve, hashlib
d = shelve.open(self.tmpfname)
stored = []
@@ -1779,8 +1883,8 @@ class FileTests(unittest.TestCase, Util):
def test_from_empty_file(self):
- fo = open(self.tmpfname, 'wb')
- fo.close()
+ with open(self.tmpfname, 'wb') as fo:
+ pass
a = bitarray()
a.fromfile(open(self.tmpfname, 'rb'))
@@ -1790,9 +1894,8 @@ class FileTests(unittest.TestCase, Util):
def test_from_large_file(self):
N = 100000
- fo = open(self.tmpfname, 'wb')
- fo.write(N * to_bytes('X'))
- fo.close()
+ with open(self.tmpfname, 'wb') as fo:
+ fo.write(N * b'X')
a = bitarray()
a.fromfile(open(self.tmpfname, 'rb'))
@@ -1803,9 +1906,8 @@ class FileTests(unittest.TestCase, Util):
def test_fromfile_Foo(self):
- fo = open(self.tmpfname, 'wb')
- fo.write(to_bytes('Foo\n'))
- fo.close()
+ with open(self.tmpfname, 'wb') as fo:
+ fo.write(b'Foo\n')
a = bitarray(endian='big')
a.fromfile(open(self.tmpfname, 'rb'))
@@ -1831,61 +1933,54 @@ class FileTests(unittest.TestCase, Util):
def test_fromfile_n(self):
a = bitarray()
a.fromstring('ABCDEFGHIJ')
- fo = open(self.tmpfname, 'wb')
- a.tofile(fo)
- fo.close()
+ with open(self.tmpfname, 'wb') as fo:
+ a.tofile(fo)
b = bitarray()
- f = open(self.tmpfname, 'rb')
- b.fromfile(f, 1); self.assertEqual(b.tostring(), 'A')
- f.read(1)
- b = bitarray()
- b.fromfile(f, 2); self.assertEqual(b.tostring(), 'CD')
- b.fromfile(f, 1); self.assertEqual(b.tostring(), 'CDE')
- b.fromfile(f, 0); self.assertEqual(b.tostring(), 'CDE')
- b.fromfile(f); self.assertEqual(b.tostring(), 'CDEFGHIJ')
- b.fromfile(f); self.assertEqual(b.tostring(), 'CDEFGHIJ')
- f.close()
+ with open(self.tmpfname, 'rb') as f:
+ b.fromfile(f, 0); self.assertEqual(b.tostring(), '')
+ b.fromfile(f, 1); self.assertEqual(b.tostring(), 'A')
+ f.read(1)
+ b = bitarray()
+ b.fromfile(f, 2); self.assertEqual(b.tostring(), 'CD')
+ b.fromfile(f, 1); self.assertEqual(b.tostring(), 'CDE')
+ b.fromfile(f, 0); self.assertEqual(b.tostring(), 'CDE')
+ b.fromfile(f); self.assertEqual(b.tostring(), 'CDEFGHIJ')
+ b.fromfile(f); self.assertEqual(b.tostring(), 'CDEFGHIJ')
b = bitarray()
- f = open(self.tmpfname, 'rb')
- f.read(1);
- self.assertRaises(EOFError, b.fromfile, f, 10)
- f.close()
+ with open(self.tmpfname, 'rb') as f:
+ f.read(1);
+ self.assertRaises(EOFError, b.fromfile, f, 10)
+
self.assertEqual(b.tostring(), 'BCDEFGHIJ')
b = bitarray()
- f = open(self.tmpfname, 'rb')
- b.fromfile(f);
- self.assertEqual(b.tostring(), 'ABCDEFGHIJ')
- self.assertRaises(EOFError, b.fromfile, f, 1)
- f.close()
+ with open(self.tmpfname, 'rb') as f:
+ b.fromfile(f);
+ self.assertEqual(b.tostring(), 'ABCDEFGHIJ')
+ self.assertRaises(EOFError, b.fromfile, f, 1)
def test_tofile(self):
a = bitarray()
- f = open(self.tmpfname, 'wb')
- a.tofile(f)
- f.close()
+ with open(self.tmpfname, 'wb') as f:
+ a.tofile(f)
- fi = open(self.tmpfname, 'rb')
- self.assertEqual(fi.read(), to_bytes(''))
- fi.close()
+ with open(self.tmpfname, 'rb') as fi:
+ self.assertEqual(fi.read(), b'')
a = bitarray('01000110011011110110111100001010', endian='big')
- f = open(self.tmpfname, 'wb')
- a.tofile(f)
- f.close()
+ with open(self.tmpfname, 'wb') as f:
+ a.tofile(f)
- fi = open(self.tmpfname, 'rb')
- self.assertEqual(fi.read(), to_bytes('Foo\n'))
- fi.close()
+ with open(self.tmpfname, 'rb') as fi:
+ self.assertEqual(fi.read(), b'Foo\n')
for a in self.randombitarrays():
b = bitarray(a, endian='big')
- fo = open(self.tmpfname, 'wb')
- b.tofile(fo)
- fo.close()
+ with open(self.tmpfname, 'wb') as fo:
+ b.tofile(fo)
s = open(self.tmpfname, 'rb').read()
self.assertEqual(len(s), a.buffer_info()[1])
@@ -1895,21 +1990,19 @@ class FileTests(unittest.TestCase, Util):
self.assertRaises(TypeError, a.tofile)
self.assertRaises(TypeError, a.tofile, StringIO())
- f = open(self.tmpfname, 'wb')
- a.tofile(f)
- f.close()
+ with open(self.tmpfname, 'wb') as f:
+ a.tofile(f)
self.assertRaises(TypeError, a.tofile, f)
for n in range(20):
a = n * bitarray('1', endian='little')
- fo = open(self.tmpfname, 'wb')
- a.tofile(fo)
- fo.close()
+ with open(self.tmpfname, 'wb') as fo:
+ a.tofile(fo)
s = open(self.tmpfname, 'rb').read()
self.assertEqual(len(s), a.buffer_info()[1])
- b = a.__copy__()
+ b = a.copy()
b.fill()
c = bitarray(endian='little')
@@ -1923,16 +2016,6 @@ tests.append(FileTests)
class PrefixCodeTests(unittest.TestCase, Util):
- def test_encode_errors(self):
- a = bitarray()
- self.assertRaises(TypeError, a.encode, 0, '')
- self.assertRaises(ValueError, a.encode, {}, '')
- self.assertRaises(TypeError, a.encode, {'a':42}, '')
- self.assertRaises(ValueError, a.encode, {'a': bitarray()}, '')
- # 42 not iterable
- self.assertRaises(TypeError, a.encode, {'a': bitarray('0')}, 42)
- self.assertEqual(len(a), 0)
-
def test_encode_string(self):
a = bitarray()
d = {'a': bitarray('0')}
@@ -1944,7 +2027,7 @@ class PrefixCodeTests(unittest.TestCase, Util):
def test_encode_list(self):
a = bitarray()
- d = {'a':bitarray('0')}
+ d = {'a': bitarray('0')}
a.encode(d, [])
self.assertEqual(a, bitarray())
a.encode(d, ['a'])
@@ -1979,14 +2062,48 @@ class PrefixCodeTests(unittest.TestCase, Util):
'a': bitarray('001'), 'n': bitarray('000')})
self.assertRaises(ValueError, a.encode, d, 'arvin')
+ def test_encode_symbol_not_in_code(self):
+ d = {None : bitarray('0'),
+ 0 : bitarray('10'),
+ 'A' : bitarray('11')}
+ a = bitarray()
+ a.encode(d, ['A', None, 0])
+ self.assertEqual(a, bitarray('11010'))
+ self.assertRaises(ValueError, a.encode, d, [1, 2])
+ self.assertRaises(ValueError, a.encode, d, 'ABCD')
+
+ def test_encode_not_iterable(self):
+ d = {'a': bitarray('0'), 'b': bitarray('1')}
+ a = bitarray()
+ a.encode(d, 'abba')
+ self.assertRaises(TypeError, a.encode, d, 42)
+ self.assertRaises(TypeError, a.encode, d, 1.3)
+ self.assertRaises(TypeError, a.encode, d, None)
+ self.assertEqual(a, bitarray('0110'))
- def test_decode_check_codedict(self):
+ def test_check_codedict_encode(self):
a = bitarray()
+ self.assertRaises(TypeError, a.encode, None, '')
+ self.assertRaises(ValueError, a.encode, {}, '')
+ self.assertRaises(TypeError, a.encode, {'a': 'b'}, '')
+ self.assertRaises(ValueError, a.encode, {'a': bitarray()}, '')
+ self.assertEqual(len(a), 0)
+
+ def test_check_codedict_decode(self):
+ a = bitarray('101')
self.assertRaises(TypeError, a.decode, 0)
self.assertRaises(ValueError, a.decode, {})
- # 42 not iterable
- self.assertRaises(TypeError, a.decode, {'a':42})
- self.assertRaises(ValueError, a.decode, {'a':bitarray()})
+ self.assertRaises(TypeError, a.decode, {'a': 42})
+ self.assertRaises(ValueError, a.decode, {'a': bitarray()})
+ self.assertEqual(a, bitarray('101'))
+
+ def test_check_codedict_iterdecode(self):
+ a = bitarray('1100101')
+ self.assertRaises(TypeError, a.iterdecode, 0)
+ self.assertRaises(ValueError, a.iterdecode, {})
+ self.assertRaises(TypeError, a.iterdecode, {'a': []})
+ self.assertRaises(ValueError, a.iterdecode, {'a': bitarray()})
+ self.assertEqual(a, bitarray('1100101'))
def test_decode_simple(self):
d = {'I': bitarray('1'),
@@ -2068,16 +2185,15 @@ class PrefixCodeTests(unittest.TestCase, Util):
self.assertEqual(a, bitarray('1'))
def test_decode_ambiguous_code(self):
- d = {'a': bitarray('0'), 'b': bitarray('0'), 'c': bitarray('1')}
- a = bitarray()
- self.assertRaises(ValueError, a.decode, d)
- self.assertRaises(ValueError, a.iterdecode, d)
-
- def test_decode_ambiguous2(self):
- d = {'a': bitarray('01'), 'b': bitarray('01'), 'c': bitarray('1')}
- a = bitarray()
- self.assertRaises(ValueError, a.decode, d)
- self.assertRaises(ValueError, a.iterdecode, d)
+ for d in [
+ {'a': bitarray('0'), 'b': bitarray('0'), 'c': bitarray('1')},
+ {'a': bitarray('01'), 'b': bitarray('01'), 'c': bitarray('1')},
+ {'a': bitarray('0'), 'b': bitarray('01')},
+ {'a': bitarray('0'), 'b': bitarray('11'), 'c': bitarray('111')},
+ ]:
+ a = bitarray()
+ self.assertRaises(ValueError, a.decode, d)
+ self.assertRaises(ValueError, a.iterdecode, d)
def test_miscitems(self):
d = {None : bitarray('00'),
@@ -2099,34 +2215,34 @@ class PrefixCodeTests(unittest.TestCase, Util):
self.assertStopIteration(it)
def test_real_example(self):
- code = {' ' : bitarray('001'),
- '.' : bitarray('0101010'),
- 'a' : bitarray('0110'),
- 'b' : bitarray('0001100'),
- 'c' : bitarray('000011'),
- 'd' : bitarray('01011'),
- 'e' : bitarray('111'),
- 'f' : bitarray('010100'),
- 'g' : bitarray('101000'),
- 'h' : bitarray('00000'),
- 'i' : bitarray('1011'),
- 'j' : bitarray('0111101111'),
- 'k' : bitarray('00011010'),
- 'l' : bitarray('01110'),
- 'm' : bitarray('000111'),
- 'n' : bitarray('1001'),
- 'o' : bitarray('1000'),
- 'p' : bitarray('101001'),
- 'q' : bitarray('00001001101'),
- 'r' : bitarray('1101'),
- 's' : bitarray('1100'),
- 't' : bitarray('0100'),
- 'u' : bitarray('000100'),
- 'v' : bitarray('0111100'),
- 'w' : bitarray('011111'),
- 'x' : bitarray('0000100011'),
- 'y' : bitarray('101010'),
- 'z' : bitarray('00011011110')}
+ code = {' ': bitarray('001'),
+ '.': bitarray('0101010'),
+ 'a': bitarray('0110'),
+ 'b': bitarray('0001100'),
+ 'c': bitarray('000011'),
+ 'd': bitarray('01011'),
+ 'e': bitarray('111'),
+ 'f': bitarray('010100'),
+ 'g': bitarray('101000'),
+ 'h': bitarray('00000'),
+ 'i': bitarray('1011'),
+ 'j': bitarray('0111101111'),
+ 'k': bitarray('00011010'),
+ 'l': bitarray('01110'),
+ 'm': bitarray('000111'),
+ 'n': bitarray('1001'),
+ 'o': bitarray('1000'),
+ 'p': bitarray('101001'),
+ 'q': bitarray('00001001101'),
+ 'r': bitarray('1101'),
+ 's': bitarray('1100'),
+ 't': bitarray('0100'),
+ 'u': bitarray('000100'),
+ 'v': bitarray('0111100'),
+ 'w': bitarray('011111'),
+ 'x': bitarray('0000100011'),
+ 'y': bitarray('101010'),
+ 'z': bitarray('00011011110')}
a = bitarray()
message = 'the quick brown fox jumps over the lazy dog.'
a.encode(code, message)
@@ -2140,7 +2256,7 @@ class PrefixCodeTests(unittest.TestCase, Util):
tests.append(PrefixCodeTests)
-# -------------- Buffer Interface (Python 2.7 only for now) ----------------
+# -------------- Buffer Interface (Python 2.7 and above) --------------------
class BufferInterfaceTests(unittest.TestCase):
@@ -2149,36 +2265,117 @@ class BufferInterfaceTests(unittest.TestCase):
v = memoryview(a)
self.assertEqual(len(v), 3)
self.assertEqual(v[0], 65 if is_py3k else 'A')
- self.assertEqual(v[:].tobytes(), b'ABC')
+ self.assertEqual(v.tobytes(), b'ABC')
a[13] = 1
- self.assertEqual(v[:].tobytes(), b'AFC')
+ self.assertEqual(v.tobytes(), b'AFC')
def test_read2(self):
- a = bitarray([randint(0, 1) for d in range(8000)])
+ a = bitarray()
+ a.frombytes(os.urandom(100))
v = memoryview(a)
- self.assertEqual(len(v), 1000)
- b = a[345 * 8 : 657 * 8]
- self.assertEqual(v[345:657].tobytes(), b.tobytes())
- self.assertEqual(v[:].tobytes(), a.tobytes())
+ self.assertEqual(len(v), 100)
+ b = a[34 * 8 : 67 * 8]
+ self.assertEqual(v[34:67].tobytes(), b.tobytes())
+ self.assertEqual(v.tobytes(), a.tobytes())
def test_write(self):
- a = bitarray(800000)
+ a = bitarray(8000)
a.setall(0)
v = memoryview(a)
self.assertFalse(v.readonly)
- v[50000] = 255 if is_py3k else '\xff'
- self.assertEqual(a[399999:400009], bitarray('0111111110'))
- a[400003] = 0
- self.assertEqual(a[399999:400009], bitarray('0111011110'))
- v[30001:30004] = b'ABC'
- self.assertEqual(a[240000:240040].tobytes(), b'\x00ABC\x00')
+ v[500] = 255 if is_py3k else '\xff'
+ self.assertEqual(a[3999:4009], bitarray('0111111110'))
+ a[4003] = 0
+ self.assertEqual(a[3999:4009], bitarray('0111011110'))
+ v[301:304] = b'ABC'
+ self.assertEqual(a[300 *8 : 305 * 8].tobytes(), b'\x00ABC\x00')
if sys.version_info[:2] >= (2, 7):
tests.append(BufferInterfaceTests)
# ---------------------------------------------------------------------------
+class TestsFrozenbitarray(unittest.TestCase, Util):
+
+ def test_init(self):
+ a = frozenbitarray('110')
+ self.assertEqual(a, bitarray('110'))
+ self.assertEqual(a.to01(), '110')
+ for endian in 'big', 'little':
+ a = frozenbitarray(0, endian)
+ self.assertEqual(a.endian(), endian)
+
+ def test_methods(self):
+ # test a few methods which do not raise the TypeError
+ a = frozenbitarray('1101100')
+ self.assertEqual(a[2], 0)
+ self.assertEqual(a[:4].to01(), '1101')
+ self.assertEqual(a.count(), 4)
+ self.assertEqual(a.index(0), 2)
+ b = a.copy()
+ self.assertEqual(b, a)
+ self.assertEqual(repr(type(b)), "<class 'bitarray.frozenbitarray'>")
+ self.assertEqual(len(b), 7)
+ self.assertEqual(b.length(), 7)
+ self.assertEqual(b.all(), False)
+ self.assertEqual(b.any(), True)
+
+ def test_init_bitarray(self):
+ for a in self.randombitarrays():
+ b = frozenbitarray(a)
+ self.assertFalse(b is a)
+ self.assertEqual(b, a)
+ self.assertEqual(b.endian(), a.endian())
+ c = frozenbitarray(b)
+ self.assertEqual(c, b)
+ self.assertFalse(c is b)
+ self.assertEqual(c.endian(), a.endian())
+ self.assertEqual(hash(c), hash(b))
+
+ def test_repr(self):
+ a = frozenbitarray()
+ self.assertEqual(repr(a), "frozenbitarray()")
+ self.assertEqual(str(a), "frozenbitarray()")
+ a = frozenbitarray('10111')
+ self.assertEqual(repr(a), "frozenbitarray('10111')")
+ self.assertEqual(str(a), "frozenbitarray('10111')")
+
+ def test_immutable(self):
+ a = frozenbitarray('111')
+ self.assertRaises(TypeError, a.append, True)
+ self.assertRaises(TypeError, a.__setitem__, 0, 0)
+ self.assertRaises(TypeError, a.__delitem__, 0)
+
+ def test_dictkey(self):
+ a = frozenbitarray('01')
+ b = frozenbitarray('1001')
+ d = {a: 123, b: 345}
+ self.assertEqual(d[frozenbitarray('01')], 123)
+ self.assertEqual(d[frozenbitarray(b)], 345)
+
+ def test_dictkey2(self): # taken sllightly modified from issue #74
+ a1 = frozenbitarray([True, False])
+ a2 = frozenbitarray([False, False])
+ dct = {a1: "one", a2: "two"}
+ a3 = frozenbitarray([True, False])
+ self.assertEqual(a3, a1)
+ self.assertEqual(dct[a3], 'one')
+
+ def test_mix(self):
+ a = bitarray('110')
+ b = frozenbitarray('0011')
+ self.assertEqual(a + b, bitarray('1100011'))
+ a.extend(b)
+ self.assertEqual(a, bitarray('1100011'))
+
+tests.append(TestsFrozenbitarray)
+
+# ---------------------------------------------------------------------------
+
def run(verbosity=1, repeat=1):
+ import bitarray.test_util as btu
+ tests.extend(btu.tests)
+
print('bitarray is installed in: %s' % os.path.dirname(__file__))
print('bitarray version: %s' % __version__)
print('Python version: %s' % sys.version)
diff --git a/shell/ext-py/bitarray-1.2.1/bitarray/test_util.py b/shell/ext-py/bitarray-1.2.1/bitarray/test_util.py
new file mode 100644
index 0000000..2446290
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/bitarray/test_util.py
@@ -0,0 +1,590 @@
+"""
+Tests for bitarray.util module
+"""
+import os
+import sys
+import unittest
+from string import hexdigits
+from random import choice, randint
+try:
+ from collections import Counter
+except ImportError:
+ pass
+
+from bitarray import bitarray, frozenbitarray, bits2bytes
+from bitarray.test_bitarray import Util
+
+from bitarray.util import (zeros, rindex, strip, count_n,
+ count_and, count_or, count_xor, subset,
+ ba2hex, hex2ba, ba2int, int2ba, huffman_code)
+
+
+tests = []
+
+# ---------------------------------------------------------------------------
+
+class TestsZeros(unittest.TestCase):
+
+ def test_init(self):
+ a = zeros(0)
+ self.assertEqual(a, bitarray(''))
+ self.assertEqual(a.endian(), 'big')
+ self.assertRaises(TypeError, zeros, 1.0)
+ for n in range(100):
+ a = zeros(n)
+ self.assertEqual(a, bitarray(n * '0'))
+ self.assertRaises(TypeError, zeros) # no argument
+
+ # wrong arguments
+ self.assertRaises(TypeError, zeros, '')
+ self.assertRaises(TypeError, zeros, bitarray())
+ self.assertRaises(TypeError, zeros, [])
+ self.assertRaises(ValueError, zeros, -1)
+
+ self.assertRaises(TypeError, zeros, 0, 1) # endian not string
+ self.assertRaises(ValueError, zeros, 0, 'foo') # endian wrong string
+
+ def test_endian(self):
+ for endian in 'big', 'little':
+ a = zeros(1, endian)
+ self.assertEqual(a, bitarray('0'))
+ self.assertEqual(a.endian(), endian)
+ a = zeros(1, endian=endian)
+ self.assertEqual(a, bitarray('0'))
+ self.assertEqual(a.endian(), endian)
+
+tests.append(TestsZeros)
+
+# ---------------------------------------------------------------------------
+
+class TestsHelpers(unittest.TestCase, Util):
+
+ def test_rindex(self):
+ self.assertRaises(TypeError, rindex)
+ self.assertRaises(TypeError, rindex, None)
+ self.assertRaises(TypeError, rindex, bitarray(), 1, 2)
+ for endian in 'big', 'little':
+ a = bitarray('00010110000', endian)
+ self.assertEqual(rindex(a), 6)
+ self.assertEqual(rindex(a, 1), 6)
+ self.assertEqual(rindex(a, 'A'), 6)
+ self.assertEqual(rindex(a, True), 6)
+
+ a = bitarray('00010110111', endian)
+ self.assertEqual(rindex(a, 0), 7)
+ self.assertEqual(rindex(a, None), 7)
+ self.assertEqual(rindex(a, False), 7)
+
+ a = frozenbitarray('00010110111', endian)
+ self.assertEqual(rindex(a, 0), 7)
+ self.assertEqual(rindex(a, None), 7)
+ self.assertEqual(rindex(a, False), 7)
+
+ for v in 0, 1:
+ self.assertRaises(ValueError, rindex,
+ bitarray(0, endian), v)
+ self.assertRaises(ValueError, rindex,
+ bitarray('000', endian), 1)
+ self.assertRaises(ValueError, rindex,
+ bitarray('11111', endian), 0)
+
+ def test_rindex2(self):
+ for a in self.randombitarrays():
+ v = randint(0, 1)
+ try:
+ i = rindex(a, v)
+ except ValueError:
+ i = None
+ s = a.to01()
+ try:
+ j = s.rindex(str(v))
+ except ValueError:
+ j = None
+ self.assertEqual(i, j)
+
+ def test_rindex3(self):
+ for _ in range(100):
+ n = randint(1, 100000)
+ v = randint(0, 1)
+ a = bitarray(n)
+ a.setall(1 - v)
+ lst = [randint(0, n - 1) for _ in range(100)]
+ for i in lst:
+ a[i] = v
+ self.assertEqual(rindex(a, v), max(lst))
+
+ def test_rindex4(self):
+ for _ in range(100):
+ N = randint(1, 10000)
+ a = bitarray(N)
+ a.setall(0)
+ a[randint(0, N - 1)] = 1
+ self.assertEqual(rindex(a), a.index(1))
+
+ def test_strip1(self):
+ self.assertRaises(TypeError, strip, bitarray(), 123)
+ self.assertRaises(ValueError, strip, bitarray(), 'up')
+ for endian in 'big', 'little':
+ a = bitarray('00010110000', endian)
+ self.assertEQUAL(strip(a), bitarray('0001011', endian))
+ self.assertEQUAL(strip(a, 'left'), bitarray('10110000', endian))
+ self.assertEQUAL(strip(a, 'both'), bitarray('1011', endian))
+
+ for mode in 'left', 'right', 'both':
+ self.assertEqual(strip(bitarray('000'), mode), bitarray())
+ self.assertEqual(strip(bitarray(), mode), bitarray())
+
+ def test_strip2(self):
+ for a in self.randombitarrays():
+ b = a.copy()
+ s = a.to01()
+ self.assertEqual(strip(a, 'left'), bitarray(s.lstrip('0')))
+ self.assertEqual(strip(a, 'right'), bitarray(s.rstrip('0')))
+ self.assertEqual(strip(a, 'both'), bitarray(s.strip('0')))
+ self.assertEQUAL(a, b)
+
+ def test_strip_both(self):
+ for _ in range(100):
+ N = randint(1, 10000)
+ a = bitarray(N)
+ a.setall(0)
+ a[randint(0, N - 1)] = 1
+ self.assertEqual(strip(a, 'both'), bitarray('1'))
+
+ def check_result(self, a, n, i):
+ self.assertEqual(a.count(1, 0, i), n)
+ if i:
+ self.assertTrue(a[i - 1])
+
+ def test_count_n1(self):
+ a = bitarray('111110111110111110111110011110111110111110111000')
+ b = a.copy()
+ self.assertEqual(len(a), 48)
+ self.assertEqual(a.count(), 37)
+ self.assertRaises(TypeError, count_n, '', 0)
+ self.assertEqual(count_n(a, 0), 0)
+ self.assertEqual(count_n(a, 20), 23)
+ self.assertEqual(count_n(a, 37), 45)
+ self.assertRaises(ValueError, count_n, a, -1) # n < 0
+ self.assertRaises(ValueError, count_n, a, 38) # n > a.count()
+ self.assertRaises(ValueError, count_n, a, 49) # n > len(a)
+ self.assertRaises(TypeError, count_n, a, "7")
+ for n in range(0, 37):
+ i = count_n(a, n)
+ self.check_result(a, n, i)
+ self.assertEqual(a[:i].count(), n)
+ self.assertEQUAL(a, b)
+
+ def test_count_n1_frozen(self):
+ a = frozenbitarray('001111101111101111101111100111100')
+ self.assertEqual(len(a), 33)
+ self.assertEqual(a.count(), 24)
+ self.assertRaises(TypeError, count_n, '', 0)
+ self.assertEqual(count_n(a, 0), 0)
+ self.assertEqual(count_n(a, 10), 13)
+ self.assertEqual(count_n(a, 24), 31)
+ self.assertRaises(ValueError, count_n, a, -1) # n < 0
+ self.assertRaises(ValueError, count_n, a, 25) # n > a.count()
+ self.assertRaises(ValueError, count_n, a, 34) # n > len(a)
+ self.assertRaises(TypeError, count_n, a, "7")
+
+ def test_count_n2(self):
+ for N in list(range(100)) + [1000, 10000, 100000]:
+ a = bitarray(N)
+ v = randint(0, 1)
+ a.setall(v - 1)
+ for _ in range(randint(0, min(N, 100))):
+ a[randint(0, N - 1)] = v
+ n = randint(0, a.count())
+ self.check_result(a, n, count_n(a, n))
+ # check for total count
+ tc = a.count()
+ self.assertTrue(count_n(a, tc) <= N)
+ self.assertRaises(ValueError, count_n, a, tc + 1)
+
+ def test_count_n3(self):
+ N = 100000
+ for _ in range(10):
+ a = bitarray(N)
+ a.setall(0)
+ self.assertEqual(count_n(a, 0), 0)
+ self.assertRaises(ValueError, count_n, a, 1)
+ i = randint(0, N - 1)
+ a[i] = 1
+ self.assertEqual(count_n(a, 1), i + 1)
+ self.assertRaises(ValueError, count_n, a, 2)
+
+ def test_count_n4(self):
+ for a in self.randombitarrays():
+ n = a.count() // 2
+ i = count_n(a, n)
+ self.check_result(a, n, i)
+
+tests.append(TestsHelpers)
+
+# ---------------------------------------------------------------------------
+
+class TestsBitwiseCount(unittest.TestCase, Util):
+
+ def test_bit_count1(self):
+ a = bitarray('001111')
+ aa = a.copy()
+ b = bitarray('010011')
+ bb = b.copy()
+ self.assertEqual(count_and(a, b), 2)
+ self.assertEqual(count_or(a, b), 5)
+ self.assertEqual(count_xor(a, b), 3)
+ for f in count_and, count_or, count_xor:
+ # not two arguments
+ self.assertRaises(TypeError, f)
+ self.assertRaises(TypeError, f, a)
+ self.assertRaises(TypeError, f, a, b, 3)
+ # wrong argument types
+ self.assertRaises(TypeError, f, a, '')
+ self.assertRaises(TypeError, f, '1', b)
+ self.assertRaises(TypeError, f, a, 4)
+ self.assertEQUAL(a, aa)
+ self.assertEQUAL(b, bb)
+
+ b.append(1)
+ for f in count_and, count_or, count_xor:
+ self.assertRaises(ValueError, f, a, b)
+ self.assertRaises(ValueError, f,
+ bitarray('110', 'big'),
+ bitarray('101', 'little'))
+
+ def test_bit_count_frozen(self):
+ a = frozenbitarray('001111')
+ b = frozenbitarray('010011')
+ self.assertEqual(count_and(a, b), 2)
+ self.assertEqual(count_or(a, b), 5)
+ self.assertEqual(count_xor(a, b), 3)
+
+ def test_bit_count2(self):
+ for n in list(range(50)) + [randint(1000, 2000)]:
+ a = bitarray()
+ a.frombytes(os.urandom(bits2bytes(n)))
+ del a[n:]
+ b = bitarray()
+ b.frombytes(os.urandom(bits2bytes(n)))
+ del b[n:]
+ self.assertEqual(count_and(a, b), (a & b).count())
+ self.assertEqual(count_or(a, b), (a | b).count())
+ self.assertEqual(count_xor(a, b), (a ^ b).count())
+
+tests.append(TestsBitwiseCount)
+
+# ---------------------------------------------------------------------------
+
+class TestsSubset(unittest.TestCase, Util):
+
+ def test_subset(self):
+ a = frozenbitarray('0101')
+ b = bitarray('0111')
+ self.assertTrue(subset(a, b))
+ self.assertFalse(subset(b, a))
+ self.assertRaises(TypeError, subset)
+ self.assertRaises(TypeError, subset, a, '')
+ self.assertRaises(TypeError, subset, '1', b)
+ self.assertRaises(TypeError, subset, a, 4)
+ b.append(1)
+ self.assertRaises(ValueError, subset, a, b)
+
+ def subset_simple(self, a, b):
+ return (a & b).count() == a.count()
+
+ def test_subset_True(self):
+ for a, b in [('', ''), ('0', '1'), ('0', '0'), ('1', '1'),
+ ('000', '111'), ('0101', '0111'),
+ ('000010111', '010011111')]:
+ a, b = bitarray(a), bitarray(b)
+ self.assertTrue(subset(a, b) is True)
+ self.assertTrue(self.subset_simple(a, b) is True)
+
+ def test_subset_False(self):
+ for a, b in [('1', '0'), ('1101', '0111'),
+ ('0000101111', '0100111011')]:
+ a, b = bitarray(a), bitarray(b)
+ self.assertTrue(subset(a, b) is False)
+ self.assertTrue(self.subset_simple(a, b) is False)
+
+ def test_many(self):
+ for a in self.randombitarrays(start=1):
+ b = a.copy()
+ # we set one random bit in b to 1, so a is always a subset of b
+ b[randint(0, len(a)-1)] = 1
+ self.assertTrue(subset(a, b))
+ # but b in not always a subset of a
+ self.assertEqual(subset(b, a), self.subset_simple(b, a))
+ # we set all bits in a, which ensures that b is a subset of a
+ a.setall(1)
+ self.assertTrue(subset(b, a))
+
+tests.append(TestsSubset)
+
+# ---------------------------------------------------------------------------
+
+class TestsHexlify(unittest.TestCase, Util):
+
+ def test_ba2hex(self):
+ self.assertEqual(ba2hex(bitarray(0, 'big')), b'')
+ self.assertEqual(ba2hex(bitarray('1110', 'big')), b'e')
+ self.assertEqual(ba2hex(bitarray('00000001', 'big')), b'01')
+ self.assertEqual(ba2hex(bitarray('10000000', 'big')), b'80')
+ self.assertEqual(ba2hex(frozenbitarray('11000111', 'big')), b'c7')
+ # length not multiple of 4
+ self.assertRaises(ValueError, ba2hex, bitarray('10'))
+ self.assertRaises(ValueError, ba2hex, bitarray(endian='little'))
+ self.assertRaises(TypeError, ba2hex, '101')
+
+ for n in range(7):
+ a = bitarray(n * '1111', 'big')
+ b = a.copy()
+ self.assertEqual(ba2hex(a), n * b'f')
+ # ensure original object wasn't altered
+ self.assertEQUAL(a, b)
+
+ def test_hex2ba(self):
+ self.assertEqual(hex2ba(''), bitarray())
+ for c in 'e', 'E', b'e', b'E':
+ a = hex2ba(c)
+ self.assertEqual(a.to01(), '1110')
+ self.assertEqual(a.endian(), 'big')
+ self.assertEQUAL(hex2ba('01'), bitarray('00000001', 'big'))
+ self.assertRaises(Exception, hex2ba, '01a7x89')
+ self.assertRaises(TypeError, hex2ba, 0)
+
+ def test_explicit(self):
+ for h, bs in [(b'', ''),
+ (b'0', '0000'),
+ (b'a', '1010'),
+ (b'f', '1111'),
+ (b'1a', '00011010'),
+ (b'2b', '00101011'),
+ (b'4c1', '010011000001'),
+ (b'a7d', '101001111101')]:
+ a = bitarray(bs, 'big')
+ self.assertEQUAL(hex2ba(h), a)
+ self.assertEqual(ba2hex(a), h)
+
+ def test_round_trip(self):
+ for i in range(100):
+ s = ''.join(choice(hexdigits) for _ in range(randint(0, 1000)))
+ t = ba2hex(hex2ba(s))
+ self.assertEqual(t.decode(), s.lower())
+
+ def test_round_trip2(self):
+ for a in self.randombitarrays():
+ if len(a) % 4 or a.endian() != 'big':
+ self.assertRaises(ValueError, ba2hex, a)
+ continue
+ b = hex2ba(ba2hex(a))
+ self.assertEQUAL(b, a)
+
+tests.append(TestsHexlify)
+
+# ---------------------------------------------------------------------------
+
+class TestsIntegerization(unittest.TestCase, Util):
+
+ def test_ba2int(self):
+ self.assertEqual(ba2int(bitarray('0')), 0)
+ self.assertEqual(ba2int(bitarray('1')), 1)
+ self.assertEqual(ba2int(bitarray('00101', 'big')), 5)
+ self.assertEqual(ba2int(bitarray('00101', 'little')), 20)
+ self.assertEqual(ba2int(frozenbitarray('11')), 3)
+ self.assertRaises(ValueError, ba2int, bitarray())
+ self.assertRaises(ValueError, ba2int, frozenbitarray())
+ self.assertRaises(TypeError, ba2hex, '101')
+ a = bitarray('111')
+ b = a.copy()
+ self.assertEqual(ba2int(a), 7)
+ # ensure original object wasn't altered
+ self.assertEQUAL(a, b)
+
+ def test_int2ba(self):
+ self.assertEqual(int2ba(0), bitarray('0'))
+ self.assertEqual(int2ba(1), bitarray('1'))
+ self.assertEqual(int2ba(5), bitarray('101'))
+ self.assertEQUAL(int2ba(6), bitarray('110', 'big'))
+ self.assertEQUAL(int2ba(6, endian='little'),
+ bitarray('011', 'little'))
+ self.assertRaises(ValueError, int2ba, -1)
+ self.assertRaises(TypeError, int2ba, 1.0)
+ self.assertRaises(TypeError, int2ba, 1, 3.0)
+ self.assertRaises(ValueError, int2ba, 1, 0)
+ self.assertRaises(TypeError, int2ba, 1, 10, 123)
+ self.assertRaises(ValueError, int2ba, 1, 10, 'asd')
+
+ def test_int2ba_length(self):
+ self.assertRaises(TypeError, int2ba, 0, 1.0)
+ self.assertRaises(ValueError, int2ba, 0, 0)
+ self.assertEqual(int2ba(5, length=6), bitarray('000101'))
+ self.assertRaises(OverflowError, int2ba, 3, 1)
+ for n in range(1, 100):
+ ab = int2ba(1, n, 'big')
+ al = int2ba(1, n, 'little')
+ self.assertEqual(ab.endian(), 'big')
+ self.assertEqual(al.endian(), 'little')
+ self.assertEqual(len(ab), n),
+ self.assertEqual(len(al), n)
+ self.assertEqual(ab, bitarray((n - 1) * '0') + bitarray('1'))
+ self.assertEqual(al, bitarray('1') + bitarray((n - 1) * '0'))
+
+ ab = int2ba(0, n, 'big')
+ al = int2ba(0, n, 'little')
+ self.assertEqual(len(ab), n)
+ self.assertEqual(len(al), n)
+ self.assertEqual(ab, bitarray(n * '0', 'big'))
+ self.assertEqual(al, bitarray(n * '0', 'little'))
+
+ self.assertRaises(OverflowError, int2ba, 2 ** n, n, 'big')
+ self.assertRaises(OverflowError, int2ba, 2 ** n, n, 'little')
+ self.assertEqual(int2ba(2 ** n - 1), bitarray(n * '1'))
+ self.assertEqual(int2ba(2 ** n - 1, endian='little'),
+ bitarray(n * '1'))
+
+ def test_explicit(self):
+ for i, sa in [( 0, '0'), (1, '1'),
+ ( 2, '10'), (3, '11'),
+ (25, '11001'), (265, '100001001'),
+ (3691038, '1110000101001000011110')]:
+ ab = bitarray(sa, 'big')
+ al = bitarray(sa[::-1], 'little')
+ self.assertEQUAL(int2ba(i), ab)
+ self.assertEQUAL(int2ba(i, endian='little'), al)
+ self.assertEqual(ba2int(ab), ba2int(al), i)
+ if i == 0 or i >= 512:
+ continue
+ for n in range(9, 32):
+ for endian in 'big', 'little':
+ a = int2ba(i, length=n, endian=endian)
+ self.assertEqual(a.endian(), endian)
+ self.assertEqual(len(a), n)
+ if endian == 'big':
+ f = a.index(1)
+ self.assertEqual(a[:f], bitarray(f * '0'))
+ self.assertEqual(a[f:], ab)
+
+ def check_round_trip(self, i):
+ for endian in 'big', 'little':
+ a = int2ba(i, endian=endian)
+ self.assertEqual(a.endian(), endian)
+ self.assertTrue(len(a) > 0)
+ # ensure we have no leading zeros
+ if a.endian == 'big':
+ self.assertTrue(len(a) == 1 or a.index(1) == 0)
+ self.assertEqual(ba2int(a), i)
+ if i > 0 and sys.version_info[:2] >= (2, 7):
+ self.assertEqual(i.bit_length(), len(a))
+ # add a few / trailing leading zeros to bitarray
+ if endian == 'big':
+ a = zeros(randint(0, 3), endian) + a
+ else:
+ a = a + zeros(randint(0, 3), endian)
+ self.assertEqual(a.endian(), endian)
+ self.assertEqual(ba2int(a), i)
+
+ def test_many(self):
+ for i in range(1000):
+ self.check_round_trip(i)
+ self.check_round_trip(randint(0, 10 ** randint(3, 300)))
+
+
+tests.append(TestsIntegerization)
+
+# ---------------------------------------------------------------------------
+
+class TestsHuffman(unittest.TestCase):
+
+ def test_simple(self):
+ freq = {0: 10, 'as': 2, None: 1.6}
+ code = huffman_code(freq)
+ self.assertEqual(len(code), 3)
+ self.assertEqual(len(code[0]), 1)
+ self.assertEqual(len(code['as']), 2)
+ self.assertEqual(len(code[None]), 2)
+
+ def test_tiny(self):
+ code = huffman_code({0: 0})
+ self.assertEqual(len(code), 1)
+ self.assertEqual(code, {0: bitarray()})
+
+ code = huffman_code({0: 0, 1: 0})
+ self.assertEqual(len(code), 2)
+ for i in range(2):
+ self.assertEqual(len(code[i]), 1)
+
+ def test_endianness(self):
+ freq = {'A': 10, 'B': 2, 'C': 5}
+ for endian in 'big', 'little':
+ code = huffman_code(freq, endian)
+ self.assertEqual(len(code), 3)
+ for v in code.values():
+ self.assertEqual(v.endian(), endian)
+
+ def test_wrong_arg(self):
+ self.assertRaises(TypeError, huffman_code, [('a', 1)])
+ self.assertRaises(TypeError, huffman_code, 123)
+ self.assertRaises(TypeError, huffman_code, None)
+ # cannot compare 'a' with 1
+ self.assertRaises(TypeError, huffman_code, {'A': 'a', 'B': 1})
+ self.assertRaises(ValueError, huffman_code, {})
+
+ def test_balanced(self):
+ n = 6
+ freq = {}
+ for i in range(2 ** n):
+ freq[i] = 1
+ code = huffman_code(freq)
+ self.assertEqual(len(code), 2 ** n)
+ self.assertTrue(all(len(v) == n for v in code.values()))
+
+ def test_unbalanced(self):
+ N = 27
+ freq = {}
+ for i in range(N):
+ freq[i] = 2 ** i
+ code = huffman_code(freq)
+ self.assertEqual(len(code), N)
+ for i in range(N):
+ self.assertEqual(len(code[i]), N - (1 if i <= 1 else i))
+
+ if sys.version_info[:2] >= (2, 7):
+ def test_counter(self):
+ message = 'the quick brown fox jumps over the lazy dog.'
+ code = huffman_code(Counter(message))
+ a = bitarray()
+ a.encode(code, message)
+ self.assertEqual(''.join(a.decode(code)), message)
+
+ def test_rand_list(self):
+ plain = [randint(0, 100) for _ in range(500)]
+ code = huffman_code(Counter(plain))
+ a = bitarray()
+ a.encode(code, plain)
+ self.assertEqual(a.decode(code), plain)
+
+
+tests.append(TestsHuffman)
+
+# ---------------------------------------------------------------------------
+
+def run(verbosity=1):
+ import os
+ import bitarray
+
+ print('bitarray is installed in: %s' % os.path.dirname(bitarray.__file__))
+ print('bitarray version: %s' % bitarray.__version__)
+ print('Python version: %s' % sys.version)
+
+ suite = unittest.TestSuite()
+ for cls in tests:
+ suite.addTest(unittest.makeSuite(cls))
+
+ runner = unittest.TextTestRunner(verbosity=verbosity)
+ return runner.run(suite)
+
+
+if __name__ == '__main__':
+ run()
diff --git a/shell/ext-py/bitarray-1.2.1/bitarray/util.py b/shell/ext-py/bitarray-1.2.1/bitarray/util.py
new file mode 100644
index 0000000..f2ddb40
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/bitarray/util.py
@@ -0,0 +1,274 @@
+# Copyright (c) 2019, Ilan Schnell
+# bitarray is published under the PSF license.
+#
+# Author: Ilan Schnell
+"""
+Useful utilities for working with bitarrays.
+"""
+import sys
+import heapq
+import binascii
+
+from bitarray import bitarray, frozenbitarray, bits2bytes, _bitarray
+
+from bitarray._util import (count_n, rindex,
+ count_and, count_or, count_xor, subset,
+ _set_babt)
+
+
+__all__ = ['zeros', 'rindex', 'strip', 'count_n',
+ 'count_and', 'count_or', 'count_xor', 'subset',
+ 'ba2hex', 'hex2ba', 'ba2int', 'int2ba', 'huffman_code']
+
+
+# tell the _util extension what the bitarray base type is, such that it can
+# check for instances thereof when checking for bitarray type
+_set_babt(_bitarray)
+
+_is_py2 = bool(sys.version_info[0] == 2)
+
+
+def zeros(length, endian='big'):
+ """zeros(length, /, endian='big') -> bitarray
+
+Create a bitarray of length, with all values 0.
+"""
+ if not isinstance(length, (int, long) if _is_py2 else int):
+ raise TypeError("integer expected")
+
+ a = bitarray(length, endian)
+ a.setall(0)
+ return a
+
+
+def strip(a, mode='right'):
+ """strip(bitarray, mode='right', /) -> bitarray
+
+Strip zeros from left, right or both ends.
+Allowed values for mode are the strings: `left`, `right`, `both`
+"""
+ if not isinstance(a, (bitarray, frozenbitarray)):
+ raise TypeError("bitarray expected")
+ if not isinstance(mode, str):
+ raise TypeError("string expected for mode")
+ if mode not in ('left', 'right', 'both'):
+ raise ValueError("allowed values 'left', 'right', 'both', got: %r" %
+ mode)
+ first = 0
+ if mode in ('left', 'both'):
+ try:
+ first = a.index(1)
+ except ValueError:
+ return bitarray(endian=a.endian())
+
+ last = a.length() - 1
+ if mode in ('right', 'both'):
+ try:
+ last = rindex(a)
+ except ValueError:
+ return bitarray(endian=a.endian())
+
+ return a[first:last + 1]
+
+
+def ba2hex(a):
+ """ba2hex(bitarray, /) -> hexstr
+
+Return a bytes object containing with hexadecimal representation of
+the bitarray (which has to be multiple of 4 in length).
+"""
+ if not isinstance(a, (bitarray, frozenbitarray)):
+ raise TypeError("bitarray expected")
+ if a.endian() != 'big':
+ raise ValueError("big-endian bitarray expected")
+ la = a.length()
+ if la % 4:
+ raise ValueError("bitarray length not multiple of 4")
+ if la % 8:
+ # make sure we don't mutate the original argument
+ a = a + bitarray(4, 'big')
+ assert a.length() % 8 == 0
+
+ s = binascii.hexlify(a.tobytes())
+ if la % 8:
+ s = s[:-1]
+ return s
+
+
+def hex2ba(s):
+ """hex2ba(hexstr, /) -> bitarray
+
+Bitarray of hexadecimal representation.
+hexstr may contain any number of hex digits (upper or lower case).
+"""
+ if not isinstance(s, (str, bytes)):
+ raise TypeError("string expected")
+
+ ls = len(s)
+ if ls % 2:
+ s = s + ('0' if isinstance(s, str) else b'0')
+ assert len(s) % 2 == 0
+
+ a = bitarray(endian='big')
+ a.frombytes(binascii.unhexlify(s))
+ if ls % 2:
+ del a[-4:]
+ return a
+
+
+def ba2int(a):
+ """ba2int(bitarray, /) -> int
+
+Convert the given bitarray into an integer.
+The bit-endianness of the bitarray is respected.
+"""
+ if not isinstance(a, (bitarray, frozenbitarray)):
+ raise TypeError("bitarray expected")
+ if not a:
+ raise ValueError("non-empty bitarray expected")
+
+ endian = a.endian()
+ big_endian = bool(endian == 'big')
+ if a.length() % 8:
+ # pad with leading zeros, such that length is multiple of 8
+ if big_endian:
+ a = zeros(8 - a.length() % 8, 'big') + a
+ else:
+ a = a + zeros(8 - a.length() % 8, 'little')
+ assert a.length() % 8 == 0
+ b = a.tobytes()
+
+ if _is_py2:
+ c = bytearray(b)
+ res = 0
+ j = len(c) - 1 if big_endian else 0
+ for x in c:
+ res |= x << 8 * j
+ j += -1 if big_endian else 1
+ return res
+ else: # py3
+ return int.from_bytes(b, byteorder=endian)
+
+
+def int2ba(i, length=None, endian='big'):
+ """int2ba(int, /, length=None, endian='big') -> bitarray
+
+Convert the given integer into a bitarray (with given endianness,
+and no leading (big-endian) / trailing (little-endian) zeros).
+If length is provided, the result will be of this length, and an
+`OverflowError` will be raised, if the integer cannot be represented
+within length bits.
+"""
+ if not isinstance(i, (int, long) if _is_py2 else int):
+ raise TypeError("integer expected")
+ if i < 0:
+ raise ValueError("non-negative integer expected")
+ if length is not None:
+ if not isinstance(length, int):
+ raise TypeError("integer expected for length")
+ if length <= 0:
+ raise ValueError("integer larger than 0 expected for length")
+ if not isinstance(endian, str):
+ raise TypeError("string expected for endian")
+ if endian not in ('big', 'little'):
+ raise ValueError("endian can only be 'big' or 'little'")
+
+ if i == 0:
+ # there a special cases for 0 which we'd rather not deal with below
+ return zeros(length or 1, endian=endian)
+
+ big_endian = bool(endian == 'big')
+ if _is_py2:
+ c = bytearray()
+ while i:
+ i, r = divmod(i, 256)
+ c.append(r)
+ if big_endian:
+ c.reverse()
+ b = bytes(c)
+ else: # py3
+ b = i.to_bytes(bits2bytes(i.bit_length()), byteorder=endian)
+
+ a = bitarray(endian=endian)
+ a.frombytes(b)
+ la = a.length()
+ if la == length:
+ return a
+
+ if length is None:
+ return strip(a, 'left' if big_endian else 'right')
+
+ if la > length:
+ size = (la - a.index(1)) if big_endian else (rindex(a) + 1)
+ if size > length:
+ raise OverflowError("cannot represent %d bit integer in "
+ "%d bits" % (size, length))
+ a = a[la - length:] if big_endian else a[:length - la]
+
+ if la < length:
+ if big_endian:
+ a = zeros(length - la, 'big') + a
+ else:
+ a += zeros(length - la, 'little')
+
+ assert a.length() == length
+ return a
+
+
+def huffman_code(freq_map, endian='big'):
+ """huffman_code(dict, /, endian='big') -> dict
+
+Given a frequency map, a dictionary mapping symbols to thier frequency,
+calculate the Huffman code, i.e. a dict mapping those symbols to
+bitarrays (with given endianness). Note that the symbols may be any
+hashable object (including `None`).
+"""
+ if not isinstance(freq_map, dict):
+ raise TypeError("dict expected")
+ if len(freq_map) == 0:
+ raise ValueError("non-empty dict expected")
+
+ class Node(object):
+ # a Node object will have either .symbol or .child set below,
+ # .freq will always be set
+ def __lt__(self, other):
+ # heapq needs to be able to compare the nodes
+ return self.freq < other.freq
+
+ def huff_tree(freq_map):
+ # given a dictionary mapping symbols to thier frequency,
+ # construct a Huffman tree and return its root node
+
+ minheap = []
+ # create all the leaf nodes and push them onto the queue
+ for sym, f in freq_map.items():
+ nd = Node()
+ nd.symbol = sym
+ nd.freq = f
+ heapq.heappush(minheap, nd)
+
+ # repeat the process until only one node remains
+ while len(minheap) > 1:
+ # take the nodes with smallest frequencies from the queue
+ child_0 = heapq.heappop(minheap)
+ child_1 = heapq.heappop(minheap)
+ # construct the new internal node and push it onto the queue
+ parent = Node()
+ parent.child = [child_0, child_1]
+ parent.freq = child_0.freq + child_1.freq
+ heapq.heappush(minheap, parent)
+
+ # the single remaining node is the root of the Huffman tree
+ return minheap[0]
+
+ result = {}
+
+ def traverse(nd, prefix=bitarray(endian=endian)):
+ if hasattr(nd, 'symbol'): # leaf
+ result[nd.symbol] = prefix
+ else: # parent, so traverse each of the children
+ traverse(nd.child[0], prefix + bitarray([0]))
+ traverse(nd.child[1], prefix + bitarray([1]))
+
+ traverse(huff_tree(freq_map))
+ return result
diff --git a/shell/ext-py/bitarray-0.9.0/setup.py b/shell/ext-py/bitarray-1.2.1/setup.py
similarity index 86%
rename from shell/ext-py/bitarray-0.9.0/setup.py
rename to shell/ext-py/bitarray-1.2.1/setup.py
index 0473b1f..363be01 100644
--- a/shell/ext-py/bitarray-0.9.0/setup.py
+++ b/shell/ext-py/bitarray-1.2.1/setup.py
@@ -5,7 +5,7 @@ from distutils.core import setup, Extension
kwds = {}
try:
- kwds['long_description'] = open('README.rst').read()
+ kwds['long_description'] = open('README.md').read()
except IOError:
pass
@@ -28,7 +28,6 @@ setup(
"Operating System :: OS Independent",
"Programming Language :: C",
"Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.5",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
@@ -37,11 +36,14 @@ setup(
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
"Topic :: Utilities",
],
description = "efficient arrays of booleans -- C extension",
packages = ["bitarray"],
ext_modules = [Extension(name = "bitarray._bitarray",
- sources = ["bitarray/_bitarray.c"])],
+ sources = ["bitarray/_bitarray.c"]),
+ Extension(name = "bitarray._util",
+ sources = ["bitarray/_util.c"])],
**kwds
)
diff --git a/shell/ext-py/bitarray-1.2.1/update_readme.py b/shell/ext-py/bitarray-1.2.1/update_readme.py
new file mode 100644
index 0000000..985597c
--- /dev/null
+++ b/shell/ext-py/bitarray-1.2.1/update_readme.py
@@ -0,0 +1,112 @@
+import sys
+if not sys.version_info[0] == 3:
+ sys.exit("This program only runs with Python 3, sorry :-(")
+
+import re
+import doctest
+from io import StringIO
+
+import bitarray
+import bitarray.util
+
+
+fo = StringIO()
+
+
+def write_changelog():
+ fo.write("Change log\n"
+ "----------\n\n")
+ ver_pat = re.compile(r'(\d{4}-\d{2}-\d{2})\s+(\d+\.\d+\.\d+)')
+ count = 0
+ for line in open('CHANGE_LOG'):
+ m = ver_pat.match(line)
+ if m:
+ if count == 3:
+ break
+ count += 1
+ fo.write(m.expand(r'*\2* (\1):\n'))
+ elif line.startswith('---'):
+ fo.write('\n')
+ else:
+ fo.write(line)
+
+ url = "https://github.com/ilanschnell/bitarray/blob/master/CHANGE_LOG"
+ fo.write('Please find the complete change log\n'
+ '<a href="%s">here</a>.\n' % url)
+
+
+sig_pat = re.compile(r'(\w+\([^()]*\))( -> (.+))?')
+def write_doc(name):
+ doc = eval('bitarray.%s.__doc__' % name)
+ lines = doc.splitlines()
+ m = sig_pat.match(lines[0])
+ if m is None:
+ raise Exception("signature line invalid: %r" % lines[0])
+ s = '`%s`' % m.group(1)
+ if m.group(3):
+ s += ' -> %s' % m.group(3)
+ fo.write(s + '\n\n')
+ assert lines[1] == ''
+ for line in lines[2:]:
+ fo.write(line.rstrip() + '\n')
+ fo.write('\n\n')
+
+
+def write_reference():
+ fo.write("Reference\n"
+ "=========\n\n"
+ "The bitarray object:\n"
+ "--------------------\n\n")
+ write_doc('bitarray')
+
+ fo.write("**A bitarray object supports the following methods:**\n\n")
+ for method in sorted(dir(bitarray.bitarray)):
+ if method.startswith('_'):
+ continue
+ write_doc('bitarray.%s' % method)
+
+ fo.write("The frozenbitarray object:\n"
+ "--------------------------\n\n")
+ write_doc('frozenbitarray')
+
+ fo.write("Functions defined in the module:\n"
+ "--------------------------------\n\n")
+ write_doc('test')
+ write_doc('bitdiff')
+ write_doc('bits2bytes')
+
+ fo.write("Functions defined in bitarray.util:\n"
+ "-----------------------------------\n\n")
+ for func in bitarray.util.__all__:
+ write_doc('util.%s' % func)
+
+
+def write_all(data):
+ ver_pat = re.compile(r'(bitarray.+?)(\d+\.\d+\.\d+)')
+ for line in data.splitlines():
+ if line == 'Reference':
+ break
+ line = ver_pat.sub(lambda m: m.group(1) + bitarray.__version__, line)
+ fo.write(line + '\n')
+
+ write_reference()
+ write_changelog()
+
+
+def main():
+ data = open('README.md').read()
+ write_all(data)
+ new_data = fo.getvalue()
+ fo.close()
+
+ if new_data == data:
+ print("already up-to-date")
+ else:
+ with open('README.md', 'w') as f:
+ f.write(new_data)
+
+ doctest.testfile('README.md')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/shell/packaging/requirements.txt b/shell/packaging/requirements.txt
index 84bfe80..00e7f3c 100644
--- a/shell/packaging/requirements.txt
+++ b/shell/packaging/requirements.txt
@@ -1,4 +1,4 @@
-bitarray==1.0.1
+bitarray==1.2.1
configparser==4.0.2
prettytable==0.7.2
sasl==0.2.1