{"id":5385,"library":"py-money","title":"py-money","description":"py-money is a Python 3 library that provides `Money` and `Currency` classes for precise monetary calculations. It enforces correct decimal places for currencies, leverages Python's `Decimal` type to prevent floating-point errors, and supports basic arithmetic and logical operations for immutable money objects. The current version is 0.5.0, with releases historically focused on bug fixes and minor feature enhancements.","status":"active","version":"0.5.0","language":"en","source_language":"en","source_url":"https://github.com/vimeo/py-money","tags":["money","currency","financial","decimal","accounting","iso4217"],"install":[{"cmd":"pip install py-money","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Used for locale-aware formatting of monetary amounts, though not a strict installation dependency. Version 0.4.0 expanded allowed Babel versions.","package":"Babel","optional":true}],"imports":[{"note":"The primary Money class resides within the 'money.money' module path, not directly under the top-level 'py_money' package name.","wrong":"from py_money import Money","symbol":"Money","correct":"from money.money import Money"},{"note":"The Currency class is found within the 'money.currency' module path, not directly under the top-level 'py_money' package name.","wrong":"from py_money import Currency","symbol":"Currency","correct":"from money.currency import Currency"},{"note":"Pre-defined ISO 4217 currencies like USD are available from `money.currency`, not `money.money`.","wrong":"from money.money import USD","symbol":"USD","correct":"from money.currency import USD"}],"quickstart":{"code":"from money.money import Money\nfrom money.currency import USD, EUR\n\n# Create Money objects\nprice_usd = Money('100.50', USD)\nprice_eur = Money('50.25', EUR)\n\n# Accessing amount and currency\nprint(f\"USD Price: {price_usd.amount} {price_usd.currency.code}\") # Expected: USD Price: 100.50 USD\n\n# Basic arithmetic (same currency)\ntotal_usd = price_usd + Money('9.50', USD)\nprint(f\"Total USD: {total_usd}\") # Expected: Total USD: 110.00 USD\n\n# Subtraction\nremaining_usd = price_usd - Money('20.00', USD)\nprint(f\"Remaining USD: {remaining_usd}\") # Expected: Remaining USD: 80.50 USD\n\n# Multiplication\ntaxed_price = price_usd * 1.05\nprint(f\"Taxed USD: {taxed_price}\") # Expected: Taxed USD: 105.53 USD (due to rounding)\n\n# Division\nsplit_price = price_usd / 2\nprint(f\"Split USD: {split_price}\") # Expected: Split USD: 50.25 USD\n\n# Create from subunits (v0.3.0+)\n# e.g., 12345 cents for USD\nsub_unit_money = Money.from_sub_units(12345, USD)\nprint(f\"From subunits USD: {sub_unit_money}\") # Expected: From subunits USD: 123.45 USD\nprint(f\"To subunits USD: {sub_unit_money.sub_units}\") # Expected: To subunits USD: 12345","lang":"python","description":"This quickstart demonstrates how to create `Money` objects, perform basic arithmetic operations, and work with currency subunits. It highlights the importance of using the correct import paths and shows how to access the amount and currency code."},"warnings":[{"fix":"Manually convert amounts to a common currency before performing operations, or ensure all operations are between `Money` objects of the same currency.","message":"Direct currency conversion between different `Money` objects is explicitly not supported by design. Attempting to add or subtract `Money` objects of different currencies will raise an error.","severity":"breaking","affected_versions":"All versions"},{"fix":"Initialize `Money` objects with `Money('100.50', USD)` or `Money(Decimal('100.50'), USD)` instead of `Money(100.50, USD)`.","message":"Instantiating `Money` with floating-point numbers can lead to precision issues. Always use strings or `Decimal` objects for monetary amounts to guarantee accuracy.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure monetary amounts conform to the standard decimal places for their respective currencies (e.g., 2 for USD, 0 for JPY) before creating `Money` objects.","message":"The library enforces the correct number of decimal places for each currency. Providing an amount with too many decimal places (e.g., '3.678 USD') will raise an error.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Be mindful of the order of operations and simplify expressions where intermediate rounding might be problematic. For critical financial calculations, evaluate if this rounding behavior meets specific accounting requirements.","message":"Rounding is performed after *each* multiplication or division operation. This can lead to different results compared to calculating with higher precision and rounding only at the end of a series of operations.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your `babel` dependency, if used for formatting, is within the compatible range, or upgrade `py-money` to `0.4.0` or newer.","message":"Older versions of `babel` might have caused compatibility issues. Version `0.4.0` was released to allow `py-money` to work with a broader range of `babel` versions (`>= 2.4.0` and `< 3.0`).","severity":"deprecated","affected_versions":"<0.4.0"},{"fix":"Upgrade to `py-money` v0.3.0 or later to utilize the `Money.from_sub_units()` method and the `.sub_units` property.","message":"Prior to v0.3.0, there was no direct support for creating `Money` objects from or converting to currency subunits. This functionality was introduced in v0.3.0.","severity":"gotcha","affected_versions":"<0.3.0"}],"env_vars":null,"last_verified":"2026-04-13T00:00:00.000Z","next_check":"2026-07-12T00:00:00.000Z"}