0
# Type Checking
1
2
Comprehensive type validation utilities for common Python and Ethereum-specific data types. Provides reliable type checking for data validation pipelines.
3
4
## Capabilities
5
6
### Basic Type Checking
7
8
Check for fundamental Python data types.
9
10
```python { .api }
11
def is_integer(value) -> bool:
12
"""
13
Check if value is integer type (excluding boolean).
14
15
Args:
16
value: Value to check
17
18
Returns:
19
bool: True if value is int but not bool
20
"""
21
22
def is_boolean(value) -> bool:
23
"""
24
Check if value is boolean type.
25
26
Args:
27
value: Value to check
28
29
Returns:
30
bool: True if value is bool
31
"""
32
33
def is_string(value) -> bool:
34
"""
35
Check if value is string-like (str, bytes, or bytearray).
36
37
Args:
38
value: Value to check
39
40
Returns:
41
bool: True if value is any string type
42
"""
43
44
def is_text(value) -> bool:
45
"""
46
Check if value is text string (str only).
47
48
Args:
49
value: Value to check
50
51
Returns:
52
bool: True if value is str type
53
"""
54
55
def is_bytes(value) -> bool:
56
"""
57
Check if value is bytes-like object (bytes or bytearray).
58
59
Args:
60
value: Value to check
61
62
Returns:
63
bool: True if value is bytes or bytearray
64
"""
65
```
66
67
### Numeric Type Checking
68
69
Specialized numeric type validation.
70
71
```python { .api }
72
def is_number(obj) -> bool:
73
"""
74
Check if object is numeric type (int, float, Decimal, but not bool).
75
76
Args:
77
obj: Object to check
78
79
Returns:
80
bool: True if object is numeric
81
"""
82
83
def is_null(obj) -> bool:
84
"""
85
Check if object is None.
86
87
Args:
88
obj: Object to check
89
90
Returns:
91
bool: True if object is None
92
"""
93
```
94
95
### Collection Type Checking
96
97
Check for collection and sequence types.
98
99
```python { .api }
100
def is_dict(obj) -> bool:
101
"""
102
Check if object is mapping type (dict or dict-like).
103
104
Args:
105
obj: Object to check
106
107
Returns:
108
bool: True if object implements mapping protocol
109
"""
110
111
def is_list(obj) -> bool:
112
"""
113
Check if object is list type.
114
115
Args:
116
obj: Object to check
117
118
Returns:
119
bool: True if object is list
120
"""
121
122
def is_tuple(obj) -> bool:
123
"""
124
Check if object is tuple type.
125
126
Args:
127
obj: Object to check
128
129
Returns:
130
bool: True if object is tuple
131
"""
132
133
def is_list_like(obj) -> bool:
134
"""
135
Check if object is sequence-like (list, tuple, etc. but not string).
136
137
Args:
138
obj: Object to check
139
140
Returns:
141
bool: True if object is sequence but not string type
142
"""
143
```
144
145
## Usage Examples
146
147
### Input Validation
148
149
```python
150
from eth_utils import is_integer, is_string, is_bytes, is_boolean
151
152
def validate_transaction_input(value, input_type):
153
"""Validate transaction input based on expected type."""
154
if input_type == "uint256":
155
if not is_integer(value):
156
raise TypeError(f"Expected integer for uint256, got {type(value)}")
157
if value < 0 or value >= 2**256:
158
raise ValueError("uint256 value out of range")
159
160
elif input_type == "address":
161
if not is_string(value):
162
raise TypeError(f"Expected string for address, got {type(value)}")
163
# Additional address validation would go here
164
165
elif input_type == "bytes":
166
if not is_bytes(value) and not is_string(value):
167
raise TypeError(f"Expected bytes or hex string, got {type(value)}")
168
169
elif input_type == "bool":
170
if not is_boolean(value):
171
raise TypeError(f"Expected boolean, got {type(value)}")
172
173
return True
174
175
# Usage examples
176
validate_transaction_input(12345, "uint256") # Valid
177
validate_transaction_input("0x123...", "address") # Valid
178
validate_transaction_input(True, "bool") # Valid
179
# validate_transaction_input("123", "uint256") # Raises TypeError
180
```
181
182
### Data Processing Pipeline
183
184
```python
185
from eth_utils import is_list_like, is_dict, is_string, is_integer
186
187
def process_mixed_data(data):
188
"""Process data based on its type."""
189
if is_dict(data):
190
return {k: process_mixed_data(v) for k, v in data.items()}
191
192
elif is_list_like(data):
193
return [process_mixed_data(item) for item in data]
194
195
elif is_string(data):
196
return data.strip().lower()
197
198
elif is_integer(data):
199
return abs(data) # Ensure positive
200
201
else:
202
return str(data) # Convert to string as fallback
203
204
# Examples
205
result1 = process_mixed_data({"key": " VALUE "}) # {"key": "value"}
206
result2 = process_mixed_data([1, -2, " Text "]) # [1, 2, "text"]
207
result3 = process_mixed_data(-42) # 42
208
```
209
210
### Type-Safe Function Parameters
211
212
```python
213
from eth_utils import is_integer, is_string, is_bytes, is_list_like
214
215
def encode_function_call(function_name, parameters):
216
"""Encode function call with type validation."""
217
if not is_string(function_name):
218
raise TypeError("Function name must be string")
219
220
if not is_list_like(parameters):
221
raise TypeError("Parameters must be list-like")
222
223
encoded_params = []
224
for i, param in enumerate(parameters):
225
if is_integer(param):
226
# Encode integer parameter
227
encoded_params.append(f"uint256:{param}")
228
elif is_string(param):
229
# Encode string parameter
230
encoded_params.append(f"string:{param}")
231
elif is_bytes(param):
232
# Encode bytes parameter
233
encoded_params.append(f"bytes:{param.hex()}")
234
else:
235
raise TypeError(f"Unsupported parameter type at index {i}: {type(param)}")
236
237
return f"{function_name}({','.join(encoded_params)})"
238
239
# Usage
240
call = encode_function_call("transfer", ["0x123...", 1000])
241
print(call) # transfer(string:0x123...,uint256:1000)
242
```
243
244
### Contract ABI Validation
245
246
```python
247
from eth_utils import is_dict, is_list_like, is_string
248
249
def validate_abi_element(abi_element):
250
"""Validate ABI element structure."""
251
if not is_dict(abi_element):
252
raise TypeError("ABI element must be dictionary")
253
254
required_fields = ["type", "name"]
255
for field in required_fields:
256
if field not in abi_element:
257
raise ValueError(f"Missing required field: {field}")
258
if not is_string(abi_element[field]):
259
raise TypeError(f"Field {field} must be string")
260
261
# Validate inputs if present
262
if "inputs" in abi_element:
263
inputs = abi_element["inputs"]
264
if not is_list_like(inputs):
265
raise TypeError("ABI inputs must be list")
266
267
for i, input_param in enumerate(inputs):
268
if not is_dict(input_param):
269
raise TypeError(f"Input parameter {i} must be dictionary")
270
if "type" not in input_param:
271
raise ValueError(f"Input parameter {i} missing type")
272
273
return True
274
275
# Example ABI validation
276
abi_element = {
277
"type": "function",
278
"name": "transfer",
279
"inputs": [
280
{"name": "to", "type": "address"},
281
{"name": "amount", "type": "uint256"}
282
]
283
}
284
285
validate_abi_element(abi_element) # Returns True
286
```
287
288
### Safe Type Conversion
289
290
```python
291
from eth_utils import is_integer, is_string, is_bytes, is_number
292
293
def safe_to_int(value):
294
"""Safely convert value to integer."""
295
if is_integer(value):
296
return value
297
elif is_string(value):
298
try:
299
return int(value, 0) # Auto-detect base (0x for hex)
300
except ValueError:
301
raise ValueError(f"Cannot convert string to int: {value}")
302
elif is_number(value):
303
return int(value)
304
else:
305
raise TypeError(f"Cannot convert {type(value)} to int")
306
307
def safe_to_string(value):
308
"""Safely convert value to string."""
309
if is_string(value):
310
return value if is_text(value) else value.decode('utf-8')
311
elif is_bytes(value):
312
return value.decode('utf-8')
313
else:
314
return str(value)
315
316
# Examples
317
print(safe_to_int("123")) # 123
318
print(safe_to_int("0x123")) # 291
319
print(safe_to_int(123.7)) # 123
320
print(safe_to_string(b"test")) # "test"
321
```
322
323
### Configuration Validation
324
325
```python
326
from eth_utils import is_dict, is_string, is_integer, is_boolean
327
328
def validate_config(config):
329
"""Validate application configuration."""
330
if not is_dict(config):
331
raise TypeError("Configuration must be dictionary")
332
333
# Required string fields
334
string_fields = ["network_url", "contract_address"]
335
for field in string_fields:
336
if field not in config:
337
raise ValueError(f"Missing required field: {field}")
338
if not is_string(config[field]):
339
raise TypeError(f"Field {field} must be string")
340
341
# Required integer fields
342
if "block_confirmation_count" in config:
343
if not is_integer(config["block_confirmation_count"]):
344
raise TypeError("block_confirmation_count must be integer")
345
if config["block_confirmation_count"] < 1:
346
raise ValueError("block_confirmation_count must be positive")
347
348
# Optional boolean fields
349
if "debug_mode" in config:
350
if not is_boolean(config["debug_mode"]):
351
raise TypeError("debug_mode must be boolean")
352
353
return True
354
355
# Example configuration
356
config = {
357
"network_url": "https://mainnet.infura.io/v3/...",
358
"contract_address": "0x123...",
359
"block_confirmation_count": 12,
360
"debug_mode": False
361
}
362
363
validate_config(config) # Returns True
364
```
365
366
## Type Constants
367
368
The module provides type tuples for isinstance checks:
369
370
```python { .api }
371
bytes_types = (bytes, bytearray)
372
integer_types = (int,)
373
text_types = (str,)
374
string_types = (bytes, str, bytearray)
375
```
376
377
```python
378
from eth_utils import bytes_types, string_types, integer_types
379
380
# Use constants for isinstance checks
381
def is_bytes_like(value):
382
return isinstance(value, bytes_types)
383
384
def is_string_like(value):
385
return isinstance(value, string_types)
386
387
# Examples
388
print(is_bytes_like(b"test")) # True
389
print(is_bytes_like(bytearray())) # True
390
print(is_string_like("test")) # True
391
print(is_string_like(b"test")) # True
392
```
393
394
## Common Validation Patterns
395
396
### Comprehensive Input Validation
397
398
```python
399
from eth_utils import (
400
is_string, is_integer, is_bytes, is_boolean,
401
is_list_like, is_dict, is_null
402
)
403
404
def validate_smart_contract_call(contract_address, function_name, parameters):
405
"""Validate smart contract call parameters."""
406
# Address validation
407
if is_null(contract_address) or not is_string(contract_address):
408
raise TypeError("Contract address must be non-null string")
409
410
# Function name validation
411
if is_null(function_name) or not is_string(function_name):
412
raise TypeError("Function name must be non-null string")
413
414
# Parameters validation
415
if is_null(parameters):
416
parameters = []
417
elif not is_list_like(parameters):
418
raise TypeError("Parameters must be list-like or None")
419
420
# Validate each parameter
421
for i, param in enumerate(parameters):
422
if is_null(param):
423
continue # Allow null parameters
424
elif not (is_string(param) or is_integer(param) or
425
is_bytes(param) or is_boolean(param)):
426
raise TypeError(f"Parameter {i} has unsupported type: {type(param)}")
427
428
return True
429
```