faster-eth-utils 2.3.1__cp311-cp311-win32.whl → 5.3.23__cp311-cp311-win32.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 (54) hide show
  1. faster_eth_utils/__init__.py +54 -17
  2. faster_eth_utils/__json/eth_networks.json +1 -0
  3. faster_eth_utils/__main__.py +3 -1
  4. faster_eth_utils/abi.cp311-win32.pyd +0 -0
  5. faster_eth_utils/abi.py +840 -37
  6. faster_eth_utils/address.cp311-win32.pyd +0 -0
  7. faster_eth_utils/address.py +54 -66
  8. faster_eth_utils/applicators.cp311-win32.pyd +0 -0
  9. faster_eth_utils/applicators.py +126 -71
  10. faster_eth_utils/conversions.cp311-win32.pyd +0 -0
  11. faster_eth_utils/conversions.py +57 -30
  12. faster_eth_utils/crypto.cp311-win32.pyd +0 -0
  13. faster_eth_utils/crypto.py +11 -6
  14. faster_eth_utils/currency.cp311-win32.pyd +0 -0
  15. faster_eth_utils/currency.py +74 -33
  16. faster_eth_utils/curried/__init__.py +110 -89
  17. faster_eth_utils/debug.cp311-win32.pyd +0 -0
  18. faster_eth_utils/debug.py +3 -3
  19. faster_eth_utils/decorators.cp311-win32.pyd +0 -0
  20. faster_eth_utils/decorators.py +73 -24
  21. faster_eth_utils/encoding.cp311-win32.pyd +0 -0
  22. faster_eth_utils/encoding.py +1 -1
  23. faster_eth_utils/exceptions.cp311-win32.pyd +0 -0
  24. faster_eth_utils/exceptions.py +8 -3
  25. faster_eth_utils/functional.cp311-win32.pyd +0 -0
  26. faster_eth_utils/functional.py +42 -28
  27. faster_eth_utils/hexadecimal.cp311-win32.pyd +0 -0
  28. faster_eth_utils/hexadecimal.py +34 -26
  29. faster_eth_utils/humanize.cp311-win32.pyd +0 -0
  30. faster_eth_utils/humanize.py +55 -27
  31. faster_eth_utils/logging.py +65 -64
  32. faster_eth_utils/module_loading.cp311-win32.pyd +0 -0
  33. faster_eth_utils/module_loading.py +8 -7
  34. faster_eth_utils/network.cp311-win32.pyd +0 -0
  35. faster_eth_utils/network.py +25 -14
  36. faster_eth_utils/numeric.cp311-win32.pyd +0 -0
  37. faster_eth_utils/numeric.py +11 -4
  38. faster_eth_utils/pydantic.py +99 -0
  39. faster_eth_utils/toolz.cp311-win32.pyd +0 -0
  40. faster_eth_utils/toolz.py +82 -152
  41. faster_eth_utils/types.cp311-win32.pyd +0 -0
  42. faster_eth_utils/types.py +34 -21
  43. faster_eth_utils/typing/misc.py +3 -1
  44. faster_eth_utils/units.cp311-win32.pyd +0 -0
  45. faster_eth_utils-5.3.23.dist-info/METADATA +192 -0
  46. faster_eth_utils-5.3.23.dist-info/RECORD +53 -0
  47. {faster_eth_utils-2.3.1.dist-info → faster_eth_utils-5.3.23.dist-info}/licenses/LICENSE +1 -1
  48. faster_eth_utils-5.3.23.dist-info/top_level.txt +3 -0
  49. faster_eth_utils__mypyc.cp311-win32.pyd +0 -0
  50. bce0bfc64ce5e845ec4a__mypyc.cp311-win32.pyd +0 -0
  51. faster_eth_utils-2.3.1.dist-info/METADATA +0 -160
  52. faster_eth_utils-2.3.1.dist-info/RECORD +0 -45
  53. faster_eth_utils-2.3.1.dist-info/top_level.txt +0 -3
  54. {faster_eth_utils-2.3.1.dist-info → faster_eth_utils-5.3.23.dist-info}/WHEEL +0 -0
