Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
d21b56c
Starting on v5.0
scott-griffiths Mar 11, 2026
3825275
Removing more bitarray - replacing with tibs when needed.
scott-griffiths Mar 11, 2026
906411a
Moving the common helpers.
scott-griffiths Mar 11, 2026
732e6eb
Renaming bitstore_tibs_helpers.py to bitstore_helpers.py
scott-griffiths Mar 11, 2026
636df3f
Renaming _bits to tibs.
scott-griffiths Mar 12, 2026
ad7f087
Fix for signed ints > 128 bits not being interpreted correctly.
scott-griffiths Mar 12, 2026
cbd1f8f
Using the constructors instead of from_tibs and from_mutibs methods.
scott-griffiths Mar 13, 2026
b314d75
A few simplifications.
scott-griffiths Mar 14, 2026
59f5dd6
Defaulting more to Mutibs during construction.
scott-griffiths Mar 14, 2026
0efbd29
Fixes for upgrade to tibs 0.6.
Apr 3, 2026
6812800
Removing some validation that's not needed any more as tibs is doing it.
Apr 3, 2026
fbc0236
Better encapsulation of tibs and using more of its methods.
Apr 4, 2026
362f91c
Removing duplicated length check.
Apr 4, 2026
ebaff1c
Factoring out mutibs creation from ints.
Apr 4, 2026
afa1b55
Using tibs.__iter__ directly.
Apr 4, 2026
409a797
Updating to use tibs 0.7.
May 4, 2026
1dc5936
Removing lsb0 mode.
May 5, 2026
49a06f4
Fix to use find_all_iter.
May 5, 2026
fd1a31b
Removing deprecated way of setting module options.
May 5, 2026
cfe15e6
Fix to return type if ilshift and irshift for MutableBitStore.
May 9, 2026
1e0c1b2
Fix for some comparisons raising AttributeError
May 9, 2026
8919cbb
Allowing 0 as a factor when expanding brackets.
May 9, 2026
08720d0
Fix for other correct inplace Array return types.
May 9, 2026
d014786
Scale should be used in Dtype comparisons.
May 9, 2026
fc9ca95
Check for negative factors in tokens.
May 9, 2026
21e5764
Don't let reinitialising the Options reset them.
May 9, 2026
38a20a1
Better array insert clamping.
May 9, 2026
38b0156
A few fixes for Array.fromfile, plus some AI generated unit tests.
May 9, 2026
b295348
Using offset and length of Tibs.from_bytes to improve performance.
May 9, 2026
5b7f144
Don't always read file into memory if offset given.
May 9, 2026
12170fc
Removing deprecated old options.
May 9, 2026
7456cfc
Fix to make ConstBitStore the default. Surprisingly big speed up :)
May 9, 2026
8d7b4de
More ConstBitStore correctness.
May 9, 2026
46ac240
More small performance improvements.
May 9, 2026
528517b
Fast path for cut with a const bitstore.
May 9, 2026
f692a1e
Adding explicit read methods instead of using get allows for reads to…
May 25, 2026
0031b9f
Upping tibs version dependency to 0.9
May 27, 2026
7e51d71
Using start and end parameters on Tibs to_xxx methods.
May 27, 2026
10aa76e
Updating to tibs 0.10 and using new methods from it to simplify things.
Jun 20, 2026
23ebc90
Removing BitStream and ConstBitstream classes.
Jun 20, 2026
7a7bb48
Some tibs simplifications.
Jun 20, 2026
2e52b82
Change to find return. Now returns int | None instead of a tuple.
Jun 20, 2026
64d030d
Making many positional arguments keyword only. This can help prevent …
Jun 20, 2026
df66f36
Removing support for Python 3.8 and 3.9 as they are end of life.
Jun 20, 2026
7ac1c44
Upgrading to Python 3.10 syntax for types.
Jun 20, 2026
5d87f9c
Removing command-line usage. I don't think anyone ever actually used it.
Jun 20, 2026
a67a75e
Pack returns a Bits instead of a BitArray.
Jun 20, 2026
435a63c
Implemented the first factory/conversion pass.
Jun 20, 2026
3d2e9e5
Renaming Dtype build/parse to pack/unpack.
Jun 20, 2026
2601549
Changed:
Jun 20, 2026
7a4b8ae
Fix to array itemsize bug, plus bug when counting non numeric array i…
Jun 20, 2026
60a11d0
Various cleanups and efficiency improvements.
Jun 20, 2026
900b2c8
A bunch of docs fixes.
Jun 20, 2026
f0c3c16
Upgrading to v5 guide.
Jun 20, 2026
1530a2e
Removing the b/o/h aliases for bin/oct/hex.
Jun 21, 2026
a36512c
Now preferring the u/i/f names to uint/int/float, but the others rema…
Jun 21, 2026
fa6a27d
Also preferring the u/i/f names to uint/int/float when used as constr…
Jun 21, 2026
ab78465
New preferred naming of ule etc. instead of uintle.
Jun 21, 2026
69e937a
Re-adding fromstring as a compatibility alias to from_string.
Jun 21, 2026
dae8cc8
Refactoring the overflow mode out of the options and into the types t…
Jun 21, 2026
9e161f0
Updating readme.
Jun 21, 2026
2c68894
Updating to tibs 0.11.
Jun 27, 2026
ededc44
Updating to tibs 0.12.
Jul 5, 2026
ed5d4f7
Prep for merging to main.
Jul 5, 2026
e60769c
Adding methods for from_tibs and to_tibs.
Jul 5, 2026
68a9886
Making Tibs and Mutibs 'bits-like' types so they can be promoted to B…
Jul 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 2 additions & 117 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
# and then finally an actual release version. actions/setup-python doesn't
# support this for PyPy presently so we get no help there.
#
# CPython -> 3.9.0-alpha - 3.9.X
# CPython -> 3.10.0-alpha - 3.10.X
# PyPy -> pypy-3.7
# python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python.action), matrix.python.action))[startsWith(matrix.python.action, 'pypy')] }}
# architecture: x64
Expand Down Expand Up @@ -82,12 +82,6 @@ jobs:
- name: 🪟
runs-on: windows-latest
python:
- name: CPython 3.8
major_dot_minor: '3.8'
action: '3.8'
- name: CPython 3.9
major_dot_minor: '3.9'
action: '3.9'
- name: CPython 3.10
major_dot_minor: '3.10'
action: '3.10'
Expand All @@ -104,20 +98,6 @@ jobs:
major_dot_minor: '3.14'
action: '3.14'
exclude:
- os:
name: "🍎"
runs-on: macos-15
python:
name: "CPython 3.8"
major_dot_minor: '3.8'
action: '3.8'
- os:
name: "🍎"
runs-on: macos-15
python:
name: "CPython 3.9"
major_dot_minor: '3.9'
action: '3.9'
- os:
name: "🍎"
runs-on: macos-15
Expand All @@ -144,7 +124,7 @@ jobs:
# and then finally an actual release version. actions/setup-python doesn't
# support this for PyPy presently so we get no help there.
#
# CPython -> 3.9.0-alpha - 3.9.X
# CPython -> 3.10.0-alpha - 3.10.X
# PyPy -> pypy-3.7
python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python.action), matrix.python.action))[startsWith(matrix.python.action, 'pypy')] }}
architecture: x64
Expand All @@ -160,100 +140,6 @@ jobs:
ls -la

