Description
- Version: 5.29.2
- Python: 3.8.10
- OS: Linux
What was wrong?
Depending on the items, AttributeDict
might not always be hashable.
For example, log entries returned by eth_getLogs()
can contain list objects (in this case 'topics'), which are not hashable.
AttributeDict({
'address': '0x2C846CF666f2D427ec86ca4BADe204fFD5CbC421',
'topics': [HexBytes('0xdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496'), HexBytes('0x000000000000000000000000e54ca86531e17ef3616d22ca28b0d458b6c89106'), HexBytes('0x000000000000000000000000d2f59be407080abfd97a00a7071d67f93b526733')],
'data': '0x000000000000000000000000000000000000000000000000000000000018921600000000000000000000000000000000000000000000000033bd1424be462f14',
'blockNumber': 16955438,
'transactionHash': HexBytes('0x932a26038bcf3d22bd981543b7ed6aae653a8a565a2a78bd644162c7e1bff6e4'),
'transactionIndex': 2,
'blockHash': HexBytes('0xd5b1c3a7704a26b1b7b47b12d1a929ecba82bb0cbf9b97f41d227ff104612f7b'),
'logIndex': 16,
'removed': False
})
How can it be fixed?
a) Adjust the __hash__
function. Recursively look for mutable types like lists, etc. and temporary replace them before hashing.
This would likely also require changing __eq__
as two object can now have the same hash without being "equal".
def __hash__(self) -> int:
return hash(tuple(sorted(self.items())))
b) Recursively replace mutable types (e.g. list -> tuple) when creating the AttributeDict object.
def __init__(
self, dictionary: Dict[TKey, TValue], *args: Any, **kwargs: Any
) -> None:
# type ignored on 46/50 b/c dict() expects str index type not TKey
self.__dict__ = dict(dictionary) # type: ignore
self.__dict__.update(dict(*args, **kwargs))
c) Handle it earlier, for instance when parsing response results.
d) Add a more restrictive TValue
type (e.g. allow only hashable values). That seems a much larger change though as it likely affects many parts/sections of the code base.
The AttributeDict
type is supposed to be immutable, this would suggest going with something like b).
I can prepare a PR, just need some directions on how you would like to have it solved.