or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/pypi-bitstruct

Python library for converting between Python values and C bit field structs represented as byte strings.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/bitstruct@8.21.x

To install, run

npx @tessl/cli install tessl/pypi-bitstruct@8.21.0

0

# Bitstruct

1

2

A Python library for converting between Python values and C bit field structs represented as byte strings. Bitstruct provides functionality similar to the built-in struct module but operates on individual bits instead of primitive data types, enabling precise bit-level data manipulation for binary protocols, embedded systems, and specialized data formats.

3

4

## Package Information

5

6

- **Package Name**: bitstruct

7

- **Language**: Python

8

- **Installation**: `pip install bitstruct`

9

10

## Core Imports

11

12

```python

13

import bitstruct

14

```

15

16

Common usage patterns:

17

18

```python

19

from bitstruct import * # Import all functions

20

```

21

22

For better performance (C extension):

23

24

```python

25

import bitstruct.c as bitstruct # Optional C implementation

26

```

27

28

## Basic Usage

29

30

```python

31

import bitstruct

32

33

# Pack values into bytes using format string

34

packed = bitstruct.pack('u1u3u4s16', 1, 2, 3, -4)

35

print(packed) # b'\xa3\xff\xfc'

36

37

# Unpack bytes back to values

38

unpacked = bitstruct.unpack('u1u3u4s16', packed)

39

print(unpacked) # (1, 2, 3, -4)

40

41

# Calculate the size in bits for a format

42

size = bitstruct.calcsize('u1u3u4s16')

43

print(size) # 24 bits

44

45

# Use compiled format for repeated operations

46

cf = bitstruct.compile('u1u3u4s16')

47

packed = cf.pack(1, 2, 3, -4)

48

unpacked = cf.unpack(packed)

49

```

50

51

## Format String Specification

52

53

Format strings define the bit layout using type-length combinations:

54

55

- **Bit Order**: `>` (MSB first, default) or `<` (LSB first)

56

- **Byte Order**: `>` (big endian, default) or `<` (little endian) as suffix

57

- **Types**:

58

- `u` - unsigned integer

59

- `s` - signed integer

60

- `f` - floating point (16, 32, or 64 bits)

61

- `b` - boolean

62

- `t` - text (ASCII or UTF-8)

63

- `r` - raw bytes

64

- `p` - padding with zeros (ignored)

65

- `P` - padding with ones (ignored)

66

67

Example format strings:

68

- `'u1u3u4s16'` - 1-bit uint, 3-bit uint, 4-bit uint, 16-bit signed int

69

- `'<u1u3u4s16<'` - Same with LSB bit order and little endian byte order

70

- `'u5s5f32b1r13t40'` - Mixed types including float, boolean, raw, and text

71

72

## Capabilities

73

74

### Pack Functions

75

76

Convert Python values to bytes according to format strings.

77

78

```python { .api }

79

def pack(fmt: str, *args) -> bytes:

80

"""Pack values into bytes according to format string."""

81

82

def pack_into(fmt: str, buf: bytearray, offset: int, *args, **kwargs) -> None:

83

"""Pack values into existing buffer at bit offset."""

84

85

def pack_dict(fmt: str, names: list[str], data: dict) -> bytes:

86

"""Pack values from dictionary using field names."""

87

88

def pack_into_dict(fmt: str, names: list[str], buf: bytearray, offset: int, data: dict, **kwargs) -> None:

89

"""Pack dictionary values into buffer at bit offset."""

90

```

91

92

### Unpack Functions

93

94

Convert bytes to Python values according to format strings.

95

96

```python { .api }

97

def unpack(fmt: str, data: bytes, allow_truncated: bool = False, text_encoding: str = 'utf-8', text_errors: str = 'strict') -> tuple:

98

"""Unpack bytes according to format string."""

99

100

def unpack_from(fmt: str, data: bytes, offset: int = 0, allow_truncated: bool = False, text_encoding: str = 'utf-8', text_errors: str = 'strict') -> tuple:

101

"""Unpack from bytes starting at bit offset."""

102

103

def unpack_dict(fmt: str, names: list[str], data: bytes, allow_truncated: bool = False, text_encoding: str = 'utf-8', text_errors: str = 'strict') -> dict:

104

"""Unpack bytes to dictionary using field names."""

105

106

def unpack_from_dict(fmt: str, names: list[str], data: bytes, offset: int = 0, allow_truncated: bool = False, text_encoding: str = 'utf-8', text_errors: str = 'strict') -> dict:

107

"""Unpack from bytes to dictionary starting at bit offset."""

108

```

109

110

### Utility Functions

111

112

Additional operations for format analysis and byte manipulation.

113

114

```python { .api }

115

def calcsize(fmt: str) -> int:

116

"""Return the number of bits in given format string."""

117

118

def byteswap(fmt: str, data: bytes, offset: int = 0) -> bytes:

119

"""Swap bytes in data according to format."""

120

121

def compile(fmt: str, names: list[str] = None, text_encoding: str = 'utf-8', text_errors: str = 'strict') -> CompiledFormat | CompiledFormatDict:

122

"""Compile format string for repeated use."""

123

```

124

125

### Compiled Format Classes

126

127

Pre-compiled format objects for efficient repeated operations.

128

129

