-
Notifications
You must be signed in to change notification settings - Fork 269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix support for callable coders #76
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
from eth_abi.abi import ( | ||
decode_single, | ||
encode_single, | ||
) | ||
from eth_abi.decoding import ( | ||
BaseDecoder, | ||
) | ||
from eth_abi.encoding import ( | ||
BaseEncoder, | ||
) | ||
from eth_abi.exceptions import ( | ||
DecodingError, | ||
EncodingError, | ||
) | ||
from eth_abi.registry import ( | ||
registry, | ||
) | ||
|
||
NULL_ENCODING = b'\x00' * 32 | ||
|
||
|
||
def encode_null(x): | ||
if x is not None: | ||
raise EncodingError('Unsupported value') | ||
|
||
return NULL_ENCODING | ||
|
||
|
||
def decode_null(stream): | ||
if stream.read(32) != NULL_ENCODING: | ||
raise DecodingError('Not enough data or wrong data') | ||
|
||
return None | ||
|
||
|
||
class EncodeNull(BaseEncoder): | ||
word_width = None | ||
|
||
@classmethod | ||
def from_type_str(cls, type_str, registry): | ||
word_width = int(type_str[4:]) | ||
return cls(word_width=word_width) | ||
|
||
def encode(self, value): | ||
self.validate_value(value) | ||
return NULL_ENCODING * self.word_width | ||
|
||
def validate_value(self, value): | ||
if value is not None: | ||
raise EncodingError('Unsupported value') | ||
|
||
|
||
class DecodeNull(BaseDecoder): | ||
word_width = None | ||
|
||
@classmethod | ||
def from_type_str(cls, type_str, registry): | ||
word_width = int(type_str[4:]) | ||
return cls(word_width=word_width) | ||
|
||
def decode(self, stream): | ||
byts = stream.read(32 * self.word_width) | ||
if byts != NULL_ENCODING * self.word_width: | ||
raise DecodingError('Not enough data or wrong data') | ||
|
||
return None | ||
|
||
|
||
def test_register_and_use_callables(): | ||
registry.register('null', encode_null, decode_null) | ||
|
||
assert encode_single('null', None) == NULL_ENCODING | ||
assert decode_single('null', NULL_ENCODING) is None | ||
|
||
encoded_tuple = encode_single('(int,null)', (1, None)) | ||
|
||
assert encoded_tuple == b'\x00' * 31 + b'\x01' + NULL_ENCODING | ||
assert decode_single('(int,null)', encoded_tuple) == (1, None) | ||
|
||
registry.unregister('null') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This @pytest.fixture
def registry():
return make_registry() Then we don't have to worry about unregistering. Since there are other more pressing issues, maybe just capture the idea into an issue and we can come back to it later. (if you like it) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about making a fixture but just decided it was an okay hack for the time being. Also, I felt like it would be useful to test the functionality by calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Issue created: #77 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be wrapped in a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PR created for this: #79 |
||
|
||
|
||
def test_register_and_use_coder_classes(): | ||
registry.register( | ||
lambda x: x.startswith('null'), | ||
EncodeNull, | ||
DecodeNull, | ||
label='null', | ||
) | ||
|
||
assert encode_single('null2', None) == NULL_ENCODING * 2 | ||
assert decode_single('null2', NULL_ENCODING * 2) is None | ||
|
||
encoded_tuple = encode_single('(int,null2)', (1, None)) | ||
|
||
assert encoded_tuple == b'\x00' * 31 + b'\x01' + NULL_ENCODING * 2 | ||
assert decode_single('(int,null2)', encoded_tuple) == (1, None) | ||
|
||
registry.unregister('null') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is confusing to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for catching that. I intended for that to be
return cls()
and I believe my thinking was that it would make some of the examples in the registry documentation more simple but then I just went with slightly more complex examples. I'll make a PR to revert it right away.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR created for this: #78