faster-eth-utils 5.3.2__cp312-cp312-musllinux_1_2_i686.whl → 5.3.22__cp312-cp312-musllinux_1_2_i686.whl

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.

Potentially problematic release.


This version of faster-eth-utils might be problematic. Click here for more details.

Files changed (46) hide show
  1. faster_eth_utils/abi.cpython-312-i386-linux-musl.so +0 -0
  2. faster_eth_utils/abi.py +99 -74
  3. faster_eth_utils/address.cpython-312-i386-linux-musl.so +0 -0
  4. faster_eth_utils/address.py +15 -36
  5. faster_eth_utils/applicators.cpython-312-i386-linux-musl.so +0 -0
  6. faster_eth_utils/applicators.py +79 -59
  7. faster_eth_utils/conversions.cpython-312-i386-linux-musl.so +0 -0
  8. faster_eth_utils/conversions.py +18 -20
  9. faster_eth_utils/crypto.cpython-312-i386-linux-musl.so +0 -0
  10. faster_eth_utils/crypto.py +3 -8
  11. faster_eth_utils/currency.cpython-312-i386-linux-musl.so +0 -0
  12. faster_eth_utils/currency.py +11 -8
  13. faster_eth_utils/curried/__init__.py +65 -65
  14. faster_eth_utils/debug.cpython-312-i386-linux-musl.so +0 -0
  15. faster_eth_utils/decorators.cpython-312-i386-linux-musl.so +0 -0
  16. faster_eth_utils/decorators.py +65 -29
  17. faster_eth_utils/encoding.cpython-312-i386-linux-musl.so +0 -0
  18. faster_eth_utils/encoding.py +1 -1
  19. faster_eth_utils/exceptions.cpython-312-i386-linux-musl.so +0 -0
  20. faster_eth_utils/exceptions.py +8 -1
  21. faster_eth_utils/functional.cpython-312-i386-linux-musl.so +0 -0
  22. faster_eth_utils/functional.py +39 -27
  23. faster_eth_utils/hexadecimal.cpython-312-i386-linux-musl.so +0 -0
  24. faster_eth_utils/hexadecimal.py +8 -12
  25. faster_eth_utils/humanize.cpython-312-i386-linux-musl.so +0 -0
  26. faster_eth_utils/humanize.py +18 -22
  27. faster_eth_utils/logging.py +51 -44
  28. faster_eth_utils/module_loading.cpython-312-i386-linux-musl.so +0 -0
  29. faster_eth_utils/network.cpython-312-i386-linux-musl.so +0 -0
  30. faster_eth_utils/network.py +11 -4
  31. faster_eth_utils/numeric.cpython-312-i386-linux-musl.so +0 -0
  32. faster_eth_utils/pydantic.py +15 -13
  33. faster_eth_utils/toolz.cpython-312-i386-linux-musl.so +0 -0
  34. faster_eth_utils/toolz.py +82 -152
  35. faster_eth_utils/types.cpython-312-i386-linux-musl.so +0 -0
  36. faster_eth_utils/types.py +20 -17
  37. faster_eth_utils/units.cpython-312-i386-linux-musl.so +0 -0
  38. {faster_eth_utils-5.3.2.dist-info → faster_eth_utils-5.3.22.dist-info}/METADATA +46 -17
  39. faster_eth_utils-5.3.22.dist-info/RECORD +53 -0
  40. faster_eth_utils-5.3.22.dist-info/top_level.txt +3 -0
  41. faster_eth_utils__mypyc.cpython-312-i386-linux-musl.so +0 -0
  42. bce0bfc64ce5e845ec4a__mypyc.cpython-312-i386-linux-musl.so +0 -0
  43. faster_eth_utils-5.3.2.dist-info/RECORD +0 -47
  44. faster_eth_utils-5.3.2.dist-info/top_level.txt +0 -3
  45. {faster_eth_utils-5.3.2.dist-info → faster_eth_utils-5.3.22.dist-info}/WHEEL +0 -0
  46. {faster_eth_utils-5.3.2.dist-info → faster_eth_utils-5.3.22.dist-info}/licenses/LICENSE +0 -0
