Make TPayload hashable
#331
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We've been using Thriftpy2 successfully for a little while, however have run into what we consider a bug.
When a
TPayload(which I understand to be a struct, union, or exception) is used as the key inside a Thrift map, the binary protocol will attempt to store thatTPayloadvalue as the key in adict. BecauseTPayload.__hash__is set toNone, this makesTPayloadinstances unhashable, and so they can't be used fordictkeys and instead throw this exception:Now
TPayload.__hash__is set toNonewas done intentionally in daa213d apparently to fix #184. There are skim details on this motivation and that particular issue, but laterTExceptionwas made hashable in 40219d4, again with skim details.Given structs and unions are viable Thrift
mapkeys, I would consider the current behavior a bug. The most direct fix is just to restore the oldTPayload.__hash__logic. That makesTPayloadhashable, but I am not sure if this is a good idea as it was purposefully made unhashable. Though that fix was from 2016, nearly 10 years ago, and so I am wondering if the fix is still needed?The less direct way to fix this is to have the binary protocol (and also the compact protocol) read a map not into a vanilla Python
dict, but into some custom type that implements__contains__and is otherwise duck-typed like adict, but does nothash(key)ifkeyis aTPayload, instead doing some other thing.This PR implements the direct fix, but again let me know that is a bad idea. If so I can do the less direct fix, or another fix you think is more appropriate. Happy to fixup this PR to implement whatever.