Skip to content

Commit 8b53dbf

Browse files
committed
feat: optimize reject_recursive_repeats
1 parent 8a2f478 commit 8b53dbf

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

web3/_utils/decorators.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from typing import (
44
Any,
55
Callable,
6+
Set,
7+
Tuple,
68
TypeVar,
79
cast,
810
)
@@ -20,21 +22,22 @@ def reject_recursive_repeats(to_wrap: Callable[..., Any]) -> Callable[..., Any]:
2022
Prevent simple cycles by returning None when called recursively with same instance
2123
"""
2224
# types ignored b/c dynamically set attribute
23-
to_wrap.__already_called = {} # type: ignore
25+
already_called: Set[Tuple[int, ...]] = set()
26+
to_wrap.__already_called = already_called # type: ignore
27+
28+
add_call = already_called.add
29+
remove_call = already_called.remove
2430

2531
@functools.wraps(to_wrap)
2632
def wrapped(*args: Any) -> Any:
27-
arg_instances = tuple(map(id, args))
28-
thread_id = threading.get_ident()
29-
thread_local_args = (thread_id,) + arg_instances
30-
if thread_local_args in to_wrap.__already_called: # type: ignore
33+
thread_local_args = (threading.get_ident(), *map(id, args))
34+
if thread_local_args in already_called:
3135
raise Web3ValueError(f"Recursively called {to_wrap} with {args!r}")
32-
to_wrap.__already_called[thread_local_args] = True # type: ignore
36+
add_call(thread_local_args)
3337
try:
34-
wrapped_val = to_wrap(*args)
38+
return to_wrap(*args)
3539
finally:
36-
del to_wrap.__already_called[thread_local_args] # type: ignore
37-
return wrapped_val
40+
remove_call(thread_local_args)
3841

3942
return wrapped
4043

0 commit comments

Comments
 (0)