Skip to content

Commit

Permalink
Remove encode_single / decode_single in favor of ``encode_abi…
Browse files Browse the repository at this point in the history
…`` / ``decode_abi``
  • Loading branch information
fselmo committed Apr 7, 2022
1 parent 7ea09ff commit b037171
Show file tree
Hide file tree
Showing 17 changed files with 274 additions and 325 deletions.
2 changes: 0 additions & 2 deletions eth_abi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

from eth_abi.abi import ( # NOQA
decode_abi,
decode_single,
encode_abi,
encode_single,
is_encodable,
is_encodable_type,
)
Expand Down
2 changes: 0 additions & 2 deletions eth_abi/abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
default_codec = ABICodec(registry)

encode_abi = default_codec.encode_abi
encode_single = default_codec.encode_single
decode_abi = default_codec.decode_abi
decode_single = default_codec.decode_single
is_encodable = default_codec.is_encodable
is_encodable_type = default_codec.is_encodable_type
36 changes: 0 additions & 36 deletions eth_abi/codec.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,6 @@ class ABIEncoder(BaseABICoder):
"""
Wraps a registry to provide last-mile encoding functionality.
"""
def encode_single(self, typ: TypeStr, arg: Any) -> bytes:
"""
Encodes the python value ``arg`` as a binary value of the ABI type
``typ``.
:param typ: The string representation of the ABI type that will be used
for encoding e.g. ``'uint256'``, ``'bytes[]'``, ``'(int,int)'``,
etc.
:param arg: The python value to be encoded.
:returns: The binary representation of the python value ``arg`` as a
value of the ABI type ``typ``.
"""
encoder = self._registry.get_encoder(typ)

return encoder(arg)

def encode_abi(self, types: Iterable[TypeStr], args: Iterable[Any]) -> bytes:
"""
Expand Down Expand Up @@ -134,26 +118,6 @@ class ABIDecoder(BaseABICoder):
"""
stream_class = ContextFramesBytesIO

def decode_single(self, typ: TypeStr, data: Decodable) -> Any:
"""
Decodes the binary value ``data`` of the ABI type ``typ`` into its
equivalent python value.
:param typ: The string representation of the ABI type that will be used for
decoding e.g. ``'uint256'``, ``'bytes[]'``, ``'(int,int)'``, etc.
:param data: The binary value to be decoded.
:returns: The equivalent python value of the ABI value represented in
``data``.
"""
if not is_bytes(data):
raise TypeError("The `data` value must be of bytes type. Got {0}".format(type(data)))

decoder = self._registry.get_decoder(typ)
stream = self.stream_class(data)

return decoder(stream)