@@ -1,9 +1,20 @@
1
1
  import decimal
2
- from decimal import localcontext
3
- from typing import Final, Union, final
4
-
5
- from .types import is_integer, is_string
6
- from .units import units
2
+ from decimal import (
3
+ localcontext,
4
+ )
5
+ from typing import (
6
+ Final,
7
+ Union,
8
+ final,
9
+ )
10
+
11
+ from .types import (
12
+ is_integer,
13
+ is_string,
14
+ )
15
+ from .units import (
16
+ units,
17
+ )
7
18
 
8
19
 
9
20
  @final
@@ -35,24 +46,17 @@ class denoms:
35
46
 
36
47
  MIN_WEI: Final = 0
37
48
  MAX_WEI: Final = 2**256 - 1
49
+ DECIMAL_ZERO: Final = decimal.Decimal(0)
38
50
 
51
+ _NumberType = Union[int, float, str, decimal.Decimal]
39
52
 
40
- def from_wei(number: int, unit: str) -> Union[int, decimal.Decimal]:
41
- """
42
- Takes a number of wei and converts it to any other ether unit.
43
- """
44
- if unit.lower() not in units:
45
- raise ValueError(
46
- "Unknown unit. Must be one of {0}".format("/".join(units.keys()))
47
- )
48
53
 
54
+ def _from_wei(number: int, unit_value: decimal.Decimal) -> int | decimal.Decimal:
49
55
  if number == 0:
50
56
  return 0
51
57
 
52
58
  if number < MIN_WEI or number > MAX_WEI:
53
- raise ValueError("value must be between 1 and 2**256 - 1")
54
-
55
- unit_value = units[unit.lower()]
59
+ raise ValueError("value must be between 0 and 2**256 - 1")
56
60
 
57
61
  with localcontext() as ctx:
58
62
  ctx.prec = 999
@@ -62,35 +66,26 @@ def from_wei(number: int, unit: str) -> Union[int, decimal.Decimal]:
62
66
  return result_value
63
67
 
64
68
 
65
- def to_wei(number: Union[int, float, str, decimal.Decimal], unit: str) -> int:
66
- """
67
- Takes a number of a unit and converts it to wei.
68
- """
69
- if unit.lower() not in units:
70
- raise ValueError(
71
- "Unknown unit. Must be one of {0}".format("/".join(units.keys()))
72
- )
73
-
69
+ def _to_wei(number: _NumberType, unit_value: decimal.Decimal) -> int:
74
70
  if is_integer(number) or is_string(number):
75
- d_number = decimal.Decimal(value=number)
71
+ d_number = decimal.Decimal(value=number) # type: ignore [arg-type]
76
72
  elif isinstance(number, float):
77
73
  d_number = decimal.Decimal(value=str(number))
78
74
  elif isinstance(number, decimal.Decimal):
79
75
  d_number = number
80
76
  else:
81
- raise TypeError("Unsupported type. Must be one of integer, float, or string")
77
+ raise TypeError("Unsupported type. Must be one of integer, float, or string")
82
78
 
83
- s_number = str(number)
84
- unit_value = units[unit.lower()]
85
-
86
- if d_number == decimal.Decimal(0):
79
+ if d_number == DECIMAL_ZERO:
87
80
  return 0
88
81
 
82
+ s_number = str(number)
83
+
89
84
  if d_number < 1 and "." in s_number:
90
85
  with localcontext() as ctx:
91
86
  multiplier = len(s_number) - s_number.index(".") - 1
92
87
  ctx.prec = multiplier
93
- d_number = decimal.Decimal(value=number, context=ctx) * 10**multiplier
88
+ d_number = decimal.Decimal(value=number, context=ctx) * 10**multiplier # type: ignore [arg-type]
94
89
  unit_value /= 10**multiplier
95
90
 
96
91
  with localcontext() as ctx:
@@ -98,6 +93,52 @@ def to_wei(number: Union[int, float, str, decimal.Decimal], unit: str) -> int:
98
93
  result_value = decimal.Decimal(value=d_number, context=ctx) * unit_value
