Skip to main content

Dinero

Precise, Type-Safe Monetary Calculations in Python

PyPI Build Status CodeQL Status Codecov License

Dinero is a modern Python library that brings precision and type safety to monetary calculations. Built on Python's Decimal type, it provides an intuitive API for financial operations while ensuring accuracy and maintainability.

📚 Read the Full Documentation

Key Features

  • 🎯 Precise Calculations: Built on Python's Decimal type for exact monetary computations
  • 🔒 Type Safety: Full type hint support and runtime validation
  • 🌍 Currency Support: Over 100 currencies following ISO 4217 standards
  • 🧮 Financial Tools: Built-in support for VAT, interest calculations, markup, and more
  • 🔄 Immutable Objects: Thread-safe with predictable behavior
  • 💪 Modern Python: Type hints, clean API, and comprehensive test coverage

Why Dinero?

Working with money in Python can be tricky due to floating-point arithmetic:

>>> 2.32 * 3 == 6.96
False
>>> 2.32 * 3
6.959999999999999  # Not ideal for financial calculations!

Dinero makes it simple and safe:

>>> from dinero import Dinero
>>> from dinero.currencies import USD
>>>
>>> price = Dinero("2.32", USD)  # Use strings for maximum precision
>>> total = price * 3
>>> print(total.format(symbol=True))  # "$6.96"
>>> total == Dinero("6.96", USD)
True

Quick Start

Installation

pip install dinero

Basic Usage

  1. Create and Format Money:
from dinero import Dinero
from dinero.currencies import USD, EUR

# Create monetary values
price = Dinero("99.99", USD)
discount = Dinero("10.00", USD)

# Format output
print(price.format(symbol=True, currency=True))  # "$99.99 USD"
  1. Perform Currency-Safe Calculations:
# Basic arithmetic
total = price - discount  # Dinero("89.99", USD)

# Safe currency handling
euro_price = Dinero("89.99", EUR)
try:
    total = price + euro_price  # Raises DifferentCurrencyError
except DifferentCurrencyError:
    print("Cannot add different currencies!")
  1. Use Financial Tools:
from dinero.tools import calculate_vat_portion, calculate_compound_interest

# Calculate VAT
vat = calculate_vat_portion(price, 20)  # 20% VAT
print(vat.format(symbol=True))  # "$20.00"

# Calculate compound interest
investment = Dinero("10000", USD)
future_value = calculate_compound_interest(
    principal=investment,
    interest_rate=5,  # 5% annual rate
    duration=10,      # 10 years
    compound_frequency=12  # Monthly compounding
)
  1. Compare Monetary Values:
from dinero.currencies import USD

price1 = Dinero("99.99", USD)
price2 = Dinero("89.99", USD)

# Using comparison operators
price1 > price2    # True - first price is higher

# Using methods for more explicit code
price1.eq(price2)  # False - prices are not equal
price2.lt(price1)  # True - price2 is less than price1
  1. Convert Between Currencies:
from dinero.currencies import USD, EUR, JPY

# Convert $100 USD to Euros with exchange rate 0.85
usd_price = Dinero("100.00", USD)
eur_price = usd_price.convert("0.85", EUR)
eur_price.format(symbol=True)  # "€85.00"

# Convert to Japanese Yen
jpy_price = usd_price.convert("110.50", JPY)
jpy_price.format(symbol=True, currency=True)  # "¥11,050 JPY"

Features

Type-Safe Currency Operations

# Arithmetic operations
total = price + shipping
monthly = rent * 12
unit_cost = total_cost / quantity

# Method chaining for complex calculations
final_price = (
    Dinero("100.00", USD)
    .multiply(1.20)  # Add 20% markup
    .subtract("5.00")  # Apply discount
)

Comparison Operators

# Direct comparison operators
price1 < price2            # Less than -> returns True/False
price1 <= price2           # Less than or equal -> returns True/False
price1 > price2            # Greater than -> returns True/False
price1 >= price2           # Greater than or equal -> returns True/False
price1 == price2           # Equal -> returns True/False

# Method-based comparisons
price1.lt(price2)   # Less than -> returns True/False
price1.lte(price2)  # Less than or equal -> returns True/False
price1.gt(price2)   # Greater than -> returns True/False
price1.gte(price2)  # Greater than or equal -> returns True/False
price1.eq(price2)   # Equal -> returns True/False

Currency Conversion

from dinero.currencies import USD, EUR, CLP

# Convert USD to EUR with an exchange rate of 0.85
usd_amount = Dinero("100", USD)
eur_amount = usd_amount.convert("0.85", EUR)
eur_amount.format(symbol=True)  # "€85.00"

# Convert USD to CLP (which has 0 decimal places)
clp_amount = usd_amount.convert(750, CLP)
clp_amount.format(currency=True)  # "75,000 CLP"

# Function-based conversion
from dinero.tools.conversion import convert
jpy_amount = convert(usd_amount, "110.25", JPY)
jpy_amount.format()  # "11,050"

Currency Support

  • Access over 100 pre-defined ISO 4217 currencies:
from dinero.currencies import USD, EUR, GBP, JPY, BTC

# Each currency knows its symbol and decimal places
amount = Dinero("42.42", EUR)
print(amount.format(symbol=True))  # "€42.42"
  • Create custom currencies:
from dinero.types import Currency

GOLD = {
    "code": "XAU",
    "base": 10,
    "exponent": 4,  # 4 decimal places
    "symbol": "Au"
}

gold_price = Dinero("1842.5930", GOLD)
print(gold_price.format(symbol=True))  # "Au1,842.5930"

Best Practices

  1. Use String Inputs: Avoid float precision issues by using strings:
# Good ✅
amount = Dinero("42.42", USD)

# Avoid ❌
amount = Dinero(42.42, USD)  # Potential precision loss
  1. Handle Currency Mismatches: Always validate currency compatibility:
# Good ✅
try:
    total = usd_price + eur_price
except DifferentCurrencyError:
    # Convert currencies or handle error
  1. Format for Display: Use appropriate formatting options:
# Full format with symbol and code
price.format(symbol=True, currency=True)  # "$42.42 USD"

# Just the number
price.format()  # "42.42"

For more detailed information and advanced features, check out our comprehensive documentation.

Metadata

Release files for dinero 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dinero 0.4.0
File Size Uploaded
dinero-0.4.0.tar.gz 20.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dinero 0.4.0
File Interpreter ABI Platform
dinero-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 73.7 kB

Release files / dinero-0.4.0.tar.gz

Download URL dinero-0.4.0.tar.gz
Size 20.8 kB
Tags Source
SHA-256 checksum
How to use checksums
87b55cc17dd5a9a2acf7bd044d460c769f869100e3d5a286a7a94c065af84125
BLAKE2b-256 checksum
How to use checksums
6956d5b5a2fd33c844be8c3a42ab42f95fb51a6297486966599fa25abc79776e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.0.0 CPython/3.13.3 Darwin/24.4.0

Release files / dinero-0.4.0-py3-none-any.whl

Download URL dinero-0.4.0-py3-none-any.whl
Size 52.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
19f66e4fa7b1c7b9419bb1d942cf0a06c12c1f38b444b21cec510f5a9408c387
BLAKE2b-256 checksum
How to use checksums
f90ecca2c39fb429d465a1ea54038d6449a61ddd818d6b9886691b1aa184ba94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.0.0 CPython/3.13.3 Darwin/24.4.0

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page