def decode_abi(self, types: Iterable[TypeStr], data: Decodable) -> Tuple[Any, ...]:
"""
Decodes the binary value ``data`` as a sequence of values of the ABI types
Expand Down
1 change: 0 additions & 1 deletion eth_abi/packed.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@

default_encoder_packed = ABIEncoder(registry_packed)

encode_single_packed = default_encoder_packed.encode_single
encode_abi_packed = default_encoder_packed.encode_abi
is_encodable_packed = default_encoder_packed.is_encodable
35 changes: 33 additions & 2 deletions tests/abi/test_decode_abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@
)

from ..common.unit import (
CORRECT_DYNAMIC_ENCODINGS,
CORRECT_STATIC_ENCODINGS,
CORRECT_TUPLE_ENCODINGS,
words,
)


@pytest.mark.parametrize(
'type_str,expected,_1,abi_encoding,_2',
'type_str,expected,abi_encoding,_',
CORRECT_TUPLE_ENCODINGS,
)
def test_decode_abi(type_str, expected, _1, abi_encoding, _2):
def test_decode_abi_for_multiple_types_as_list(type_str, expected, abi_encoding, _):
abi_type = parse(type_str)
if abi_type.arrlist is not None:
pytest.skip('ABI coding functions do not support array types')
Expand All @@ -30,6 +33,34 @@ def test_decode_abi(type_str, expected, _1, abi_encoding, _2):
assert actual == expected


@pytest.mark.parametrize(
'type_str,expected,abi_encoding,_',
CORRECT_STATIC_ENCODINGS,
)
def test_abi_decode_for_single_static_types(type_str, expected, abi_encoding, _):
(actual,) = decode(abi_encoding, [type_str])
assert actual == expected


@pytest.mark.parametrize(
'type_str,expected,abi_encoding,_',
CORRECT_DYNAMIC_ENCODINGS,
)
def test_abi_decode_for_single_dynamic_types(type_str, expected, abi_encoding, _):
# Tests set up list values but encoders return sequences as tuples.
# i.e. [b'\xde\xad\xbe\xef'] vs encoder return type (b'\xde\xad\xbe\xef',)
expected = tuple(expected) if isinstance(expected, list) else expected

abi_encoding = (
# 32 bytes offset for dynamic types
b''.join([words('20'), abi_encoding])
)

(actual,) = decode(abi_encoding, [type_str])

assert actual == expected


def test_decode_abi_empty_data_raises():
with pytest.raises(DecodingError):
decode_abi(['uint32', 'uint32'], b'')
Expand Down
23 changes: 0 additions & 23 deletions tests/abi/test_decode_single.py

This file was deleted.

46 changes: 31 additions & 15 deletions tests/abi/test_encode_abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@
)

from ..common.unit import (
CORRECT_DYNAMIC_ENCODINGS,
CORRECT_STATIC_ENCODINGS,
CORRECT_TUPLE_ENCODINGS,
words,
)


@pytest.mark.parametrize(
'tuple_type,python_value,_1,encoded_list_of_types,_2',
'tuple_type,python_value,solidity_abi_encoded,_',
CORRECT_TUPLE_ENCODINGS,
)
def test_encode_abi_as_list_of_types(tuple_type, python_value, _1, encoded_list_of_types, _2):
def test_encode_abi_for_multiple_types_as_list(
tuple_type, python_value, solidity_abi_encoded, _
):
abi_type = parse(tuple_type)
if abi_type.arrlist is not None:
pytest.skip('ABI coding functions do not support array types')
Expand All @@ -34,17 +38,18 @@ def test_encode_abi_as_list_of_types(tuple_type, python_value, _1, encoded_list_
# abi.encode(arr,num);
separated_list_of_types = [t.to_type_str() for t in abi_type.components]
eth_abi_encoded = encode_abi(separated_list_of_types, python_value)
assert eth_abi_encoded == encoded_list_of_types

assert eth_abi_encoded == solidity_abi_encoded


@pytest.mark.parametrize(
'tuple_type,python_value,is_dynamic,encoded_list_of_types,_2',
CORRECT_TUPLE_ENCODINGS,
'single_abi_type,python_value,solidity_abi_encoded,_',
CORRECT_STATIC_ENCODINGS,
)
def test_encode_abi_as_single_tuple_type(
tuple_type, python_value, is_dynamic, encoded_list_of_types, _2
def test_encode_abi_for_single_static_types(
single_abi_type, python_value, solidity_abi_encoded, _
):
# assert the tuple type is encoded correctly
# If single_abi_type is a tuple, assert the tuple type is encoded correctly
# e.g. encode_abi(['(bytes32[],uint256)'], [([b'a', b'b'], 22)])
#
# compare to solidity:
Expand All @@ -58,13 +63,24 @@ def test_encode_abi_as_single_tuple_type(
# uint256 num = 22;
#
# abi.encode(TupleExample(arr,num));
eth_abi_encoded = encode_abi([tuple_type], [python_value])
eth_abi_encoded = encode_abi([single_abi_type], [python_value])

encoded_tuple_type = (
# 32 bytes offset for dynamic tuple types
b''.join([words('20'), encoded_list_of_types]) if is_dynamic
assert eth_abi_encoded == solidity_abi_encoded

# no offset for static tuples so same encoding as if encoding a list of the types
else encoded_list_of_types

@pytest.mark.parametrize(
'single_abi_type,python_value,solidity_abi_encoded,_',
CORRECT_DYNAMIC_ENCODINGS,
)
def test_encode_abi_for_single_dynamic_types(
single_abi_type, python_value, solidity_abi_encoded, _
):
# Same test as the single static types test above but with dynamic types
eth_abi_encoded = encode_abi([single_abi_type], [python_value])

solidity_abi_encoded = (
# 32 bytes offset for dynamic types
b''.join([words('20'), solidity_abi_encoded])
)
assert eth_abi_encoded == encoded_tuple_type

assert eth_abi_encoded == solidity_abi_encoded
18 changes: 0 additions & 18 deletions tests/abi/test_encode_single.py

This file was deleted.

8 changes: 4 additions & 4 deletions tests/abi/test_is_encodable.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
tuple_strs_values,
)
from tests.common.unit import (
CORRECT_SINGLE_ENCODINGS,
CORRECT_ENCODINGS,
NOT_ENCODABLE,
)


@pytest.mark.parametrize(
'type_str,python_value,_1,_2,_3',
CORRECT_SINGLE_ENCODINGS,
'type_str,python_value,_1,_2',
CORRECT_ENCODINGS,
)
def test_is_encodable_returns_true(type_str, python_value, _1, _2, _3):
def test_is_encodable_returns_true(type_str, python_value, _1, _2):
assert is_encodable(type_str, python_value)


Expand Down
8 changes: 4 additions & 4 deletions tests/abi/test_is_encodable_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
is_encodable_type,
)
from tests.common.unit import (
CORRECT_SINGLE_ENCODINGS,
CORRECT_ENCODINGS,
)


@pytest.mark.parametrize(
'type_str,_python_value,_1,_2,_3',
CORRECT_SINGLE_ENCODINGS,
'type_str,_python_value,_1,_2',
CORRECT_ENCODINGS,
)
def test_is_encodable_type_returns_true(type_str, _python_value, _1, _2, _3):
def test_is_encodable_type_returns_true(type_str, _python_value, _1, _2):
assert is_encodable_type(type_str)


Expand Down
47 changes: 23 additions & 24 deletions tests/abi/test_reversibility_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

from eth_abi import (
decode_abi,
decode_single,
encode_abi,
encode_single,
)
from tests.common.strategies import (
multi_strs_values,
Expand All @@ -28,27 +26,28 @@ def test_multi_abi_reversibility(types_and_values):
decoded_values = decode_abi(types, encoded_values)
assert values == decoded_values

# TODO: Delete
# @settings(deadline=None)
# @given(single_strs_values)
# def test_single_abi_reversibility(type_and_value):
# """
# Tests round trip encoding and decoding for basic types and lists of basic
# types.
# """
# _type, value = type_and_value
# encoded_value = encode_single(_type, value)
# decoded_value = decode_single(_type, encoded_value)
# assert value == decoded_value

