Skip to main content

Dinero is a library for working with monetary values in Python.

Project description

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dinero-0.4.0.tar.gz (20.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dinero-0.4.0-py3-none-any.whl (52.9 kB view details)

Uploaded Python 3

File details

Details for the file dinero-0.4.0.tar.gz.

File metadata

  • Download URL: dinero-0.4.0.tar.gz
  • Upload date:
  • Size: 20.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.0 CPython/3.13.3 Darwin/24.4.0

File hashes

Hashes for dinero-0.4.0.tar.gz
Algorithm Hash digest
SHA256 87b55cc17dd5a9a2acf7bd044d460c769f869100e3d5a286a7a94c065af84125
MD5 6c7a18cc5172a712af73b5dd7eff0055
BLAKE2b-256 6956d5b5a2fd33c844be8c3a42ab42f95fb51a6297486966599fa25abc79776e

See more details on using hashes here.

File details

Details for the file dinero-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: dinero-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 52.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.0 CPython/3.13.3 Darwin/24.4.0

File hashes

Hashes for dinero-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 19f66e4fa7b1c7b9419bb1d942cf0a06c12c1f38b444b21cec510f5a9408c387
MD5 8c1d56bd05ff9a1acca1958b1318e7af
BLAKE2b-256 f90ecca2c39fb429d465a1ea54038d6449a61ddd818d6b9886691b1aa184ba94

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page