99
94
 
100
95
  if result_value < MIN_WEI or result_value > MAX_WEI:
101
- raise ValueError("Resulting wei value must be between 1 and 2**256 - 1")
96
+ raise ValueError("Resulting wei value must be between 0 and 2**256 - 1")
102
97
 
103
98
  return int(result_value)
99
+
100
+
101
+ def from_wei(number: int, unit: str) -> int | decimal.Decimal:
102
+ """
103
+ Takes a number of wei and converts it to any other ether unit.
104
+ """
105
+ unit_key = unit.lower()
106
+ if unit_key not in units:
107
+ raise ValueError(f"Unknown unit. Must be one of {'/'.join(units.keys())}")
108
+
109
+ unit_value = units[unit_key]
110
+
111
+ return _from_wei(number, unit_value)
112
+
113
+
114
+ def to_wei(number: _NumberType, unit: str) -> int:
115
+ """
116
+ Takes a number of a unit and converts it to wei.
117
+ """
118
+ unit_key = unit.lower()
119
+ if unit_key not in units:
120
+ raise ValueError(f"Unknown unit. Must be one of {'/'.join(units.keys())}")
121
+
122
+ unit_value = units[unit_key]
123
+
124
+ return _to_wei(number, unit_value)
125
+
126
+
127
+ def from_wei_decimals(number: int, decimals: int) -> int | decimal.Decimal:
128
+ """
129
+ Takes a number of wei and converts it to a decimal with the specified
130
+ number of decimals.
131
+ """
132
+ unit_value = decimal.Decimal(10) ** decimal.Decimal(value=decimals)
133
+
134
+ return _from_wei(number, unit_value)
135
+
136
+
137
+ def to_wei_decimals(number: _NumberType, decimals: int) -> int:
138
+ """
139
+ Takes a number of a unit and converts it to wei with the specified
140
+ number of decimals.
141
+ """
142
+ unit_value = decimal.Decimal(10) ** decimal.Decimal(value=decimals)
143
+
144
+ return _to_wei(number, unit_value)
@@ -1,18 +1,17 @@
1
- # flake8: noqa
1
+ import sys
2
+ from collections.abc import Callable, Generator, Sequence
2
3
  from typing import (
4
+ TYPE_CHECKING,
3
5
  Any,
4
- Callable,
5
- Dict,
6
- Generator,
7
6
  Optional,
8
- Sequence,
9
- Tuple,
7
+ TypeGuard,
10
8
  TypeVar,
11
9
  Union,
12
10
  overload,
13
11
  )
14
12
 
