bitstring 4.2.2__tar.gz → 4.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bitstring-4.2.2 → bitstring-4.3.0}/LICENSE +1 -1
- {bitstring-4.2.2 → bitstring-4.3.0}/MANIFEST.in +1 -1
- {bitstring-4.2.2/bitstring.egg-info → bitstring-4.3.0}/PKG-INFO +63 -76
- bitstring-4.3.0/README.md +109 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/__init__.py +33 -14
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/__main__.py +1 -1
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/array_.py +14 -12
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/bitarray_.py +3 -4
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/bits.py +21 -23
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/bitstore.py +35 -21
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/bitstore_helpers.py +11 -1
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/bitstream.py +1 -1
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/bitstring_options.py +2 -1
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/dtypes.py +3 -4
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/exceptions.py +0 -1
- bitstring-4.3.0/bitstring/luts.py +245 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/mxfp.py +19 -13
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/utils.py +14 -6
- {bitstring-4.2.2 → bitstring-4.3.0/bitstring.egg-info}/PKG-INFO +63 -76
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring.egg-info/SOURCES.txt +2 -1
- bitstring-4.3.0/bitstring.egg-info/requires.txt +1 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/pyproject.toml +3 -2
- bitstring-4.2.2/release_notes.txt → bitstring-4.3.0/release_notes.md +758 -689
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_array.py +1 -1
- bitstring-4.3.0/tests/test_benchmarks.py +72 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_bitarray.py +3 -3
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_bits.py +55 -30
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_bitstream.py +12 -4
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_mxfp.py +26 -0
- bitstring-4.2.2/README.md +0 -123
- bitstring-4.2.2/bitstring/luts.py +0 -248
- bitstring-4.2.2/bitstring.egg-info/requires.txt +0 -1
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/fp8.py +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/methods.py +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring/py.typed +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring.egg-info/dependency_links.txt +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/bitstring.egg-info/top_level.txt +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/setup.cfg +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/__init__.py +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/smalltestfile +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test.m1v +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_bitstore.py +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_bitstring.py +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_constbitstream.py +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_dtypes.py +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_fp8.py +0 -0
- {bitstring-4.2.2 → bitstring-4.3.0}/tests/test_scaled_dtypes.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
The MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2006 Scott Griffiths (dr.scottgriffiths@gmail.com)
|
|
3
|
+
Copyright (c) 2006-2025 Scott Griffiths (dr.scottgriffiths@gmail.com)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bitstring
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: Simple construction, analysis and modification of binary data.
|
|
5
5
|
Author-email: Scott Griffiths <dr.scottgriffiths@gmail.com>
|
|
6
6
|
Project-URL: homepage, https://github.com/scott-griffiths/bitstring
|
|
@@ -15,20 +15,21 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
19
|
Classifier: License :: OSI Approved :: MIT License
|
|
19
20
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
21
|
Requires-Python: >=3.8
|
|
21
22
|
Description-Content-Type: text/markdown
|
|
22
23
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: bitarray<3.
|
|
24
|
+
Requires-Dist: bitarray<3.1,>=3.0.0
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|