@settings(deadline=None)
@given(single_strs_values)
def test_single_abi_reversibility(type_and_value):
"""
Tests round trip encoding and decoding for basic types and lists of basic
types.
"""
_type, value = type_and_value
encoded_value = encode_single(_type, value)
decoded_value = decode_single(_type, encoded_value)
assert value == decoded_value


@settings(deadline=None)
@given(tuple_strs_values)
def test_single_abi_tuple_reversibility(type_and_value):
"""
Tests round trip encoding and decoding for tuple types.
"""
_type, value = type_and_value
encoded_value = encode_single(_type, value)
decoded_value = decode_single(_type, encoded_value)
assert value == decoded_value
# TODO: Delete
# @settings(deadline=None)
# @given(tuple_strs_values)
# def test_single_abi_tuple_reversibility(type_and_value):
# """
# Tests round trip encoding and decoding for tuple types.
# """
# _type, value = type_and_value
# encoded_value = encode_single(_type, value)
# decoded_value = decode_single(_type, encoded_value)
# assert value == decoded_value
26 changes: 12 additions & 14 deletions tests/abi/test_uint_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

from eth_abi import (
decode_abi,
decode_single,
encode_abi,
encode_single,
)
from tests.common.strategies import (
uint_strs,
Expand All @@ -28,15 +26,15 @@ def test_always_positive_multi(_type, value):
assert decoded_value[0] >= 0


@given(uint_strs, uint_values)
def test_always_positive_single(_type, value):
"""
Tests round trip encoding and decoding for basic types and lists of basic
types.
"""
assert value >= 0

encoded_value = encode_single(_type, value)
decoded_value = decode_single(_type, encoded_value)

assert decoded_value >= 0
# @given(uint_strs, uint_values)
# def test_always_positive_single(_type, value):
# """
# Tests round trip encoding and decoding for basic types and lists of basic
# types.
# """
# assert value >= 0
#
# encoded_value = encode_single(_type, value)
# decoded_value = decode_single(_type, encoded_value)
#
# assert decoded_value >= 0
Loading

0 comments on commit b037171

Please sign in to comment.