faster_eth_utils/abi.py CHANGED
@@ -1,20 +1,17 @@
1
- from collections import (
2
- abc,
3
- )
4
1
  import copy
5
2
  import itertools
6
3
  import re
7
- from typing import (
8
- Any,
9
- Dict,
4
+ from collections.abc import (
10
5
  Iterable,
11
- List,
12
- Literal,
13
6
  Mapping,
14
- Optional,
15
7
  Sequence,
16
- Tuple,
17
- Union,
8
+ )
9
+ from typing import (
10
+ Any,
11
+ Final,
12
+ Generic,
13
+ Literal,
14
+ TypeVar,
18
15
  cast,
19
16
  overload,
20
17
  )
@@ -30,6 +27,9 @@ from eth_typing import (
30
27
  ABIFunction,
31
28
  ABIReceive,
32
29
  )
30
+ from typing_extensions import (
31
+ Self,
32
+ )
33
33
 
34
34
  from faster_eth_utils.types import (
35
35
  is_list_like,
@@ -40,9 +40,37 @@ from .crypto import (
40
40
  )
41
41
 
42
42
 
43
+ T = TypeVar("T")
44
+
45
+ ABIType = Literal["function", "constructor", "fallback", "receive", "event", "error"]
46
+
47
+ _TUPLE_TYPE_STR_RE: Final = re.compile("^(tuple)((\\[([1-9]\\d*\\b)?])*)??$")
48
+
49
+ _chain: Final = itertools.chain
50
+
51
+
52
+ class _repeat(Generic[T]):
53
+
54
+ def __init__(self, value: T, times: int | None = None) -> None:
55
+ self._value: Final[T] = value
56
+ self._times: Final[int | None] = times
57
+ self._index = 0
58
+
59
+ def __iter__(self) -> Self:
60
+ return self
61
+
62
+ def __next__(self) -> T:
63
+ if self._times is None:
64
+ return self._value
65
+ if self._index >= self._times:
66
+ raise StopIteration
67
+ self._index += 1
68
+ return self._value
69
+
70
+
43
71
  def _align_abi_input(
44
72
  arg_abi: ABIComponent, normalized_arg: Any
45
- ) -> Union[Any, Tuple[Any, ...]]:
73
+ ) -> Any | tuple[Any, ...]:
46
74
  """
47
75
  Aligns the values of any mapping at any level of nesting in ``normalized_arg``
48
76
  according to the layout of the corresponding abi spec.
@@ -66,37 +94,38 @@ def _align_abi_input(
66
94
  new_abi = copy.copy(arg_abi)
67
95
  new_abi["type"] = tuple_prefix + "[]" * (num_dims - 1)
68
96
 
69
- sub_abis = itertools.repeat(new_abi)
97
+ sub_abis = _repeat(new_abi)
70
98
 
71
99
  aligned_arg: Any
72
- if isinstance(normalized_arg, abc.Mapping):
100
+ if isinstance(normalized_arg, Mapping):
73
101
  # normalized_arg is mapping. Align values according to abi order.
74
102
  aligned_arg = tuple(normalized_arg[abi["name"]] for abi in sub_abis)
75
103
  else:
76
104
  aligned_arg = normalized_arg
77
105
 
78
- if not is_list_like(aligned_arg):
79
- raise TypeError(
80
- f'Expected non-string sequence for "{arg_abi.get("type")}" '
81
- f"component type: got {aligned_arg}"
82
- )
106
+ # We can generate more optimized C code if we branch by arg type
107
+ if isinstance(aligned_arg, tuple):
108
+ # convert NamedTuple to regular tuple
109
+ return tuple(map(_align_abi_input, sub_abis, aligned_arg))
83
110
 
84
- # convert NamedTuple to regular tuple
85
- typing = tuple if isinstance(aligned_arg, tuple) else type(aligned_arg)
111
+ elif type(aligned_arg) is list:
112
+ return list(map(_align_abi_input, sub_abis, aligned_arg))
86
113
 
87
- return typing( # type: ignore [call-arg]
88
- _align_abi_input(sub_abi, sub_arg)
89
- for sub_abi, sub_arg in zip(sub_abis, aligned_arg)
114
+ elif is_list_like(aligned_arg):
115
+ return type(aligned_arg)(map(_align_abi_input, sub_abis, aligned_arg)) # type: ignore [call-arg]
116
+
117
+ raise TypeError(
118
+ f'Expected non-string sequence for "{arg_abi.get("type")}" '
119
+ f"component type: got {aligned_arg}"
90
120
  )
91
121
 
92
122
 
93
- def _get_tuple_type_str_and_dims(s: str) -> Optional[Tuple[str, Optional[str]]]:
123
+ def _get_tuple_type_str_and_dims(s: str) -> tuple[str, str | None] | None:
94
124
  """
95
125
  Takes a JSON ABI type string. For tuple type strings, returns the separated
96
126
  prefix and array dimension parts. For all other strings, returns ``None``.
97
127
  """
98
- tuple_type_str_re = "^(tuple)((\\[([1-9]\\d*\b)?])*)??$"
99
- match = re.compile(tuple_type_str_re).match(s)
128
+ match = _TUPLE_TYPE_STR_RE.match(s)
100
129
 
101
130
  return None if match is None else (match[1], match[2])
102
131
 
@@ -119,7 +148,7 @@ def _raise_if_fallback_or_receive_abi(abi_element: ABIElement) -> None:
119
148
  )
120
149
 
121
150
 
122
- def collapse_if_tuple(abi: Union[ABIComponent, Dict[str, Any], str]) -> str:
151
+ def collapse_if_tuple(abi: ABIComponent | dict[str, Any] | str) -> str:
123
152
  """
124
153
  Extract argument types from a function or event ABI parameter.
125
154
 
@@ -274,15 +303,25 @@ def filter_abi_by_name(abi_name: str, contract_abi: ABI) -> Sequence[ABIElement]
274
303
  abi
275
304
  for abi in contract_abi
276
305
  if abi["type"] in ["function", "event", "error"]
277
- and abi["name"] == abi_name
306
+ and abi["name"] == abi_name # type: ignore [typeddict-item]
278
307
  ]