15
13
  from faster_eth_utils import (
14
+ CamelModel,
16
15
  ExtendedDebugLogger,
17
16
  HasExtendedDebugLogger,
18
17
  HasExtendedDebugLoggerMeta,
@@ -20,13 +19,19 @@ from faster_eth_utils import (
20
19
  HasLoggerMeta,
21
20
  Network,
22
21
  ValidationError,
22
+ abi_to_signature,
23
23
  add_0x_prefix,
24
24
  apply_formatter_at_index,
25
- )
26
- from faster_eth_utils import (
25
+ apply_formatter_if as non_curried_apply_formatter_if,
26
+ apply_formatter_to_array,
27
+ apply_formatters_to_dict as non_curried_apply_formatters_to_dict,
28
+ apply_formatters_to_sequence,
29
+ apply_key_map,
30
+ apply_one_of_formatters as non_curried_apply_one_of_formatters,
27
31
  apply_to_return_value,
28
32
  big_endian_to_int,
29
33
  clamp,
34
+ collapse_if_tuple,
30
35
  combine_argument_formatters,
31
36
  combomethod,
32
37
  decode_hex,
@@ -34,16 +39,27 @@ from faster_eth_utils import (
34
39
  encode_hex,
35
40
  event_abi_to_log_topic,
36
41
  event_signature_to_log_topic,
42
+ filter_abi_by_name,
43
+ filter_abi_by_type,
37
44
  flatten_return,
38
45
  from_wei,
46
+ from_wei_decimals,
39
47
  function_abi_to_4byte_selector,
40
48
  function_signature_to_4byte_selector,
49
+ get_abi_input_names,
50
+ get_abi_input_types,
51
+ get_abi_output_names,
52
+ get_abi_output_types,
53
+ get_aligned_abi_inputs,
54
+ get_all_event_abis,
55
+ get_all_function_abis,
41
56
  get_extended_debug_logger,
42
57
  get_logger,
43
- )
44
- from faster_eth_utils import (
58
+ get_normalized_abi_inputs,
59
+ hexstr_if_str as non_curried_hexstr_if_str,
45
60
  humanize_bytes,
46
61
  humanize_hash,
62
+ humanize_hexstr,
47
63
  humanize_integer_sequence,
48
64
  humanize_ipfs_uri,
49
65
  humanize_seconds,
@@ -81,8 +97,7 @@ from faster_eth_utils import (
81
97
  setup_DEBUG2_logging,
82
98
  short_name_from_chain_id,
83
99
  sort_return,
84
- )
85
- from faster_eth_utils import (
100
+ text_if_str as non_curried_text_if_str,
86
101
  to_bytes,
87
102
  to_canonical_address,
88
103
  to_checksum_address,
@@ -96,175 +111,181 @@ from faster_eth_utils import (
96
111
  to_text,
97
112
  to_tuple,
98
113
  to_wei,
114
+ to_wei_decimals,
99
115
  )
100
- from faster_eth_utils import apply_formatter_if as non_curried_apply_formatter_if
101
- from faster_eth_utils import apply_formatter_to_array
102
- from faster_eth_utils import apply_formatters_to_dict as non_curried_apply_formatters_to_dict
103
- from faster_eth_utils import apply_formatters_to_sequence, apply_key_map
104
- from faster_eth_utils import apply_one_of_formatters as non_curried_apply_one_of_formatters
105
- from faster_eth_utils import hexstr_if_str as non_curried_hexstr_if_str
106
- from faster_eth_utils import text_if_str as non_curried_text_if_str
107
- from faster_eth_utils.toolz import curry
116
+ from faster_eth_utils.toolz import (
117
+ curry,
118
+ )
119
+
120
+ if TYPE_CHECKING:
121
+ from _typeshed import SupportsBool
122
+ # We have to sacrifice a little bit of specificity on dinosaur Python3.8
108
123
 
124
+
125
+ TArg = TypeVar("TArg")
126
+ TOther = TypeVar("TOther")
109
127
  TReturn = TypeVar("TReturn")
110
128
  TValue = TypeVar("TValue")
111
129
 
112
130
 
113
131
  @overload
114
132
  def apply_formatter_if(
115
- condition: Callable[..., bool]
116
- ) -> Callable[[Callable[..., TReturn]], Callable[[TValue], Union[TReturn, TValue]]]:
133
+ condition: Callable[[TArg], TypeGuard[TOther]],
134
+ ) -> Callable[[Callable[[TOther], TReturn]], Callable[[TArg], TReturn | TArg]]:
117
135
  ...
118
136
 
119
-
120
137
  @overload
121
138
  def apply_formatter_if(
122
- condition: Callable[..., bool], formatter: Callable[..., TReturn]
123
- ) -> Callable[[TValue], Union[TReturn, TValue]]:
139
+ condition: Callable[[TArg], TypeGuard[TOther]], formatter: Callable[[TOther], TReturn]
140
+ ) -> Callable[[TArg], TReturn | TArg]:
124
141
  ...
125
142
 
126
-
127
143
  @overload
128
144
  def apply_formatter_if(
129
- condition: Callable[..., bool], formatter: Callable[..., TReturn], value: TValue
130
- ) -> Union[TReturn, TValue]:
145
+ condition: Callable[[TArg], TypeGuard[TOther]], formatter: Callable[[TOther], TReturn], value: TArg
146
+ ) -> TReturn | TArg:
131
147
  ...
132
148
 
133
-
134
- # This is just a stub to appease mypy, it gets overwritten later
149
+ @overload
135
150
  def apply_formatter_if(
136
- condition: Callable[..., bool],
137
- formatter: Callable[..., TReturn] = None,
138
- value: TValue = None,
139
- ) -> Union[
140
- Callable[[Callable[..., TReturn]], Callable[[TValue], Union[TReturn, TValue]]],
141
- Callable[[TValue], Union[TReturn, TValue]],
142
- TReturn,
143
- TValue,
144
- ]:
151
+ condition: Callable[[TArg], bool], formatter: Callable[[TArg], TReturn], value: TArg
152
+ ) -> TReturn | TArg:
145
153
  ...
