Skip to content

Commit aea4c6b

Browse files
authored
Merge pull request #1 from seba3c/alpha-2
Alpha 2
2 parents dbb9736 + ae40647 commit aea4c6b

13 files changed

Lines changed: 135 additions & 100 deletions

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
.idea/
2-
__pycache__/
2+
**/__pycache__/**
33
.coverage
44
.DS_Store

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "cryptils"
7-
version = "0.1.0a1"
7+
version = "0.1.0a2"
88
description = "A simple python utility library for representing cryptocurrency amounts"
99
readme = "README.md"
1010
license = {text = "MIT"}

src/cryptils/_core.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,48 @@
44
from decimal import Decimal
55
from typing import Any, ClassVar, TypeAlias
66

7-
_number_or_str: TypeAlias = Decimal | int | float | str
7+
_arithmetic_comparison_compatible: TypeAlias = Decimal | int | float
8+
_instance_compatible: TypeAlias = _arithmetic_comparison_compatible | str
89

910

1011
class CryptoAmount(metaclass=ABCMeta): # noqa: B024
1112
_name: ClassVar[str] = ""
12-
_symbol: ClassVar[str] = ""
13+
_code: ClassVar[str] = ""
1314
_decimals: ClassVar[int] = 0
1415

1516
@property
1617
def name(self) -> str:
1718
return self._name
1819

1920
@property
20-
def symbol(self) -> str:
21-
return self._symbol
21+
def code(self) -> str:
22+
return self._code
2223

23-
def __init__(self, value: _number_or_str) -> None:
24+
def __init__(self, value: _instance_compatible) -> None:
2425
if type(self) is CryptoAmount:
2526
raise TypeError("CryptoAmount is an abstract class and cannot be instantiated directly")
26-
self._value = self._to_decimal(value)
27+
if type(value) is self.__class__:
28+
self._value = self._to_decimal(value.as_decimal())
29+
else:
30+
self._value = self._to_decimal(value)
2731

28-
def _to_decimal(self, value: _number_or_str) -> Decimal:
32+
def _to_decimal(self, value: _arithmetic_comparison_compatible) -> Decimal:
2933
return Decimal(value).quantize(Decimal(10) ** -self._decimals)
3034

3135
def as_decimal(self) -> Decimal:
3236
return self._value
3337

3438
def to_string(self):
35-
return f"{self._value:.{self._decimals}f} {self._symbol}"
39+
return f"{self._value:.{self._decimals}f} {self._code}"
3640

3741
def __str__(self) -> str:
3842
return str(self._value)
3943

4044
def __repr__(self) -> str:
41-
return f"{self.__class__.__name__}({self.to_string()})"
45+
return f"{self.__class__.__name__}({self.as_decimal()})"
4246

4347
def _is_compatible(self, other: Any) -> bool:
44-
return isinstance(other, _number_or_str)
48+
return isinstance(other, _arithmetic_comparison_compatible)
4549

4650
def _compare(self, other: Any) -> Decimal:
4751
if isinstance(other, self.__class__):

src/cryptils/btc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55

66
class BTC(CryptoAmount):
77
_name = "Bitcoin"
8-
_symbol = "BTC"
8+
_code = "BTC"
99
_decimals = 8

src/cryptils/eth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55

66
class ETH(CryptoAmount):
77
_name = "Ethereum"
8-
_symbol = "ETH"
8+
_code = "ETH"
99
_decimals = 18

src/cryptils/usdc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55

66
class USDC(CryptoAmount):
77
_name = "USD Coin"
8-
_symbol = "USDC"
8+
_code = "USDC"
99
_decimals = 6

src/cryptils/usdt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55

66
class USDT(CryptoAmount):
77
_name = "Tether"
8-
_symbol = "USDT"
8+
_code = "USDT"
99
_decimals = 6
-140 Bytes
Binary file not shown.
-34.2 KB
Binary file not shown.

tests/test_btc.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@
66

77

88
def test_btc_name():
9-
assert BTC._name == "Bitcoin"
9+
assert BTC(0).name == "Bitcoin"
1010

1111

12-
def test_btc_symbol():
13-
assert BTC._symbol == "BTC"
12+
def test_btc_code():
13+
assert BTC(0).code == "BTC"
14+
15+
16+
def test_btc_new_instance():
17+
assert BTC("1.5") == BTC(1.5)
18+
assert BTC("1") == BTC(1)
19+
assert BTC("1.5") == BTC(Decimal("1.5"))
1420

1521

1622
def test_btc_precision():
@@ -27,7 +33,7 @@ def test_btc_str():
2733

2834

2935
def test_btc_repr():
30-
assert repr(BTC("1.5")) == "BTC(1.50000000 BTC)"
36+
assert repr(BTC("1.5")) == "BTC(1.50000000)"
3137

3238

3339
def test_btc_hash():
@@ -62,7 +68,8 @@ def test_btc_addition_with_float():
6268

6369

6470
def test_btc_addition_with_str():
65-
assert BTC("0.5") + "0.5" == BTC("1.0")
71+
with pytest.raises(TypeError):
72+
assert BTC("0.5") + "0.5"
6673

6774

6875
def test_btc_reverse_addition_with_int():
@@ -85,8 +92,9 @@ def test_btc_subtraction_with_float():
8592
assert BTC("1.5") - 0.5 == BTC("1.0")
8693

8794

88-
def test_btc_subtraction_with_str():
89-
assert BTC("1.5") - "0.5" == BTC("1.0")
95+
def test_btc_subtraction_with_str_raises():
96+
with pytest.raises(TypeError):
97+
BTC("1.5") - "0.5"
9098

9199

92100
def test_btc_reverse_subtraction_with_int():
@@ -105,8 +113,9 @@ def test_btc_multiplication_with_float():
105113
assert BTC("1") * 2.0 == BTC("2")
106114

107115

108-
def test_btc_multiplication_with_str():
109-
assert BTC("1") * "2" == BTC("2")
116+
def test_btc_multiplication_with_str_raises():
117+
with pytest.raises(TypeError):
118+
assert BTC("1") * "2"
110119

111120

112121
def test_btc_reverse_multiplication_with_int():
@@ -130,8 +139,9 @@ def test_btc_division_with_float():
130139
assert BTC("2") / 2.0 == BTC("1")
131140

132141

133-
def test_btc_division_with_str():
134-
assert BTC("2") / "2" == BTC("1")
142+
def test_btc_division_with_str_raises():
143+
with pytest.raises(TypeError):
144+
assert BTC("2") / "2"
135145

136146

137147
def test_btc_reverse_division_with_int():
@@ -159,8 +169,7 @@ def test_btc_equality_with_float():
159169

160170

161171
def test_btc_equality_with_str():
162-
assert BTC("1.5") == "1.5"
163-
assert (BTC("1.5") == "2.5") is False
172+
assert (BTC("1.5") == "1.5") is False
164173

165174

166175
def test_btc_equality_with_same_class():
@@ -193,9 +202,9 @@ def test_btc_less_than_with_float():
193202
assert not BTC("1") < 1.0
194203

195204

196-
def test_btc_less_than_with_str():
197-
assert BTC("1") < "2"
198-
assert not BTC("1") < "1"
205+
def test_btc_less_than_with_str_raises():
206+
with pytest.raises(TypeError):
207+
assert BTC("1") < "2"
199208

200209

201210
def test_btc_less_than_with_same_class():
@@ -224,9 +233,9 @@ def test_btc_greater_than_with_float():
224233
assert not BTC("1") > 1.0
225234

226235

227-
def test_btc_greater_than_with_str():
228-
assert BTC("2") > "1"
229-
assert not BTC("1") > "1"
236+
def test_btc_greater_than_with_str_raises():
237+
with pytest.raises(TypeError):
238+
assert BTC("2") > "1"
230239

231240

232241
def test_btc_greater_than_with_same_class():
@@ -244,7 +253,6 @@ def test_btc_comparison_with_zero():
244253
assert BTC("0") == 0
245254
assert BTC("0") == Decimal("0")
246255
assert BTC("0") == 0.0
247-
assert BTC("0") == "0"
248256
assert BTC("0") == BTC("0")
249257
assert BTC("1") > 0
250258
assert BTC("-1") < 0
@@ -306,7 +314,6 @@ def test_btc_comparison_with_negative():
306314
assert BTC("-1") == -1
307315
assert BTC("-1.5") == Decimal("-1.5")
308316
assert BTC("-1.5") == -1.5
309-
assert BTC("-1.5") == "-1.5"
310317
assert BTC("-1.5") == BTC("-1.5")
311318
assert BTC("-1") < 0
312319
assert BTC("-1") < BTC("0")

0 commit comments

Comments
 (0)