279
308
 
280
309
 
310
+ __ABI_TYPE_LITERALS: Final = {
311
+ Literal["function"]: "function",
312
+ Literal["constructor"]: "constructor",
313
+ Literal["fallback"]: "fallback",
314
+ Literal["receive"]: "receive",
315
+ Literal["event"]: "event",
316
+ Literal["error"]: "error",
317
+ }
318
+
319
+
281
320
  @overload
282
321
  def filter_abi_by_type(
283
322
  abi_type: Literal["function"],
284
323
  contract_abi: ABI,
285
- ) -> List[ABIFunction]:
324
+ ) -> list[ABIFunction]:
286
325
  pass
287
326
 
288
327
 
@@ -290,7 +329,7 @@ def filter_abi_by_type(
290
329
  def filter_abi_by_type(
291
330
  abi_type: Literal["constructor"],
292
331
  contract_abi: ABI,
293
- ) -> List[ABIConstructor]:
332
+ ) -> list[ABIConstructor]:
294
333
  pass
295
334
 
296
335
 
@@ -298,7 +337,7 @@ def filter_abi_by_type(
298
337
  def filter_abi_by_type(
299
338
  abi_type: Literal["fallback"],
300
339
  contract_abi: ABI,
301
- ) -> List[ABIFallback]:
340
+ ) -> list[ABIFallback]:
302
341
  pass
303
342
 
304
343
 
@@ -306,7 +345,7 @@ def filter_abi_by_type(
306
345
  def filter_abi_by_type(
307
346
  abi_type: Literal["receive"],
308
347
  contract_abi: ABI,
309
- ) -> List[ABIReceive]:
348
+ ) -> list[ABIReceive]:
310
349
  pass
311
350
 
312
351
 
@@ -314,7 +353,7 @@ def filter_abi_by_type(
314
353
  def filter_abi_by_type(
315
354
  abi_type: Literal["event"],
316
355
  contract_abi: ABI,
317
- ) -> List[ABIEvent]:
356
+ ) -> list[ABIEvent]:
318
357
  pass
