diff --git a/build/__native_5f8b22f5f815a3776376.c b/build/__native_5f8b22f5f815a3776376.c index 2e4bae1f79..0fd049e4d2 100644 --- a/build/__native_5f8b22f5f815a3776376.c +++ b/build/__native_5f8b22f5f815a3776376.c @@ -236283,22 +236283,19 @@ PyObject *CPyDef_persistent_connection___PersistentConnection___subscriptions(Py cpy_r_r3 = cpy_r_r2; else { CPy_TypeErrorTraceback("faster_web3/providers/persistent/persistent_connection.py", "subscriptions", 50, CPyStatic_persistent_connection___globals, "faster_web3.providers.persistent.request_processor.RequestProcessor", cpy_r_r2); - goto CPyL5; + goto CPyL4; } cpy_r_r4 = CPyDef_request_processor___RequestProcessor___active_subscriptions(cpy_r_r3); + CPy_DECREF_NO_IMM(cpy_r_r3); if (unlikely(cpy_r_r4 == NULL)) { CPy_AddTraceback("faster_web3/providers/persistent/persistent_connection.py", "subscriptions", DIFFCHECK_PLACEHOLDER, CPyStatic_persistent_connection___globals); - goto CPyL5; + goto CPyL4; } CPyL3: ; - CPy_DECREF(cpy_r_r2); return cpy_r_r4; CPyL4: ; cpy_r_r5 = NULL; return cpy_r_r5; -CPyL5: ; - CPy_DecRef(cpy_r_r2); - goto CPyL4; } PyObject *CPyPy_persistent_connection___PersistentConnection___subscriptions(PyObject *self, PyObject *const *args, size_t nargs, PyObject *kwnames) { @@ -290138,7 +290135,7 @@ const char * const CPyLit_Str[] = { "\003\beth_sign\021eth_signTypedData$RPC_METHODS_UNSUPPORTED_DURING_BATCH", "\004\033faster_web3._utils.batching\004web3\016_requests_info\024_async_requests_info", "\004\016RequestBatcher\ais_text\bis_bytes\alatin-1", - "\005\036unrecognized block reference: \rWeb3TypeError\tfinalized\004safe\bearliest", + "\005\036unrecognized block reference: \rWeb3TypeError\004safe\tfinalized\bearliest", "\002\tis_string\006is_hex", "\001=Value did not match any of the recognized block identifiers: ", "\004\tTypeGuard\021typing_extensions\023ASYNC_PROVIDER_TYPE\022SYNC_PROVIDER_TYPE", @@ -290784,8 +290781,8 @@ const int CPyLit_Tuple[] = { 517, 1932, 1, 2315, 8, 73, 74, 366, 76, 78, 80, 522, 82, 1, 801 }; const int CPyLit_FrozenSet[] = { - 4, 5, 394, 395, 296, 308, 396, 3, 19, 1941, 0, 2, 895, 896, 4, 1092, - 1091, 1089, 379 + 4, 5, 308, 394, 296, 395, 396, 3, 19, 1941, 0, 2, 895, 896, 4, 1089, + 1091, 1092, 379 }; CPyModule *CPyModule_faster_ens__internal = NULL; CPyModule *CPyModule_faster_ens; diff --git a/faster_web3/datastructures.py b/faster_web3/datastructures.py index 68d042b9c7..d12d1b1fdd 100644 --- a/faster_web3/datastructures.py +++ b/faster_web3/datastructures.py @@ -139,8 +139,10 @@ class AttributeDict(ReadableAttributeDict[TKey, TValue], Hashable): Provides superficial immutability, someone could hack around it """ + __hash: Optional[int] = None + def __setattr__(self, attr: str, val: TValue) -> None: - if attr == "__dict__": + if attr in ("__dict__", "_AttributeDict__hash"): super().__setattr__(attr, val) else: raise Web3TypeError( @@ -153,7 +155,11 @@ def __delattr__(self, key: str) -> None: ) def __hash__(self) -> int: - return hash(tuple(sorted(tupleize_lists_nested(self).items()))) + cached_hash = self.__hash + if cached_hash is None: + # The hash value was not cached, let's compute it and store it + cached_hash = self.__hash = hash(tuple(sorted(tupleize_lists_nested(self).items()))) + return cached_hash def __eq__(self, other: Any) -> bool: if isinstance(other, AttributeDict):