146
154
 
155
+ def apply_formatter_if( # type: ignore
156
+ condition: Callable[[TArg], TypeGuard[TOther]] | Callable[[TArg], bool],
157
+ formatter: Callable[[TOther], TReturn] | Callable[[TArg], TReturn] | None = None,
158
+ value: TArg | None = None,
159
+ ) -> (
160
+ Callable[[Callable[[TOther], TReturn]], Callable[[TArg], TReturn | TArg]] |
161
+ Callable[[TArg], TReturn | TArg] |
162
+ TReturn |
163
+ TArg
164
+ ):
165
+ pass
166
+
147
167
 
148
168
  @overload
149
169
  def apply_one_of_formatters(
150
170
  formatter_condition_pairs: Sequence[
151
- Tuple[Callable[..., bool], Callable[..., TReturn]]
152
- ]
153
- ) -> Callable[[TValue], TReturn]:
154
- ...
171
+ tuple[Callable[[TArg], "SupportsBool"], Callable[[TArg], TReturn]]
172
+ ],
173
+ ) -> Callable[[TArg], TReturn]: ...
155
174
 
156
175
 
157
176
  @overload
158
177
  def apply_one_of_formatters(
159
178
  formatter_condition_pairs: Sequence[
160
- Tuple[Callable[..., bool], Callable[..., TReturn]]
179
+ tuple[Callable[[TArg], "SupportsBool"], Callable[[TArg], TReturn]]
161
180
  ],
162
- value: TValue,
163
- ) -> TReturn:
164
- ...
181
+ value: TArg,
182
+ ) -> TReturn: ...
165
183
 
166
184
 
167
185
  # This is just a stub to appease mypy, it gets overwritten later
168
- def apply_one_of_formatters(
186
+ def apply_one_of_formatters( # type: ignore[empty-body]
169
187
  formatter_condition_pairs: Sequence[
170
- Tuple[Callable[..., bool], Callable[..., TReturn]]
188
+ tuple[Callable[[TArg], "SupportsBool"], Callable[[TArg], TReturn]]
171
189
  ],
172
- value: TValue = None,
173
- ) -> TReturn:
174
- ...
190
+ value: TArg | None = None,
191
+ ) -> Callable[[TArg], TReturn] | TReturn: ...
175
192
 
176
193
 
177
194
  @overload
178
195
  def hexstr_if_str(
179
- to_type: Callable[..., TReturn]
180
- ) -> Callable[[Union[bytes, int, str]], TReturn]:
181
- ...
196
+ to_type: Callable[..., TReturn],
197
+ ) -> Callable[[bytes | int | str], TReturn]: ...
182
198
 
183
199
 
184
200
  @overload
185
201
  def hexstr_if_str(
186
- to_type: Callable[..., TReturn], to_format: Union[bytes, int, str]
187
- ) -> TReturn:
188
- ...
202
+ to_type: Callable[..., TReturn], to_format: bytes | int | str
203
+ ) -> TReturn: ...
189
204
 
190
205
 
191
206
  # This is just a stub to appease mypy, it gets overwritten later
192
- def hexstr_if_str(
193
- to_type: Callable[..., TReturn], to_format: Union[bytes, int, str] = None
194
- ) -> TReturn:
195
- ...
207
+ def hexstr_if_str( # type: ignore
208
+ to_type: Callable[..., TReturn], to_format: bytes | int | str | None = None
209
+ ) -> TReturn: ...
196
210
 
197
211
 
198
212
  @overload