319
358
 
320
359
 
@@ -322,18 +361,16 @@ def filter_abi_by_type(
322
361
  def filter_abi_by_type(
323
362
  abi_type: Literal["error"],
324
363
  contract_abi: ABI,
325
- ) -> List[ABIError]:
364
+ ) -> list[ABIError]:
326
365
  pass
327
366
 
328
367
 
329
368
  def filter_abi_by_type(
330
- abi_type: Literal[
331
- "function", "constructor", "fallback", "receive", "event", "error"
332
- ],
369
+ abi_type: ABIType,
333
370
  contract_abi: ABI,
334
- ) -> Union[
335
- List[ABIFunction], List[ABIConstructor], List[ABIFallback], List[ABIReceive], List[ABIEvent], List[ABIError]
336
- ]:
371
+ ) -> (
372
+ list[ABIFunction] | list[ABIConstructor] | list[ABIFallback] | list[ABIReceive] | list[ABIEvent] | list[ABIError]
373
+ ):
337
374
  """
338
375
  Return a list of each ``ABIElement`` that is of type ``abi_type``.
339
376
 
@@ -361,20 +398,12 @@ ABIEvent, ABIError]]`
361
398
  [{'type': 'function', 'name': 'myFunction', 'inputs': [], 'outputs': []}, \
362
399
  {'type': 'function', 'name': 'myFunction2', 'inputs': [], 'outputs': []}]
363
400
  """
364
- if abi_type == Literal["function"] or abi_type == "function":
365
- return [abi for abi in contract_abi if abi["type"] == "function"]
366
- elif abi_type == Literal["constructor"] or abi_type == "constructor":
367
- return [abi for abi in contract_abi if abi["type"] == "constructor"]
368
- elif abi_type == Literal["fallback"] or abi_type == "fallback":
369
- return [abi for abi in contract_abi if abi["type"] == "fallback"]
370
- elif abi_type == Literal["receive"] or abi_type == "receive":
371
- return [abi for abi in contract_abi if abi["type"] == "receive"]
372
- elif abi_type == Literal["event"] or abi_type == "event":
373
- return [abi for abi in contract_abi if abi["type"] == "event"]
374
- elif abi_type == Literal["error"] or abi_type == "error":
375
- return [abi for abi in contract_abi if abi["type"] == "error"]
376
- else:
401
+ if abi_type in ("function", "constructor", "fallback", "receive", "event", "error"):
402
+ return [abi for abi in contract_abi if abi["type"] == abi_type] # type: ignore [return-value]
403
+ abi_type_string: ABIType | None = __ABI_TYPE_LITERALS.get(abi_type) # type: ignore [call-overload]
404
+ if abi_type_string is None:
377
405
  raise ValueError(f"Unsupported ABI type: {abi_type}")
406
+ return [abi for abi in contract_abi if abi["type"] == abi_type_string] # type: ignore [return-value]
378
407
 
379
408
 
380
409
  def get_all_function_abis(contract_abi: ABI) -> Sequence[ABIFunction]:
@@ -426,9 +455,9 @@ def get_all_event_abis(contract_abi: ABI) -> Sequence[ABIEvent]:
426
455
 
