0
# Type System
1
2
Explicit integer type wrappers providing precise control over BSON integer encoding. These classes ensure specific bit widths and signedness for integer values, supporting the full range of BSON integer types.
3
4
## Capabilities
5
6
### 32-bit Signed Integer Type
7
8
Wrapper for 32-bit signed integers with range validation and explicit BSON encoding control.
9
10
```python { .api }
11
class Int32:
12
def __init__(self, value):
13
"""
14
Create 32-bit signed integer wrapper.
15
16
Parameters:
17
- value: int, must be in range [-2^31, 2^31-1]
18
19
Raises:
20
ValueError: If value outside 32-bit signed integer range
21
"""
22
23
def get_value(self):
24
"""
25
Get the wrapped integer value.
26
27
Returns:
28
int: The original integer value
29
"""
30
31
def __str__(self):
32
"""String representation of the value"""
33
```
34
35
Usage example:
36
37
```python
38
from bson.types import Int32
39
import bson
40
41
# Create 32-bit signed integers
42
small_int = Int32(100)
43
negative_int = Int32(-2147483648) # Minimum 32-bit signed value
44
max_int = Int32(2147483647) # Maximum 32-bit signed value
45
46
print(small_int.get_value()) # 100
47
print(str(small_int)) # "100"
48
49
# Use in BSON serialization for explicit type control
50
data = {
51
"explicit_int32": Int32(42),
52
"regular_int": 42 # May be encoded as different BSON integer type
53
}
54
55
bson_data = bson.dumps(data)
56
restored = bson.loads(bson_data)
57
print(restored) # Both values appear as regular Python ints after deserialization
58
59
# Range validation
60
try:
61
too_big = Int32(2147483648) # 2^31, exceeds range
62
except ValueError as e:
63
print(f"Range error: {e}")
64
65
try:
66
too_small = Int32(-2147483649) # Below -2^31, exceeds range
67
except ValueError as e:
68
print(f"Range error: {e}")
69
```
70
71
### 64-bit Signed Integer Type
72
73
Wrapper for 64-bit signed integers supporting the full range of signed 64-bit values.
74
75
```python { .api }
76
class Int64:
77
def __init__(self, value):
78
"""
79
Create 64-bit signed integer wrapper.
80
81
Parameters:
82
- value: int, must be in range [-2^63, 2^63-1]
83
84
Raises:
85
ValueError: If value outside 64-bit signed integer range
86
"""
87
88
def get_value(self):
89
"""
90
Get the wrapped integer value.
91
92
Returns:
93
int: The original integer value
94
"""
95
96
def __str__(self):
97
"""String representation of the value"""
98
```
99
100
Usage example:
101
102
```python
103
from bson.types import Int64
104
import bson
105
106
# Create 64-bit signed integers
107
big_int = Int64(9223372036854775807) # Maximum 64-bit signed value
108
negative_big = Int64(-9223372036854775808) # Minimum 64-bit signed value
109
110
print(big_int.get_value()) # 9223372036854775807
111
print(str(big_int)) # "9223372036854775807"
112
113
# Use in BSON for large integers
114
data = {
115
"timestamp_ns": Int64(1634567890123456789), # Nanosecond timestamp
116
"large_id": Int64(-1000000000000000000)
117
}
118
119
bson_data = bson.dumps(data)
120
restored = bson.loads(bson_data)
121
122
# Range validation
123
try:
124
too_big = Int64(9223372036854775808) # 2^63, exceeds range
125
except ValueError as e:
126
print(f"Range error: {e}")
127
```
128
129
### 64-bit Unsigned Integer Type
130
131
Wrapper for 64-bit unsigned integers supporting values from 0 to 2^64-1.
132
133
```python { .api }
134
class UInt64:
135
def __init__(self, value):
136
"""
137
Create 64-bit unsigned integer wrapper.
138
139
Parameters:
140
- value: int, must be in range [0, 2^64-1]
141
142
Raises:
143
ValueError: If value outside 64-bit unsigned integer range
144
"""
145
146
def get_value(self):
147
"""
148
Get the wrapped integer value.
149
150
Returns:
151
int: The original integer value
152
"""
153
154
def __str__(self):
155
"""String representation of the value"""
156
```
157
158
Usage example:
159
160
```python
161
from bson.types import UInt64
162
import bson
163
164
# Create 64-bit unsigned integers
165
max_uint64 = UInt64(18446744073709551615) # Maximum 64-bit unsigned value (2^64-1)
166
zero_uint64 = UInt64(0) # Minimum value
167
168
print(max_uint64.get_value()) # 18446744073709551615
169
print(str(max_uint64)) # "18446744073709551615"
170
171
# Use for large positive values
172
data = {
173
"file_size": UInt64(17179869184000), # 16 TB in bytes
174
"counter": UInt64(18446744073709551615)
175
}
176
177
bson_data = bson.dumps(data)
178
restored = bson.loads(bson_data)
179
180
# Range validation
181
try:
182
negative = UInt64(-1) # Negative values not allowed
183
except ValueError as e:
184
print(f"Range error: {e}")
185
186
try:
187
too_big = UInt64(18446744073709551616) # 2^64, exceeds range
188
except ValueError as e:
189
print(f"Range error: {e}")
190
```
191
192
## Type Selection Behavior
193
194
### Automatic Integer Type Selection
195
196
When using regular Python integers without explicit type wrappers, the bson package automatically selects the appropriate BSON integer type based on value range:
197
198
```python
199
import bson
200
201
data = {
202
"small": 100, # -> BSON Int32
203
"medium": 2147483648, # -> BSON Int64 (exceeds Int32 range)
204
"large": 9223372036854775808, # -> BSON UInt64 (exceeds Int64 range)
205
"too_large": 18446744073709551616 # -> Exception (exceeds UInt64 range)
206
}
207
208
# Automatic type selection rules:
209
# [-2^31, 2^31-1] -> Int32
210
# [-2^63, -2^31-1] ∪ [2^31, 2^63-1] -> Int64
211
# [2^63, 2^64-1] -> UInt64
212
# Outside [0, 2^64-1] -> Exception
213
```
214
215
### Explicit Type Control
216
217
Use type wrapper classes when you need explicit control over BSON encoding:
218
219
```python
220
from bson.types import Int32, Int64, UInt64
221
import bson
222
223
# Force specific BSON types regardless of value
224
data = {
225
"explicit_int32": Int32(100), # Always encoded as BSON Int32
226
"explicit_int64": Int64(100), # Always encoded as BSON Int64
227
"explicit_uint64": UInt64(100), # Always encoded as BSON UInt64
228
"automatic": 100 # Automatically chosen (Int32 in this case)
229
}
230
231
bson_data = bson.dumps(data)
232
233
# All values appear as regular Python ints after deserialization
234
restored = bson.loads(bson_data)
235
# But they were encoded with different BSON type codes
236
```
237
238
## Integration with BSON Codec
239
240
### Encoding Behavior
241
242
The type wrapper classes integrate seamlessly with the BSON encoding system:
243
244
```python
245
from bson.types import Int32, Int64, UInt64
246
import bson
247
248
# Mixed type data
249
mixed_data = {
250
"values": [
251
Int32(42),
252
Int64(1234567890123),
253
UInt64(18446744073709551615),
254
12345 # Regular int, automatically typed
255
],
256
"metadata": {
257
"count": Int32(4),
258
"timestamp": Int64(1634567890123)
259
}
260
}
261
262
# Encode with explicit type control
263
bson_bytes = bson.dumps(mixed_data)
264
265
# Decode back to regular Python types
266
result = bson.loads(bson_bytes)
267
# All integers appear as regular Python ints in result
268
```
269
270
### Custom Object Integration
271
272
Type wrappers can be used within custom BSONCoding objects:
273
274
```python
275
from bson.types import Int32, UInt64
276
from bson.codec import BSONCoding
277
import bson
278
279
class Counter(BSONCoding):
280
def __init__(self, count=0):
281
self.count = UInt64(count) if count >= 0 else Int64(count)
282
283
def bson_encode(self):
284
return {"count": self.count}
285
286
def bson_init(self, raw_values):
287
self.count = raw_values["count"]
288
return self
289
290
# Register and use
291
bson.import_class(Counter)
292
293
counter = Counter(18446744073709551615) # Large positive value
294
data = {"counter_obj": counter}
295
296
bson_data = bson.dumps(data)
297
restored = bson.loads(bson_data)
298
```
299
300
## Error Handling
301
302
All type wrapper classes validate ranges during construction and raise `ValueError` with descriptive messages for out-of-range values:
303
304
```python
305
from bson.types import Int32, Int64, UInt64
306
307
# Int32 range errors
308
try:
309
Int32(2147483648) # 2^31, too large
310
except ValueError as e:
311
print(e) # "value 2147483648 cannot be represented in int32"
312
313
# Int64 range errors
314
try:
315
Int64(9223372036854775808) # 2^63, too large
316
except ValueError as e:
317
print(e) # "value 9223372036854775808 cannot be represented in int32" (bug in error message)
318
319
# UInt64 range errors
320
try:
321
UInt64(-1) # Negative, invalid for unsigned
322
except ValueError as e:
323
print(e) # "value -1 cannot be represented in uint32" (bug in error message)
324
325
try:
326
UInt64(18446744073709551616) # 2^64, too large
327
except ValueError as e:
328
print(e) # "value 18446744073709551616 cannot be represented in uint32" (bug in error message)
329
```
330
331
Note: The error messages contain bugs where Int64 and UInt64 classes incorrectly reference "int32" and "uint32" respectively.