```python { .api }

130

class CompiledFormat:

131

"""Compiled format string for tuple-based pack/unpack operations."""

132

133

def __init__(self, fmt: str, text_encoding: str = 'utf-8', text_errors: str = 'strict'): ...

134

135

def pack(self, *args) -> bytes:

136

"""Pack values using compiled format."""

137

138

def unpack(self, data: bytes, allow_truncated: bool = False) -> tuple:

139

"""Unpack using compiled format."""

140

141

def pack_into(self, buf: bytearray, offset: int, *args, **kwargs) -> None:

142

"""Pack into buffer using compiled format."""

143

144

def unpack_from(self, data: bytes, offset: int = 0, allow_truncated: bool = False) -> tuple:

145

"""Unpack from offset using compiled format."""

146

147

def calcsize(self) -> int:

148

"""Return the number of bits in the compiled format."""

149

150

class CompiledFormatDict:

151

"""Compiled format string for dictionary-based pack/unpack operations."""

152

153

def pack(self, data: dict) -> bytes:

154

"""Pack from dictionary using compiled format."""

155

156

def unpack(self, data: bytes, allow_truncated: bool = False) -> dict:

157

"""Unpack to dictionary using compiled format."""

158

159

def pack_into(self, buf: bytearray, offset: int, data: dict, **kwargs) -> None:

160

"""Pack dictionary into buffer using compiled format."""

161

162

def unpack_from(self, data: bytes, offset: int = 0, allow_truncated: bool = False) -> dict:

163

"""Unpack to dictionary from offset using compiled format."""

164

```

165

166

### Exception Types

167

168

Package-specific exceptions for error handling.

169

170

```python { .api }

171

class Error(Exception):

172

"""Package-specific exception for bitstruct errors."""

173

```

174

175

## Usage Examples

176

177

### Working with Mixed Data Types

178

179

```python

180

import bitstruct

181

182

# Pack unsigned int, signed int, float, boolean, raw bytes, and text

183

packed = bitstruct.pack('u5s5f32b1r13t40', 1, -1, 3.75, True, b'\xff\xff', 'hello')

184

print(packed) # b'\x0f\xd0\x1c\x00\x00?\xffhello'

185

186

# Unpack the same data

187

unpacked = bitstruct.unpack('u5s5f32b1r13t40', packed)

188

print(unpacked) # (1, -1, 3.75, True, b'\xff\xf8', 'hello')

189

```

190

191

### Dictionary-based Packing

192

193

```python

194

import bitstruct

195

196

# Define field names

197

names = ['a', 'b', 'c', 'd']

198

data = {'a': 1, 'b': 2, 'c': 3, 'd': -4}

199

200

# Pack from dictionary

201

packed = bitstruct.pack_dict('u1u3u4s16', names, data)

202

print(packed) # b'\xa3\xff\xfc'

203

204

# Unpack to dictionary

205

unpacked = bitstruct.unpack_dict('u1u3u4s16', names, packed)

206

print(unpacked) # {'a': 1, 'b': 2, 'c': 3, 'd': -4}

207

```

208

209

### Bit Offset Operations

210

211

```python

212

import bitstruct

213

214

# Pack into existing buffer at bit offset

215

data = bytearray(b'\x00\x00\x00\x00')

216

bitstruct.pack_into('u1u3u4s16', data, 5, 1, 2, 3, -4)

217

print(data) # bytearray(b'\x05\x1f\xff\xe0')

218

219

# Unpack from bit offset

220

unpacked = bitstruct.unpack_from('u1u3u4s16', data, 5)

221

print(unpacked) # (1, 2, 3, -4)

222

```

223

224

### Compiled Format Usage

225

226

```python

227

import bitstruct

228

229

# Compile format for repeated use

230

cf = bitstruct.compile('u1u3u4s16')

231

232

# Use compiled format multiple times

233

packed1 = cf.pack(1, 2, 3, -4)

234

packed2 = cf.pack(0, 7, 15, 32767)

235

236

unpacked1 = cf.unpack(packed1)

237

unpacked2 = cf.unpack(packed2)

238

239

print(f"Size: {cf.calcsize()} bits") # Size: 24 bits

240

```

241

242

### Endianness Control

243

244

```python

245

import bitstruct

246

247

# Big endian (default)

248

packed_be = bitstruct.pack('u1u3u4s16', 1, 2, 3, 1)

249

250

# Little endian

251

packed_le = bitstruct.pack('<u1u3u4s16<', 1, 2, 3, 1)

252

253

# Change byte order with byteswap

254

swapped = bitstruct.byteswap('12', packed_be)

255

unpacked_swapped = bitstruct.unpack('u1u3u4s16', swapped)

256

print(unpacked_swapped) # (1, 2, 3, 256)

257

```

258

259

## Performance Notes

260

261

- **Pure Python**: Default implementation in main `bitstruct` module

262

- **C Extension**: Optional `bitstruct.c` module for better performance

263

- Import with `import bitstruct.c as bitstruct`

264

- Limitations: 64-bit max integers/booleans, text/raw must be multiples of 8 bits

265

- **Compiled Formats**: Use `compile()` for repeated operations to avoid re-parsing format strings

266

267

## Error Handling

268

269

The library raises `bitstruct.Error` for:

270

- Invalid format strings

271

- Value range errors (e.g., integer too large for specified bit width)

272

- Buffer size mismatches

273

- Text encoding/decoding errors (controlled by `text_encoding` and `text_errors` parameters)

274

275

## Constants

276

277

```python { .api }

278

__version__: str # Package version string (currently '8.21.0')

279

```