199
213
  def text_if_str(
200
- to_type: Callable[..., TReturn]
201
- ) -> Callable[[Union[bytes, int, str]], TReturn]:
202
- ...
214
+ to_type: Callable[..., TReturn],
215
+ ) -> Callable[[bytes | int | str], TReturn]: ...
203
216
 
204
217
 
205
218
  @overload
206
219
  def text_if_str(
207
- to_type: Callable[..., TReturn], text_or_primitive: Union[bytes, int, str]
208
- ) -> TReturn:
209
- ...
220
+ to_type: Callable[..., TReturn], text_or_primitive: bytes | int | str
221
+ ) -> TReturn: ...
210
222
 
211
223
 
212
224
  # This is just a stub to appease mypy, it gets overwritten later
213
- def text_if_str(
214
- to_type: Callable[..., TReturn], text_or_primitive: Union[bytes, int, str] = None
215
- ) -> TReturn:
216
- ...
225
+ def text_if_str( # type: ignore
226
+ to_type: Callable[..., TReturn],
227
+ text_or_primitive: bytes | int | str | None = None,
228
+ ) -> TReturn: ...
217
229
 
218
230
 
219
231
  @overload
220
232
  def apply_formatters_to_dict(
221
- formatters: Dict[Any, Any]
222
- ) -> Callable[[Dict[Any, Any]], TReturn]:
233
+ formatters: dict[Any, Any], unaliased: bool = False
234
+ ) -> Callable[[dict[Any, Any] | CamelModel], dict[Any, Any]]:
223
235
  ...
224
236
 
225
237
 
226
238
  @overload
227
239
  def apply_formatters_to_dict(
228
- formatters: Dict[Any, Any], value: Dict[Any, Any]
229
- ) -> TReturn:
240
+ formatters: dict[Any, Any], value: dict[Any, Any] | CamelModel, unaliased: bool = False
241
+ ) -> dict[Any, Any]:
230
242
  ...
231
243
 
232
244
 
233
245
  # This is just a stub to appease mypy, it gets overwritten later
234
246
  def apply_formatters_to_dict(
235
- formatters: Dict[Any, Any], value: Optional[Dict[Any, Any]] = None
236
- ) -> TReturn:
237
- ...
247
+ formatters: dict[Any, Any],
248
+ value: dict[Any, Any] | CamelModel | None = None,
249
+ unaliased: bool = False,
250
+ ) -> dict[Any, Any]: ...
238
251
 
239
252
 
240
253
  apply_formatter_at_index = curry(apply_formatter_at_index)
241
- apply_formatter_if = curry(non_curried_apply_formatter_if)
254
+ apply_formatter_if = curry(non_curried_apply_formatter_if) # noqa: F811
242
255
  apply_formatter_to_array = curry(apply_formatter_to_array)
243
- apply_formatters_to_dict = curry(non_curried_apply_formatters_to_dict)
256
+ apply_formatters_to_dict = curry(non_curried_apply_formatters_to_dict) # noqa: F811
244
257
  apply_formatters_to_sequence = curry(apply_formatters_to_sequence)
245
258
  apply_key_map = curry(apply_key_map)
246
- apply_one_of_formatters = curry(non_curried_apply_one_of_formatters)
259
+ apply_one_of_formatters = curry(non_curried_apply_one_of_formatters) # noqa: F811
260
+ filter_abi_by_name = curry(filter_abi_by_name)
261
+ filter_abi_by_type = curry(filter_abi_by_type)
262
+ flatten_return = curry(flatten_return)
247
263
  from_wei = curry(from_wei)
264
+ from_wei_decimals = curry(from_wei_decimals)
265
+ get_aligned_abi_inputs = curry(get_aligned_abi_inputs)
248
266
  get_logger = curry(get_logger)
249
- hexstr_if_str = curry(non_curried_hexstr_if_str)
267
+ get_normalized_abi_inputs = curry(get_normalized_abi_inputs)
268
+ hexstr_if_str = curry(non_curried_hexstr_if_str) # noqa: F811
250
269
  is_same_address = curry(is_same_address)