427
456
  def get_normalized_abi_inputs(
428
457
  abi_element: ABIElement,
429
- *args: Optional[Sequence[Any]],
430
- **kwargs: Optional[Dict[str, Any]],
431
- ) -> Tuple[Any, ...]:
458
+ *args: Any,
459
+ **kwargs: Any,
460
+ ) -> tuple[Any, ...]:
432
461
  r"""
433
462
  Flattens positional args (``args``) and keyword args (``kwargs``) into a Tuple and
434
463
  uses the ``abi_element`` for validation.
@@ -492,10 +521,11 @@ def get_normalized_abi_inputs(
492
521
 
493
522
  # If no keyword args were given, we don't need to align them
494
523
  if not kwargs:
495
- return cast(Tuple[Any, ...], args)
524
+ return args
496
525
 
497
526
  kwarg_names = set(kwargs.keys())
498
527
  sorted_arg_names = tuple(arg_abi["name"] for arg_abi in function_inputs)
528
+ arg_positions = {name: index for index, name in enumerate(sorted_arg_names)}
499
529
  args_as_kwargs = dict(zip(sorted_arg_names, args))
500
530
 
501
531
  # Check for duplicate args
@@ -521,22 +551,17 @@ def get_normalized_abi_inputs(
521
551
 
522
552
  # Sort args according to their position in the ABI and unzip them from their
523
553
  # names
524
- sorted_args = tuple(
525
- zip(
526
- *sorted(
527
- itertools.chain(kwargs.items(), args_as_kwargs.items()),
528
- key=lambda kv: sorted_arg_names.index(kv[0]),
529
- )
530
- )
554
+ sorted_items = sorted(
555
+ _chain(kwargs.items(), args_as_kwargs.items()),
556
+ key=lambda kv: arg_positions[kv[0]],
531
557
  )
532
-
533
- return tuple(sorted_args[1]) if sorted_args else ()
558
+ return tuple(val for _, val in sorted_items)
534
559
 
535
560
 
536
561
  def get_aligned_abi_inputs(
537
562
  abi_element: ABIElement,
538
- normalized_args: Union[Tuple[Any, ...], Mapping[Any, Any]],
539
- ) -> Tuple[Tuple[str, ...], Tuple[Any, ...]]:
563
+ normalized_args: tuple[Any, ...] | Mapping[Any, Any],
564
+ ) -> tuple[tuple[str, ...], tuple[Any, ...]]:
540
565
  """
541
566
  Returns a pair of nested Tuples containing a list of types and a list of input
542
567
  values sorted by the order specified by the ``abi``.
