Skip to content

Commit

Permalink
feat: handle commas and underscores in currency string conversions (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Jul 9, 2024
1 parent c172e9d commit 1e726ab
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/ape_ethereum/_converters.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import re
from decimal import Decimal

from ape.api.convert import ConverterAPI
Expand All @@ -18,6 +19,7 @@
"babbage": int(1e3),
"wei": 1,
}
NUMBER_PATTERN = re.compile(r"^-?\d{1,3}(?:[,_]?\d{3})*(?:\.\d+)?(?:[eE][+-]?\d+)?$")


class WeiConversions(ConverterAPI):
Expand All @@ -30,11 +32,12 @@ def is_convertible(self, value: str) -> bool:
if " " not in value or len(value.split(" ")) > 2:
return False

_, unit = value.split(" ")

return unit.lower() in ETHER_UNITS
val, unit = value.split(" ")
return unit.lower() in ETHER_UNITS and bool(NUMBER_PATTERN.match(val))

def convert(self, value: str) -> int:
value, unit = value.split(" ")
converted_value = int(Decimal(value) * ETHER_UNITS[unit.lower()])
converted_value = int(
Decimal(value.replace("_", "").replace(",", "")) * ETHER_UNITS[unit.lower()]
)
return CurrencyValue(converted_value)
14 changes: 14 additions & 0 deletions tests/functional/conversion/test_ether.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from ape.exceptions import ConversionError
from ape_ethereum._converters import ETHER_UNITS

TEN_THOUSAND_ETHER_IN_WEI = 10_000_000_000_000_000_000_000


@pytest.mark.fuzzing
@given(
Expand Down Expand Up @@ -41,3 +43,15 @@ def test_no_registered_converter(convert):
convert("something", ChecksumAddress)

assert str(err.value) == "No conversion registered to handle 'something'."


@pytest.mark.parametrize("sep", (",", "_"))
def test_separaters(convert, sep):
"""
Show that separates, such as commands and underscores, are OK
in currency-string values, e.g. "10,000 ETH" is valid.
"""
currency_str = f"10{sep}000 ETHER"
actual = convert(currency_str, int)
expected = TEN_THOUSAND_ETHER_IN_WEI
assert actual == expected

0 comments on commit 1e726ab

Please sign in to comment.