251
- text_if_str = curry(non_curried_text_if_str)
270
+ sort_return = curry(sort_return)
271
+ text_if_str = curry(non_curried_text_if_str) # noqa: F811
272
+ to_ordered_dict = curry(to_ordered_dict)
252
273
  to_wei = curry(to_wei)
274
+ to_wei_decimals = curry(to_wei_decimals)
253
275
  clamp = curry(clamp)
254
276
 
255
277
  # Delete any methods and classes that are not intended to be importable from
256
- # eth_utils.curried
257
- # We do this approach instead of __all__ because this approach actually prevents
258
- # importing the wrong thing, while __all__ only affects `from eth_utils.curried import *`
278
+ # `eth_utils.curried`. We do this approach instead of __all__ because this approach
279
+ # actually prevents importing the wrong thing, while __all__ only affects
280
+ # `from eth_utils.curried import *`
259
281
  del Any
260
282
  del Callable
261
- del Dict
262
283
  del Generator
263
284
  del Optional
264
285
  del Sequence
265
286
  del TReturn
266
287
  del TValue
267
- del Tuple
288
+ del TypeGuard
268
289
  del TypeVar
269
290
  del Union
270
291
  del curry
Binary file
faster_eth_utils/debug.py CHANGED
@@ -5,15 +5,15 @@ import sys
5
5
 
6
6
  def pip_freeze() -> str:
7
7
  result = subprocess.run("python -m pip freeze".split(), stdout=subprocess.PIPE)
8
- return "python -m pip freeze result:\n%s" % result.stdout.decode()
8
+ return f"python -m pip freeze result:\n{result.stdout.decode()}"
9
9
 
10
10
 
11
11
  def python_version() -> str:
12
- return "Python version:\n%s" % sys.version
12
+ return f"Python version:\n{sys.version}"
13
13
 
14
14
 
15
15
  def platform_info() -> str:
16
- return "Operating System: %s" % platform.platform()
16
+ return f"Operating System: {platform.platform()}"
17
17
 
18
18
 
19
19
  def get_environment_summary() -> str:
Binary file
@@ -1,56 +1,103 @@
1
1
  import functools
2
- import itertools
3
- from typing import Any, Callable, Dict, Type, TypeVar, final
2
+ from collections.abc import Callable
3
+ from typing import (
4
+ Any,
5
+ Concatenate,
6
+ Final,
7
+ Generic,
8
+ TypeVar,
9
+ final,
10
+ )
4
11
 
5
- from .types import is_text
12
+ from typing_extensions import ParamSpec
13
+
14
+ P = ParamSpec("P")
6
15
 
7
16
  T = TypeVar("T")
8
17
 
18
+ TInstance = TypeVar("TInstance", bound=object)
19
+ """A TypeVar representing an instance that a method can bind to."""
20
+
9
21
 
10
22
  @final
11
- class combomethod(object):
12
- def __init__(self, method: Callable[..., Any]) -> None:
13
- self.method = method
14
-
15
- def __get__(self, obj: T = None, objtype: Type[T] = None) -> Callable[..., Any]:
16
- @functools.wraps(self.method)
17
- def _wrapper(*args: Any, **kwargs: Any) -> Any:
18
- if obj is not None:
19
- return self.method(obj, *args, **kwargs)
20
- else:
21
- return self.method(objtype, *args, **kwargs)
23
+ class combomethod(Generic[TInstance, P, T]):
24
+ def __init__(
25
+ self, method: Callable[Concatenate[TInstance | type[TInstance], P], T]
26
+ ) -> None:
27
+ self.method: Final = method
28
+
29
+ def __repr__(self) -> str:
30
+ return f"combomethod({self.method})"
31
+
32
+ def __get__(
33
+ self,
34
+ obj: TInstance | None,
35
+ objtype: type[TInstance],
36
+ ) -> Callable[P, T]:
37
+
38
+ method = self.method
39
+ bound_arg = objtype if obj is None else obj
40
+
41
+ @functools.wraps(method)
42
+ def _wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
43
+ return method(bound_arg, *args, **kwargs)
22
44
 
23
45
  return _wrapper
24
46
 
25
47
 