@@ -579,7 +604,7 @@ def get_aligned_abi_inputs(
579
604
  _raise_if_fallback_or_receive_abi(abi_element)
580
605
 
581
606
  abi_element_inputs = cast(Sequence[ABIComponent], abi_element.get("inputs", []))
582
- if isinstance(normalized_args, abc.Mapping):
607
+ if isinstance(normalized_args, Mapping):
583
608
  # `args` is mapping. Align values according to abi order.
584
609
  normalized_args = tuple(
585
610
  normalized_args[abi["name"]] for abi in abi_element_inputs
@@ -594,7 +619,7 @@ def get_aligned_abi_inputs(
594
619
  )
595
620
 
596
621
 
597
- def get_abi_input_names(abi_element: ABIElement) -> List[Optional[str]]:
622
+ def get_abi_input_names(abi_element: ABIElement) -> list[str | None]:
598
623
  """
599
624
  Return names for each input from the function or event ABI.
600
625
 
@@ -630,7 +655,7 @@ def get_abi_input_names(abi_element: ABIElement) -> List[Optional[str]]:
630
655
  ]
631
656
 
632
657
 
633
- def get_abi_input_types(abi_element: ABIElement) -> List[str]:
658
+ def get_abi_input_types(abi_element: ABIElement) -> list[str]:
634
659
  """
635
660
  Return types for each input from the function or event ABI.
636
661
 
@@ -666,7 +691,7 @@ def get_abi_input_types(abi_element: ABIElement) -> List[str]:
666
691
  ]
667
692
 
668
693
 
669
- def get_abi_output_names(abi_element: ABIElement) -> List[Optional[str]]:
694
+ def get_abi_output_names(abi_element: ABIElement) -> list[str | None]:
670
695
  """
671
696
  Return names for each output from the ABI element.
672
697
 
@@ -711,7 +736,7 @@ def get_abi_output_names(abi_element: ABIElement) -> List[Optional[str]]:
711
736
  ]
712
737
 
713
738
 
714
- def get_abi_output_types(abi_element: ABIElement) -> List[str]:
739
+ def get_abi_output_types(abi_element: ABIElement) -> list[str]:
715
740
  """
716
741
  Return types for each output from the function ABI.
717
742
 
@@ -2,9 +2,10 @@ import re
2
2
  from typing import (
3
3
  Any,
4
4
  Final,
5
- Union,
5
+ TypeGuard,
6
6
  )
7
7
 
8
+ import cchecksum
8
9
  from eth_typing import (
9
10
  Address,
10
11
  AnyAddress,
@@ -12,21 +13,13 @@ from eth_typing import (
12
13
  HexAddress,
13
14
  HexStr,
14
15
  )
15
- from typing_extensions import (
16
- TypeGuard,
17
- )
18
16
 
19
17
  from .conversions import (
20
18
  hexstr_if_str,
21
19
  to_hex,
22
20
  )
23
- from .crypto import (
24
- keccak,
25
- )
26
21
  from .hexadecimal import (
27
- add_0x_prefix,
28
22
  decode_hex,
29
- encode_hex,
30
23
  remove_0x_prefix,
31
24
  )
32
25
  from .types import (
@@ -37,6 +30,13 @@ from .types import (
37
30
  _HEX_ADDRESS_REGEXP: Final = re.compile("(0x)?[0-9a-f]{40}", re.IGNORECASE | re.ASCII)
38
31
 
39
32
 
33
+ to_checksum_address: Final = cchecksum.to_checksum_address
34
+ """
35
+ Makes a checksum address given a supported format.
36
+ We use the `cchecksum` implementation for max speed.
37
+ """
38
+
39
+
40
40
  def is_hex_address(value: Any) -> TypeGuard[HexAddress]:
41
41
  """
42
42
  Checks if the given string of text type is an address in hexadecimal encoded form.
@@ -68,7 +68,7 @@ def is_address(value: Any) -> bool:
68
68
  return False
69
69
 
70
70
 
71
- def to_normalized_address(value: Union[AnyAddress, str, bytes]) -> HexAddress:
71
+ def to_normalized_address(value: AnyAddress | str | bytes) -> HexAddress:
72
72
  """
73
73
  Converts an address to its normalized hexadecimal representation.
74
74
  """
@@ -92,7 +92,7 @@ def is_normalized_address(value: Any) -> TypeGuard[HexAddress]:
92
92
  return is_address(value) and value == to_normalized_address(value)
93
93
 
94
94
 
95
- def to_canonical_address(address: Union[AnyAddress, str, bytes]) -> Address:
95
+ def to_canonical_address(address: AnyAddress | str | bytes) -> Address:
96
96
  """
97
97
  Convert a valid address to its canonical form (20-length bytes).
98
98
  """
@@ -107,37 +107,16 @@ def is_canonical_address(address: Any) -> TypeGuard[Address]:
107
107
  8
108
108
 
109
109
  def is_same_address(
110
- left: Union[AnyAddress, str, bytes], right: Union[AnyAddress, str, bytes]
110
+ left: AnyAddress | str | bytes, right: AnyAddress | str | bytes
111
111
  ) -> bool:
112
112
  """
113
113
  Checks if both addresses are same or not.
114
114
  """
115
115
  if not is_address(left) or not is_address(right):
116
116
  raise ValueError("Both values must be valid addresses")
117
- else:
118
- return to_normalized_address(left) == to_normalized_address(right)
119
-
120
-
121
- def to_checksum_address(value: Union[AnyAddress, str, bytes]) -> ChecksumAddress:
122
- """
123
- Makes a checksum address given a supported format.
124
- """
125
- norm_address = to_normalized_address(value)
126
- address_hash = encode_hex(keccak(text=remove_0x_prefix(HexStr(norm_address))))
127
-
128
- checksum_address = add_0x_prefix(
129
- HexStr(
130
- "".join(
131
- (
132
- norm_address[i].upper()
133
- if int(address_hash[i], 16) > 7
134
- else norm_address[i]
135
- )
136
- for i in range(2, 42)
137
- )
138
- )
139
- )
140
- return ChecksumAddress(HexAddress(checksum_address))
117
+ if left == right:
118
+ return True
119
+ return to_normalized_address(left) == to_normalized_address(right)
141
120
 
142
121
 
143
122
  def is_checksum_address(value: Any) -> TypeGuard[ChecksumAddress]: