PyMoneyed
PyMoneyed provides robust Currency and Money classes for handling monetary values in Python. It is currently at version 3.0 and has a release cadence tied to significant feature additions and Python version support changes, ensuring compatibility and modern practices.
Warnings
- breaking Python 3.6 is no longer supported with version 3.0. Previous versions (2.x) also dropped support for Python 2.7, 3.5, and PyPy 2.
- breaking The `moneyed.localization` module has been removed. Its functionality for locale-aware formatting is superseded by the `moneyed.l10n` module, which leverages Babel for CLDR-based formatting.
- breaking Instantiating a `Money` object without providing a currency (e.g., `Money(100)`) now raises a `TypeError`. Previously, this would silently create an object with a made-up 'XYZ' currency.
- gotcha It is strongly recommended to avoid using Python's `float` type for the `amount` when instantiating `Money` objects, as floats do not convert losslessly to `Decimal` internally. This can lead to unexpected precision errors.
- deprecated The `Currency.countries` property is deprecated in version 3.0, as currency country data is now sourced from Babel. `Currency.country_codes` has been added.
- deprecated Setting and reading the `decimal_places_display` property on `Money` instances and using the `CURRENCY_DECIMAL_PLACES_DISPLAY` setting were deprecated in version 2.0.
Install
-
pip install py-moneyed
Imports
- Money
from moneyed import Money
- Currency (pre-built)
from moneyed import USD
- format_money
from moneyed.l10n import format_money
- list_all_currencies
from moneyed import list_all_currencies
Quickstart
from moneyed import Money, USD, EUR
from decimal import Decimal
# Instantiate Money with Decimal or string for precision
price_usd = Money(amount='99.99', currency=USD)
price_eur = Money(Decimal('75.50'), EUR)
print(f"USD Price: {price_usd}")
print(f"EUR Price: {price_eur}")
# Arithmetic operations (currency-aware)
total_price = price_usd + Money('10.01', USD)
print(f"Total USD: {total_price}")
# Invalid operations raise TypeError
try:
invalid_sum = price_usd + price_eur
except TypeError as e:
print(f"Error: {e}")
# Access components
print(f"Amount: {total_price.amount}, Currency Code: {total_price.currency.code}")
# Get amount in sub-units (e.g., cents for USD)
print(f"USD Price in cents: {price_usd.get_amount_in_sub_unit()}")