26
- def return_arg_type(at_position: int) -> Callable[..., Callable[..., T]]:
48
+ _return_arg_type_deco_cache: Final[
49
+ dict[int, Callable[[Callable[P, T]], Callable[P, Any]]]
50
+ ] = {}
51
+ # No need to hold so many unique instances in memory
52
+
53
+
54
+ def return_arg_type(at_position: int) -> Callable[[Callable[P, T]], Callable[P, Any]]:
27
55
  """
28
56
  Wrap the return value with the result of `type(args[at_position])`.
29
57
  """
58
+ if deco := _return_arg_type_deco_cache.get(at_position):
59
+ return deco
30
60
 
31
- def decorator(to_wrap: Callable[..., Any]) -> Callable[..., T]:
61
+ def decorator(to_wrap: Callable[P, Any]) -> Callable[P, Any]:
32
62
  @functools.wraps(to_wrap)
33
- def wrapper(*args: Any, **kwargs: Any) -> T:
63
+ def wrapper(*args: P.args, **kwargs: P.kwargs) -> Any:
34
64
  result = to_wrap(*args, **kwargs)
35
65
  ReturnType = type(args[at_position])
36
- return ReturnType(result) # type: ignore
66
+ return ReturnType(result) # type: ignore [call-arg]
37
67
 
38
68
  return wrapper
39
69
 
70
+ _return_arg_type_deco_cache[at_position] = decorator
71
+
40
72
  return decorator
41
73
 
42
74
 
75
+ ExcType = type[BaseException]
76
+
77
+ ReplaceExceptionsCache = dict[
78
+ tuple[tuple[ExcType, ExcType], ...],
79
+ Callable[[Callable[P, T]], Callable[P, T]],
80
+ ]
81
+
82
+ _replace_exceptions_deco_cache: Final[ReplaceExceptionsCache[..., Any]] = {}
83
+ # No need to hold so many unique instances in memory
84
+
85
+
43
86
  def replace_exceptions(
44
- old_to_new_exceptions: Dict[Type[BaseException], Type[BaseException]]
45
- ) -> Callable[[Callable[..., T]], Callable[..., T]]:
87
+ old_to_new_exceptions: dict[ExcType, ExcType],
88
+ ) -> Callable[[Callable[P, T]], Callable[P, T]]:
46
89
  """
47
90
  Replaces old exceptions with new exceptions to be raised in their place.
48
91
  """
49
- old_exceptions = tuple(old_to_new_exceptions.keys())
92
+ cache_key = tuple(old_to_new_exceptions.items())
93
+ if deco := _replace_exceptions_deco_cache.get(cache_key):
94
+ return deco
50
95
 
51
- def decorator(to_wrap: Callable[..., T]) -> Callable[..., T]:
96
+ old_exceptions = tuple(old_to_new_exceptions)
97
+
98
+ def decorator(to_wrap: Callable[P, T]) -> Callable[P, T]:
52
99
  @functools.wraps(to_wrap)
53
- def wrapped(*args: Any, **kwargs: Any) -> T:
100
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> T:
54
101
  try:
55
102
  return to_wrap(*args, **kwargs)
56
103
  except old_exceptions as err:
@@ -58,9 +105,11 @@ def replace_exceptions(
58
105
  raise old_to_new_exceptions[type(err)](err) from err
59
106
  except KeyError:
60
107
  raise TypeError(
61
- "could not look up new exception to use for %r" % err
108
+ f"could not look up new exception to use for {repr(err)}"
62
109
  ) from err
63
110
 
64
111
  return wrapped
65
112
 
113
+ _replace_exceptions_deco_cache[cache_key] = decorator
114
+
66
115
  return decorator
Binary file
@@ -2,5 +2,5 @@ def int_to_big_endian(value: int) -> bytes:
2
2
  return value.to_bytes((value.bit_length() + 7) // 8 or 1, "big")
3
3
 
4
4
 
5
- def big_endian_to_int(value: bytes) -> int:
5
+ def big_endian_to_int(value: bytes | bytearray) -> int:
6
6
  return int.from_bytes(value, "big")
Binary file