- name: Run pytest
env:
BITSTRING_USE_RUST_CORE: ${{ matrix.rust.env_var }}
run: |
python -m pytest tests/ --benchmark-disable

test-rust:
name: Test ${{ matrix.os.name }} ${{ matrix.python.name }} (Rust core)
if: always()
needs:
- test-standard
runs-on: ${{ matrix.os.runs-on }}
strategy:
fail-fast: false
matrix:
os:
- name: 🐧
runs-on: ubuntu-latest
- name: 🍎
runs-on: macos-15
- name: 🪟
runs-on: windows-latest
python:
- name: CPython 3.8
major_dot_minor: '3.8'
action: '3.8'
- name: CPython 3.9
major_dot_minor: '3.9'
action: '3.9'
- name: CPython 3.10
major_dot_minor: '3.10'
action: '3.10'
- name: CPython 3.11
major_dot_minor: '3.11'
action: '3.11'
- name: CPython 3.12
major_dot_minor: '3.12'
action: '3.12'
- name: CPython 3.13
major_dot_minor: '3.13'
action: '3.13'
- name: CPython 3.14
major_dot_minor: '3.14'
action: '3.14'
exclude:
- os:
name: "🍎"
runs-on: macos-15
python:
name: "CPython 3.8"
major_dot_minor: '3.8'
action: '3.8'
- os:
name: "🍎"
runs-on: macos-15
python:
name: "CPython 3.9"
major_dot_minor: '3.9'
action: '3.9'
- os:
name: "🍎"
runs-on: macos-15
python:
name: "CPython 3.10"
major_dot_minor: '3.10'
action: '3.10'
steps:
- uses: actions/checkout@v4
with:
path: repo