|
|
28
29
|
|
|
29
|
-
**bitstring** is a Python
|
|
30
|
+
**bitstring** is a Python library to help make the creation and analysis of all types of bit-level binary data as simple and efficient as possible. It has been actively maintained since 2006.
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
The library has has now been downloaded over 100 million times! ✨ [](https://www.pepy.tech/projects/bitstring) ✨
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
|
|
@@ -37,29 +38,16 @@ It has been actively maintained since 2006.
|
|
|
37
38
|
[](https://app.codacy.com/gh/scott-griffiths/bitstring/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
|
38
39
|
[](https://libraries.io/pypi/bitstring)
|
|
39
40
|
|
|
40
|
-
[](https://www.pepy.tech/projects/bitstring)
|
|
41
42
|
[](https://pypistats.org/packages/bitstring)
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
News
|
|
45
44
|
----
|
|
46
|
-
**May 2024**: bitstring 4.2.2 released.
|
|
47
|
-
|
|
48
|
-
New in version 4.2:
|
|
49
|
-
|
|
50
|
-
* Dropped support for Python 3.7. Minimum version is now 3.8.
|
|
51
|
-
* A new `Dtype` class can be optionally used to specify types.
|
|
52
|
-
* The `bitstring.options` object is now the preferred method for changing module options.
|
|
53
|
-
* New `fromstring` method as another way to create bitstrings from formatted strings.
|
|
54
|
-
* More types can now be pretty printed.
|
|
55
|
-
* A range of 8-bit, 6-bit and even 4-bit floating point formats added (beta):
|
|
56
|
-
* Performance improvements.
|
|
57
45
|
|
|
58
|
-
|
|
46
|
+
> [!NOTE]
|
|
47
|
+
> 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).
|
|
59
48
|
|
|
60
49
|
|
|
61
|
-
Overview
|
|
62
|
-
--------
|
|
50
|
+
# Overview
|
|
63
51
|
|
|
64
52
|
* Efficiently store and manipulate binary data in idiomatic Python.
|
|
65
53
|
* Create bitstrings from hex, octal, binary, files, formatted strings, bytes, integers and floats of different endiannesses.
|
|
@@ -70,9 +58,9 @@ Overview
|
|
|
70
58
|
* Rich API - chances are that whatever you want to do there's a simple and elegant way of doing it.
|
|
71
59
|
* Open source software, released under the MIT licence.
|
|
72
60
|
|
|
73
|
-
Documentation
|
|
74
|
-
|
|
75
|
-
Extensive documentation for the bitstring
|
|
61
|
+
# Documentation
|
|
62
|
+
|
|
63
|
+
Extensive documentation for the bitstring library is available.
|
|
76
64
|
Some starting points are given below:
|
|
77
65
|
|
|
78
66
|
* [Overview](https://bitstring.readthedocs.io/en/stable/index.html)
|
|
@@ -81,67 +69,66 @@ Some starting points are given below:
|
|
|
81
69
|
|
|
82
70
|
There is also an introductory walkthrough notebook on [binder](https://mybinder.org/v2/gh/scott-griffiths/bitstring/main?labpath=doc%2Fwalkthrough.ipynb).
|
|
83
71
|
|
|
84
|
-
|
|
85
|
-
-------------
|
|
86
|
-
|
|
87
|
-
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.txt).
|
|
88
|
-
|
|
89
|
-
Examples
|
|
90
|
-
--------
|
|
72
|
+
# Examples
|
|
91
73
|
|
|
92
74
|
### Installation
|
|
93
|
-
|
|
94
|
-
|
|
75
|
+
```
|
|
76
|
+
$ pip install bitstring
|
|
77
|
+
```
|
|
95
78
|
|
|
96
79
|
### Creation
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
80
|
+
```pycon
|
|
81
|
+
>>> from bitstring import Bits, BitArray, BitStream, pack
|
|
82
|
+
>>> a = BitArray(bin='00101')
|
|
83
|
+
>>> b = Bits(a_file_object)
|
|
84
|
+
>>> c = BitArray('0xff, 0b101, 0o65, uint6=22')
|
|
85
|
+
>>> d = pack('intle16, hex=a, 0b1', 100, a='0x34f')
|
|
86
|
+
>>> e = pack('<16h', *range(16))
|
|
87
|
+
```
|
|
104
88
|
|
|
105
89
|
### Different interpretations, slicing and concatenation
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
90
|
+
```pycon
|
|
91
|
+
>>> a = BitArray('0x3348')
|
|
92
|
+
>>> a.hex, a.bin, a.uint, a.float, a.bytes
|
|
93
|
+
('3348', '0011001101001000', 13128, 0.2275390625, b'3H')
|
|
94
|
+
>>> a[10:3:-1].bin
|
|
95
|
+
'0101100'
|
|
96
|
+
>>> '0b100' + 3*a
|
|
97
|
+
BitArray('0x866906690669, 0b000')
|
|
98
|
+
```
|
|
114
99
|
|
|
115
100
|
### Reading data sequentially
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
101
|
+
```pycon
|
|
102
|
+
>>> b = BitStream('0x160120f')
|
|
103
|
+
>>> b.read(12).hex
|
|
104
|
+
'160'
|
|
105
|
+
>>> b.pos = 0
|
|
106
|
+
>>> b.read('uint12')
|
|
107
|
+
352
|
|
108
|
+
>>> b.readlist('uint12, bin3')
|
|
109
|
+
[288, '111']
|
|
110
|
+
```
|
|
125
111
|
|
|
126
112
|
### Searching, inserting and deleting
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
113
|
+
```pycon
|
|
114
|
+
>>> c = BitArray('0b00010010010010001111') # c.hex == '0x1248f'
|
|
115
|
+
>>> c.find('0x48')
|
|
116
|
+
(8,)
|
|
117
|
+
>>> c.replace('0b001', '0xabc')
|
|
118
|
+
>>> c.insert('0b0000', pos=3)
|
|
119
|
+
>>> del c[12:16]
|
|
120
|
+
```
|
|
134
121
|
|
|
135
122
|
### Arrays of fixed-length formats
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
<sub>Copyright (c) 2006 -
|
|
123
|
+
```pycon
|
|
124
|
+
>>> from bitstring import Array
|
|
125
|
+
>>> a = Array('uint7', [9, 100, 3, 1])
|
|
126
|
+
>>> a.data
|
|
127
|
+
BitArray('0x1390181')
|
|
128
|
+
>>> a[::2] *= 5
|
|
129
|
+
>>> a
|
|
130
|
+
Array('uint7', [45, 100, 15, 1])
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
<sub>Copyright (c) 2006 - 2025 Scott Griffiths</sub>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
**bitstring** is a Python library to help make the creation and analysis of all types of bit-level binary data as simple and efficient as possible. It has been actively maintained since 2006.
|
|
6
|
+
|
|
7
|
+
The library has has now been downloaded over 100 million times! ✨ [](https://www.pepy.tech/projects/bitstring) ✨
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
[](https://github.com/scott-griffiths/bitstring/actions/workflows/ci.yml)
|
|
12
|
+
[](https://bitstring.readthedocs.io/en/latest/)
|
|
13
|
+
[](https://app.codacy.com/gh/scott-griffiths/bitstring/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
|
14
|
+
[](https://libraries.io/pypi/bitstring)
|
|
15
|
+
|
|
16
|
+
[](https://www.pepy.tech/projects/bitstring)
|
|
17
|
+
[](https://pypistats.org/packages/bitstring)
|
|
18
|
+
|
|
19
|
+
----
|
|
20
|
+
|
|
21
|
+
> [!NOTE]
|
|
22
|
+
> 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).
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Overview
|
|
26
|
+
|
|
27
|
+
* Efficiently store and manipulate binary data in idiomatic Python.
|
|
28
|
+
* Create bitstrings from hex, octal, binary, files, formatted strings, bytes, integers and floats of different endiannesses.
|
|
29
|
+
* Powerful binary packing and unpacking functions.
|
|
30
|
+
* Bit-level slicing, joining, searching, replacing and more.
|
|
31
|
+
* Create and manipulate arrays of fixed-length bitstrings.
|
|
32
|
+
* Read from and interpret bitstrings as streams of binary data.
|
|
33
|
+
* Rich API - chances are that whatever you want to do there's a simple and elegant way of doing it.
|
|
34
|
+
* Open source software, released under the MIT licence.
|
|
35
|
+
|
|
36
|
+
# Documentation
|
|
37
|
+
|
|
38
|
+
Extensive documentation for the bitstring library is available.
|
|
39
|
+
Some starting points are given below:
|
|
40
|
+
|
|
41
|
+
* [Overview](https://bitstring.readthedocs.io/en/stable/index.html)
|
|
42
|
+
* [Quick Reference](https://bitstring.readthedocs.io/en/stable/quick_reference.html)
|
|
43
|
+
* [Full Reference](https://bitstring.readthedocs.io/en/stable/reference.html)
|
|
44
|
+
|
|
45
|
+
There is also an introductory walkthrough notebook on [binder](https://mybinder.org/v2/gh/scott-griffiths/bitstring/main?labpath=doc%2Fwalkthrough.ipynb).
|
|
46
|
+
|
|
47
|
+
# Examples
|
|
48
|
+
|
|
49
|
+
### Installation
|
|
50
|
+
```
|
|
51
|
+
$ pip install bitstring
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Creation
|
|
55
|
+
```pycon
|
|
56
|
+
>>> from bitstring import Bits, BitArray, BitStream, pack
|
|
57
|
+
>>> a = BitArray(bin='00101')
|
|
58
|
+
>>> b = Bits(a_file_object)
|
|
59
|
+
>>> c = BitArray('0xff, 0b101, 0o65, uint6=22')
|
|
60
|
+
>>> d = pack('intle16, hex=a, 0b1', 100, a='0x34f')
|
|
61
|
+
>>> e = pack('<16h', *range(16))
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Different interpretations, slicing and concatenation
|
|
65
|
+
```pycon
|
|
66
|
+
>>> a = BitArray('0x3348')
|
|
67
|
+
>>> a.hex, a.bin, a.uint, a.float, a.bytes
|
|
68
|
+
('3348', '0011001101001000', 13128, 0.2275390625, b'3H')
|
|
69
|
+
>>> a[10:3:-1].bin
|
|
70
|
+
'0101100'
|
|
71
|
+
>>> '0b100' + 3*a
|
|
72
|
+
BitArray('0x866906690669, 0b000')
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Reading data sequentially
|
|
76
|
+
```pycon
|
|
77
|
+
>>> b = BitStream('0x160120f')
|
|
78
|
+
>>> b.read(12).hex
|
|
79
|
+
'160'
|
|
80
|
+
>>> b.pos = 0
|
|
81
|
+
>>> b.read('uint12')
|
|
82
|
+
352
|
|
83
|
+
>>> b.readlist('uint12, bin3')
|
|
84
|
+
[288, '111']
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Searching, inserting and deleting
|
|
88
|
+
```pycon
|
|
89
|
+
>>> c = BitArray('0b00010010010010001111') # c.hex == '0x1248f'
|
|
90
|
+
>>> c.find('0x48')
|
|
91
|
+
(8,)
|
|
92
|
+
>>> c.replace('0b001', '0xabc')
|
|
93
|
+
>>> c.insert('0b0000', pos=3)
|
|
94
|
+
>>> del c[12:16]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Arrays of fixed-length formats
|
|
98
|
+
```pycon
|
|
99
|
+
>>> from bitstring import Array
|
|
100
|
+
>>> a = Array('uint7', [9, 100, 3, 1])
|
|
101
|
+
>>> a.data
|
|
102
|
+
BitArray('0x1390181')
|
|
103
|
+
>>> a[::2] *= 5
|
|
104
|
+
>>> a
|
|
105
|
+
Array('uint7', [45, 100, 15, 1])
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
<sub>Copyright (c) 2006 - 2025 Scott Griffiths</sub>
|
|
@@ -55,7 +55,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
55
55
|
THE SOFTWARE.
|
|
56
56
|
"""
|
|
57
57
|
|
|
58
|
-
__version__ = "4.
|
|
58
|
+
__version__ = "4.3.0"
|
|
59
59
|
|
|
60
60
|
__author__ = "Scott Griffiths"
|
|
61
61
|
|
|
@@ -111,31 +111,38 @@ class _MyModuleType(types.ModuleType):
|
|
|
111
111
|
|
|
112
112
|
sys.modules[__name__].__class__ = _MyModuleType
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
|
|
115
|
+
# These methods convert a bit length to the number of characters needed to print it for different interpretations.
|
|
115
116
|
def hex_bits2chars(bitlength: int):
|
|
116
117
|
# One character for every 4 bits
|
|
117
118
|
return bitlength // 4
|
|
118
119
|
|
|
120
|
+
|
|
119
121
|
def oct_bits2chars(bitlength: int):
|
|
120
122
|
# One character for every 3 bits
|
|
121
123
|
return bitlength // 3
|
|
122
124
|
|
|
125
|
+
|
|
123
126
|
def bin_bits2chars(bitlength: int):
|
|
124
127
|
# One character for each bit
|
|
125
128
|
return bitlength
|
|
126
129
|
|
|
130
|
+
|
|
127
131
|
def bytes_bits2chars(bitlength: int):
|
|
128
132
|
# One character for every 8 bits
|
|
129
133
|
return bitlength // 8
|
|
130
134
|
|
|
135
|
+
|
|
131
136
|
def uint_bits2chars(bitlength: int):
|
|
132
137
|
# How many characters is largest possible int of this length?
|
|
133
138
|
return len(str((1 << bitlength) - 1))
|
|
134
139
|
|
|
140
|
+
|
|
135
141
|
def int_bits2chars(bitlength: int):
|
|
136
142
|
# How many characters is largest negative int of this length? (To include minus sign).
|
|
137
143
|
return len(str((-1 << (bitlength - 1))))
|
|
138
144
|
|
|
145
|
+
|
|
139
146
|
def float_bits2chars(bitlength: Literal[16, 32, 64]):
|
|
140
147
|
# These bit lengths were found by looking at lots of possible values
|
|
141
148
|
if bitlength in [16, 32]:
|
|
@@ -143,53 +150,65 @@ def float_bits2chars(bitlength: Literal[16, 32, 64]):
|
|
|
143
150
|
else:
|
|
144
151
|
return 24 # Empirical value
|
|
145
152
|
|
|
146
|
-
|
|
153
|
+
|
|
154
|
+
def p3binary_bits2chars(_: Literal[8]):
|
|
147
155
|
return 19 # Empirical value
|
|
148
156
|
|
|
149
|
-
|
|
157
|
+
|
|
158
|
+
def p4binary_bits2chars(_: Literal[8]):
|
|
150
159
|
# Found by looking at all the possible values
|
|
151
160
|
return 13 # Empirical value
|
|
152
161
|
|
|
153
|
-
|
|
162
|
+
|
|
163
|
+
def e4m3mxfp_bits2chars(_: Literal[8]):
|
|
154
164
|
return 13
|
|
155
165
|
|
|
156
|
-
|
|
166
|
+
|
|
167
|
+
def e5m2mxfp_bits2chars(_: Literal[8]):
|
|
157
168
|
return 19
|
|
158
169
|
|
|
159
|
-
|
|
170
|
+
|
|
171
|
+
def e3m2mxfp_bits2chars(_: Literal[6]):
|
|
160
172
|
# Not sure what the best value is here. It's 7 without considering the scale that could be applied.
|
|
161
173
|
return 7
|
|
162
174
|
|
|
163
|
-
|
|
175
|
+
|
|
176
|
+
def e2m3mxfp_bits2chars(_: Literal[6]):
|
|
164
177
|
# Not sure what the best value is here.
|
|
165
178
|
return 7
|
|
166
179
|
|
|
167
|
-
|
|
180
|
+
|
|
181
|
+
def e2m1mxfp_bits2chars(_: Literal[4]):
|
|
168
182
|
# Not sure what the best value is here.
|
|
169
183
|
return 7
|
|
170
184
|
|
|
171
|
-
|
|
172
|
-
|
|
185
|
+
|
|
186
|
+
def e8m0mxfp_bits2chars(_: Literal[8]):
|
|
187
|
+
# Has same range as float32
|
|
173
188
|
return 23
|
|
174
189
|
|
|
175
|
-
|
|
190
|
+
|
|
191
|
+
def mxint_bits2chars(_: Literal[8]):
|
|
176
192
|
# Not sure what the best value is here.
|
|
177
193
|
return 10
|
|
178
194
|
|
|
179
195
|
|
|
180
|
-
def bfloat_bits2chars(
|
|
196
|
+
def bfloat_bits2chars(_: Literal[16]):
|
|
181
197
|
# Found by looking at all the possible values
|
|
182
198
|
return 23 # Empirical value
|
|
183
199
|
|
|
200
|
+
|
|
184
201
|
def bits_bits2chars(bitlength: int):
|
|
185
202
|
# For bits type we can see how long it needs to be printed by trying any value
|
|
186
203
|
temp = Bits(bitlength)
|
|
187
204
|
return len(str(temp))
|
|
188
205
|
|
|
189
|
-
|
|
206
|
+
|
|
207
|
+
def bool_bits2chars(_: Literal[1]):
|
|
190
208
|
# Bools are printed as 1 or 0, not True or False, so are one character each
|
|
191
209
|
return 1
|
|
192
210
|
|
|
211
|
+
|
|
193
212
|
dtype_definitions = [
|
|
194
213
|
# Integer types
|
|
195
214
|
DtypeDefinition('uint', Bits._setuint, Bits._getuint, int, False, uint_bits2chars,
|
|
@@ -93,6 +93,7 @@ class Array:
|
|
|
93
93
|
self.data += BitArray._create_from_bitstype(trailing_bits)
|
|
94
94
|
|
|
95
95
|
_largest_values = None
|
|
96
|
+
|
|
96
97
|
@staticmethod
|
|
97
98
|
def _calculate_auto_scale(initializer, name: str, length: Optional[int]) -> float:
|
|
98
99
|
# Now need to find the largest power of 2 representable with this format.
|
|
@@ -112,12 +113,15 @@ class Array:
|
|
|
112
113
|
}
|
|
113
114
|
if f'{name}{length}' in Array._largest_values.keys():
|
|
114
115
|
float_values = Array('float64', initializer).tolist()
|
|
116
|
+
if not float_values:
|
|
117
|
+
raise ValueError("Can't calculate an 'auto' scale with an empty Array initializer.")
|
|
115
118
|
max_float_value = max(abs(x) for x in float_values)
|
|
116
119
|
if max_float_value == 0:
|
|
117
120
|
# This special case isn't covered in the standard. I'm choosing to return no scale.
|
|
118
121
|
return 1.0
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
# We need to find the largest power of 2 that is less than the max value
|
|
123
|
+
log2 = math.floor(math.log2(max_float_value))
|
|
124
|
+
lp2 = math.floor(math.log2(Array._largest_values[f'{name}{length}']))
|
|
121
125
|
lg_scale = log2 - lp2
|
|
122
126
|
# Saturate at values representable in E8M0 format.
|
|
123
127
|
if lg_scale > 127:
|
|
@@ -155,7 +159,7 @@ class Array:
|
|
|
155
159
|
except ValueError:
|
|
156
160
|
name_length = utils.parse_single_struct_token(new_dtype)
|
|
157
161
|
if name_length is not None:
|
|
158
|
-
dtype = Dtype(
|
|
162
|
+
dtype = Dtype(name_length[0], name_length[1])
|
|
159
163
|
else:
|
|
160
164
|
raise ValueError(f"Inappropriate Dtype for Array: '{new_dtype}'.")
|
|
161
165
|
if dtype.length is None:
|
|
@@ -270,7 +274,7 @@ class Array:
|
|
|
270
274
|
return new_array
|
|
271
275
|
|
|
272
276
|
def tolist(self) -> List[ElementType]:
|
|
273
|
-
return
|
|
277
|
+
return [self._dtype.read_fn(self.data, start=start)
|
|
274
278
|
for start in range(0, len(self.data) - self._dtype.length + 1, self._dtype.length)]
|
|
275
279
|
|
|
276
280
|
def append(self, x: ElementType) -> None:
|
|
@@ -408,9 +412,11 @@ class Array:
|
|
|
408
412
|
token_list = utils.preprocess_tokens(fmt)
|
|
409
413
|
if len(token_list) not in [1, 2]:
|
|
410
414
|
raise ValueError(f"Only one or two tokens can be used in an Array.pp() format - '{fmt}' has {len(token_list)} tokens.")
|
|
411
|
-
|
|
415
|
+
name1, length1 = utils.parse_name_length_token(token_list[0])
|
|
416
|
+
dtype1 = Dtype(name1, length1)
|
|
412
417
|
if len(token_list) == 2:
|
|
413
|
-
|
|
418
|
+
name2, length2 = utils.parse_name_length_token(token_list[1])
|
|
419
|
+
dtype2 = Dtype(name2, length2)
|
|
414
420
|
|
|
415
421
|
token_length = dtype1.bitlength
|
|
416
422
|
if dtype2 is not None:
|
|
@@ -754,12 +760,8 @@ class Array:
|
|
|
754
760
|
def _eq_ne(self, op, other: Any) -> Array:
|
|
755
761
|
if isinstance(other, (int, float, str, Bits)):
|
|
756
762
|
return self._apply_op_to_all_elements(op, other, is_comparison=True)
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
except:
|
|
760
|
-
return NotImplemented
|
|
761
|
-
finally:
|
|
762
|
-
return self._apply_op_between_arrays(op, other, is_comparison=True)
|
|
763
|
+
other = self.__class__(self.dtype, other)
|
|
764
|
+
return self._apply_op_between_arrays(op, other, is_comparison=True)
|
|
763
765
|
|
|
764
766
|
def __eq__(self, other: Any) -> Array:
|
|
765
767
|
return self._eq_ne(operator.eq, other)
|
|
@@ -11,6 +11,7 @@ from bitstring.bits import Bits, BitsType, TBits
|
|
|
11
11
|
|
|
12
12
|
import bitstring.dtypes
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
class BitArray(Bits):
|
|
15
16
|
"""A container holding a mutable sequence of bits.
|
|
16
17
|
|
|
@@ -71,7 +72,6 @@ class BitArray(Bits):
|
|
|
71
72
|
# As BitArray objects are mutable, we shouldn't allow them to be hashed.
|
|
72
73
|
__hash__: None = None
|
|
73
74
|
|
|
74
|
-
|
|
75
75
|
def __init__(self, auto: Optional[Union[BitsType, int]] = None, /, length: Optional[int] = None,
|
|
76
76
|
offset: Optional[int] = None, **kwargs) -> None:
|
|
77
77
|
"""Either specify an 'auto' initialiser:
|
|
@@ -172,6 +172,7 @@ class BitArray(Bits):
|
|
|
172
172
|
|
|
173
173
|
def _setitem_slice(self, key: slice, value: BitsType) -> None:
|
|
174
174
|
if isinstance(value, numbers.Integral):
|
|
175
|
+
value = int(value)
|
|
175
176
|
if key.step not in [None, -1, 1]:
|
|
176
177
|
if value in [0, 1]:
|
|
177
178
|
self.set(value, range(*key.indices(len(self))))
|
|
@@ -195,7 +196,7 @@ class BitArray(Bits):
|
|
|
195
196
|
|
|
196
197
|
def __setitem__(self, key: Union[slice, int], value: BitsType) -> None:
|
|
197
198
|
if isinstance(key, numbers.Integral):
|
|
198
|
-
self._setitem_int(key, value)
|
|
199
|
+
self._setitem_int(int(key), value)
|
|
199
200
|
else:
|
|
200
201
|
self._setitem_slice(key, value)
|
|
201
202
|
|
|
@@ -573,5 +574,3 @@ class BitArray(Bits):
|
|
|
573
574
|
def clear(self) -> None:
|
|
574
575
|
"""Remove all bits, reset to zero length."""
|
|
575
576
|
self._clear()
|
|
576
|
-
|
|
577
|
-
|
|
@@ -231,13 +231,8 @@ class Bits:
|
|
|
231
231
|
def __getitem__(self: TBits, key: Union[slice, int], /) -> Union[TBits, bool]:
|
|
232
232
|
"""Return a new bitstring representing a slice of the current bitstring.
|
|
233
233
|
|
|
234
|
-
|
|
235
|
-
Stepping is used to specify the number of bits in each item.
|
|
236
|
-
|
|
237
|
-
>>> print(BitArray('0b00110')[1:4])
|
|
234
|
+
>>> print(Bits('0b00110')[1:4])
|
|
238
235
|
'0b011'
|
|
239
|
-
>>> print(BitArray('0x00112233')[1:3:8])
|
|
240
|
-
'0x1122'
|
|
241
236
|
|
|
242
237
|
"""
|
|
243
238
|
if isinstance(key, numbers.Integral):
|
|
@@ -1699,34 +1694,37 @@ class Bits:
|
|
|
1699
1694
|
|
|
1700
1695
|
@staticmethod
|
|
1701
1696
|
def _process_pp_tokens(token_list, fmt):
|
|
1697
|
+
if len(token_list) not in [1, 2]:
|
|
1698
|
+
raise ValueError(
|
|
1699
|
+
f"Only one or two tokens can be used in an pp() format - '{fmt}' has {len(token_list)} tokens.")
|
|
1702
1700
|
has_length_in_fmt = True
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1701
|
+
name1, length1 = utils.parse_name_length_token(token_list[0])
|
|
1702
|
+
dtype1 = Dtype(name1, length1)
|
|
1703
|
+
bits_per_group = dtype1.bitlength
|
|
1704
|
+
dtype2 = None
|
|
1705
|
+
|
|
1706
|
+
if len(token_list) == 2:
|
|
1707
|
+
name2, length2 = utils.parse_name_length_token(token_list[1])
|
|
1708
|
+
dtype2 = Dtype(name2, length2)
|
|
1709
|
+
if None not in {dtype1.bitlength, dtype2.bitlength} and dtype1.bitlength != dtype2.bitlength:
|
|
1710
|
+
raise ValueError(
|
|
1711
|
+
f"Differing bit lengths of {dtype1.bitlength} and {dtype2.bitlength} in format string '{fmt}'.")
|
|
1707
1712
|
if bits_per_group is None:
|
|
1708
|
-
|
|
1713
|
+
bits_per_group = dtype2.bitlength
|
|
1714
|
+
|
|
1715
|
+
if bits_per_group is None:
|
|
1716
|
+
has_length_in_fmt = False
|
|
1717
|
+
if len(token_list) == 1:
|
|
1709
1718
|
bits_per_group = {'bin': 8, 'hex': 8, 'oct': 12, 'bytes': 32}.get(dtype1.name)
|
|
1710
1719
|
if bits_per_group is None:
|
|
1711
1720
|
raise ValueError(f"No length or default length available for pp() format '{fmt}'.")
|
|
1712
|
-
|
|
1713
|
-
dtype1 = Dtype(*utils.parse_name_length_token(token_list[0]))
|
|
1714
|
-
dtype2 = Dtype(*utils.parse_name_length_token(token_list[1]))
|
|
1715
|
-
if dtype1.bitlength is not None and dtype2.bitlength is not None and dtype1.bitlength != dtype2.bitlength:
|
|
1716
|
-
raise ValueError(
|
|
1717
|
-
f"Differing bit lengths of {dtype1.bitlength} and {dtype2.bitlength} in format string '{fmt}'.")
|
|
1718
|
-
bits_per_group = dtype1.bitlength if dtype1.bitlength is not None else dtype2.bitlength
|
|
1719
|
-
if bits_per_group is None:
|
|
1720
|
-
has_length_in_fmt = False
|
|
1721
|
+
else:
|
|
1721
1722
|
try:
|
|
1722
1723
|
bits_per_group = 2 * Bits._bits_per_char(dtype1.name) * Bits._bits_per_char(dtype2.name)
|
|
1723
1724
|
except ValueError:
|
|
1724
1725
|
raise ValueError(f"Can't find a default bitlength to use for pp() format '{fmt}'.")
|
|
1725
1726
|
if bits_per_group >= 24:
|
|
1726
1727
|
bits_per_group //= 2
|
|
1727
|
-
else:
|
|
1728
|
-
raise ValueError(
|
|
1729
|
-
f"Only one or two tokens can be used in an pp() format - '{fmt}' has {len(token_list)} tokens.")
|
|
1730
1728
|
return dtype1, dtype2, bits_per_group, has_length_in_fmt
|
|
1731
1729
|
|
|
1732
1730
|
def pp(self, fmt: Optional[str] = None, width: int = 120, sep: str = ' ',
|