def test_exceptions() -> None: for trap_float_operation in (True, False): with localcontext() as ctx: ctx.traps[FloatOperation] = trap_float_operation err_msg = "invalid satoshi amount: " with pytest.raises(BTClibValueError, match=err_msg): btc_from_sats(2_099_999_997_690_001) err_msg = "invalid BTC amount: " with pytest.raises(BTClibValueError, match=err_msg): sats_from_btc(Decimal("20_999_999.97690001")) err_msg = "too many decimals for a BTC amount: " with pytest.raises(BTClibValueError, match=err_msg): sats_from_btc(Decimal("0.123456789")) # too many decimales, now with a float with pytest.raises(BTClibValueError, match=err_msg): valid_btc_amount(0.123456789) with pytest.raises(TypeError): btc_from_sats(2.5) # type: ignore with pytest.raises(TypeError): btc_from_sats(5 / 2) # type: ignore with pytest.raises(ValueError): btc_from_sats("2.5") # type: ignore err_msg = "non-integer satoshi amount: " with pytest.raises(BTClibTypeError, match=err_msg): btc_from_sats(Decimal("2.5")) # type: ignore
def from_dict(cls: Type["TxOut"], dict_: Mapping[str, Any], check_validity: bool = True) -> "TxOut": value = sats_from_btc(dict_["value"]) script_bin = dict_["scriptPubKey"] network = dict_.get("network", "mainnet") return cls(value, ScriptPubKey(script_bin, network), check_validity)
def test_self_consistency() -> None: for trap_float_operation in (True, False): with localcontext() as ctx: ctx.traps[FloatOperation] = trap_float_operation # 8.50390625 = 2177 / pow(2, 8) # 8.50390625 * 100_000_000 is 850390625.0 # 8.50492428 * 100_000_000 is 850492427.9999999 btc_amounts = [0, 1, 8.50390625, 8.50492428] cases: List[Union[int, float, str, Decimal]] = [] for num in btc_amounts: cases += [num, float(num), str(num), f"{num:.7E}", Decimal(str(num))] for btc_amount in cases: exp_btc = Decimal(str(btc_amount)).normalize() btc = btc_from_sats(sats_from_btc(btc_amount)) # type: ignore assert btc == exp_btc assert str(btc) == str(exp_btc)