- name: Download package files
uses: actions/download-artifact@v4
with:
name: packages
path: dist

- uses: actions/setup-python@v5
with:
python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python.action), matrix.python.action))[startsWith(matrix.python.action, 'pypy')] }}
architecture: x64

- name: Setup environment
run: |
python --version --version
# make sure we test the installed code
cp -R repo/tests/ tests/
python -m pip install -r tests/requirements.txt
python -m pip install ./dist/*.whl
# show the directory contents for diagnostics
ls -la

- name: Run pytest
env:
BITSTRING_USE_RUST_CORE: '1'
run: |
python -m pytest tests/ --benchmark-disable

Expand All @@ -268,7 +154,6 @@ jobs:
# a merge.
- build
- test-standard
- test-rust
steps:
- name: Require all successes
uses: re-actors/alls-green@v1.2.2
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ build
dist
manifest
*egg-info
doc/_build
doc/_build
/.hypothesis/
/doc/html/
/html/
/tests/.hypothesis/
/uv.lock
102 changes: 82 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,70 @@
----

> [!NOTE]
> To see what been added, improved or fixed, and also to see what's coming in the next version, see the [release notes](https://github.com/scott-griffiths/bitstring/blob/main/release_notes.md).
> To see what's been added, improved or fixed, and also to see what's coming in the next version, see the [release notes](https://github.com/scott-griffiths/bitstring/blob/main/release_notes.md).

# News
> [!IMPORTANT]
> The `main` branch now contains the upcoming bitstring 5.0 work. It is visible here for testing and feedback, but it is not the current released version. The released PyPI line is still bitstring 4.x; use `pip install bitstring` or pin `bitstring<5` for the stable API. Source maintenance for 4.x is on the `4.x-maintenance` branch.

I'm rewriting the core of bitstring in Rust, and have released that cut-down and streamlined interface as the [tibs](https://github.com/scott-griffiths/tibs) package. It's now in beta, and feedback is welcome. Just `pip install tibs` to try it out.
# Version 5.0 preview

Version 5.0 of bitstring is in development. This is a major update with breaking changes.

Reasons to upgrade include:

* Significantly better performance using the new [tibs](https://github.com/scott-griffiths/tibs) Rust core.
* A simpler model for sequential reading: `Bits` and `BitArray` store data, while `Reader` stores the current bit position.
* A clearer, more explicit API for construction, conversion and dtype names.
* Removal of old compatibility layers, including the `bitarray` dependency, LSB0 mode and the old stream classes.
* A smaller internal codebase that should be easier to maintain and optimise further.

## Upgrading from version 4

If you have arrived here because bitstring 5 development work broke your code, the most practical fix may be to pin the latest version 4 release for now:

```bash
pip install "bitstring<5"
```

Version 5 is worth moving to if you need the improved performance, want the cleaner current API, or want to keep up to
date with future bitstring development. The changes are quite broad, so if your existing code is stable and performance
is not a problem, there is no need to migrate immediately.

For details on the source changes you may need, see the [Upgrading to version 5](https://bitstring.readthedocs.io/en/latest/upgrading_to_version_5.html) guide.

## What's this 'tibs' thing that everyone is talking about?

bitstring 5 is built on [tibs](https://github.com/scott-griffiths/tibs), a simpler and more focussed Python library for
binary data, written in Rust for speed. It's by the same author as bitstring so they can complement each other's needs.
If you want a leaner interface and do not need all of bitstring's higher-level format handling and historical API, tibs may be a better fit for new code.

Tibs is still in beta but I would like it to get a wider range of users before hitting 1.0. Try it with:

```bash
pip install tibs
```

Bitstring accepts tibs objects anywhere a bitstring-like value is expected:

```python
from bitstring import Bits
from tibs import Mutibs, Tibs

tibs_obj = Tibs.from_bin("1010")
bits = Bits(tibs_obj) # or Bits.from_tibs(tibs_obj)
same_data = bits.to_tibs()

mutable = Mutibs.from_bin("111")
bits_copy = Bits.from_tibs(mutable) # Mutibs inputs are copied
```

[![tibs](https://raw.githubusercontent.com/scott-griffiths/tibs/main/doc/tibs.png)](https://github.com/scott-griffiths/tibs)

A sleek Python library for your binary data

----

# Overview
# Bitstring Overview

* Efficiently store and manipulate binary data in idiomatic Python.
* Create bitstrings from hex, octal, binary, files, formatted strings, bytes, integers and floats of different endiannesses.
Expand All @@ -43,33 +95,43 @@ A sleek Python library for your binary data
Extensive documentation for the bitstring library is available.
Some starting points are given below:

* [Overview](https://bitstring.readthedocs.io/en/stable/index.html)
* [Quick Reference](https://bitstring.readthedocs.io/en/stable/quick_reference.html)
* [Full Reference](https://bitstring.readthedocs.io/en/stable/reference.html)
* [Released 4.x documentation](https://bitstring.readthedocs.io/en/stable/)
* [Upcoming 5.0 documentation](https://bitstring.readthedocs.io/en/latest/)
* [Upgrading from 4.x to 5.0](https://bitstring.readthedocs.io/en/latest/upgrading_to_version_5.html)

There is also an introductory walkthrough notebook on [binder](https://mybinder.org/v2/gh/scott-griffiths/bitstring/main?labpath=doc%2Fwalkthrough.ipynb).
There is also an introductory walkthrough notebook for the 5.0 branch on [binder](https://mybinder.org/v2/gh/scott-griffiths/bitstring/main?labpath=doc%2Fwalkthrough.ipynb).

# Examples

These examples show the upcoming 5.0 API from `main`.

### Installation
```
Released 4.x version:

```bash
$ pip install bitstring
```

5.0 preview from `main`:

```bash
$ pip install "bitstring @ git+https://github.com/scott-griffiths/bitstring.git@main"
```

### Creation
```pycon
>>> from bitstring import Bits, BitArray, BitStream, pack
>>> from bitstring import Bits, BitArray, Reader, pack
>>> a = BitArray(bin='00101')
>>> b = Bits(a_file_object)
>>> c = BitArray('0xff, 0b101, 0o65, uint6=22')
>>> d = pack('intle16, hex=a, 0b1', 100, a='0x34f')
>>> b = Bits.from_file(a_file_object)
>>> c = BitArray('0xff, 0b101, 0o65, u6=22')
>>> d = pack('ile16, hex=a, 0b1', 100, a='0x34f')
>>> e = pack('<16h', *range(16))
```

### Different interpretations, slicing and concatenation
```pycon
>>> a = BitArray('0x3348')
>>> a.hex, a.bin, a.uint, a.float, a.bytes
>>> a.hex, a.bin, a.u, a.f, a.bytes
('3348', '0011001101001000', 13128, 0.2275390625, b'3H')
>>> a[10:3:-1].bin
'0101100'
Expand All @@ -79,21 +141,21 @@ BitArray('0x866906690669, 0b000')

### Reading data sequentially
```pycon
>>> b = BitStream('0x160120f')
>>> b = Reader(Bits('0x160120f'))
>>> b.read(12).hex
'160'
>>> b.pos = 0
>>> b.read('uint12')
>>> b.read('u12')
352
>>> b.readlist('uint12, bin3')
>>> b.read_list('u12, bin3')
[288, '111']
```

### Searching, inserting and deleting
```pycon
>>> c = BitArray('0b00010010010010001111') # c.hex == '0x1248f'
>>> c.find('0x48')
(8,)
8
>>> c.replace('0b001', '0xabc')
>>> c.insert('0b0000', pos=3)
>>> del c[12:16]
Expand All @@ -102,12 +164,12 @@ BitArray('0x866906690669, 0b000')
### Arrays of fixed-length formats
```pycon
>>> from bitstring import Array
>>> a = Array('uint7', [9, 100, 3, 1])
>>> a = Array('u7', [9, 100, 3, 1])
>>> a.data
BitArray('0x1390181')
>>> a[::2] *= 5
>>> a
Array('uint7', [45, 100, 15, 1])
Array('u7', [45, 100, 15, 1])
```


Expand Down
Loading