Skip to main content

Coerce floats/strings/Decimals to Decimal with predictable scale and rounding.

Project description

always-decimal

A tiny Python package to safely convert floats, strings, and numbers into Decimal objects.
It solves common headaches when comparing PostgreSQL numeric values with Python floats by ensuring consistent Decimal values.


✨ Features

  • 🔒 Exact conversion from floatDecimal (no hidden rounding).
  • ⚖️ Configurable coercion: set scale, rounding mode, normalize trailing zeros.
  • 🧩 Works with float, int, str, or Decimal.
  • 🛡️ Raises clear DecimalCoercionError on invalid inputs.
  • 🐍 Compatible with Python 3.10+.
  • 📦 Easy install via uv or pip.

📦 Installation

Using uv (recommended)

uv add always-decimal

Using pip

pip install always-decimal

For local development:

uv pip install -e ".[dev]"
# or
pip install -e ".[dev]"

🚀 Usage

from always_decimal import ensure_decimal, to_decimal_exact

# 1. Exact conversion: no rounding, no scale changes
d1 = to_decimal_exact(0.1)
print(d1)
# Decimal('0.1000000000000000055511151231257827021181583404541015625')

# 2. Safe coercion with fixed scale
price = ensure_decimal(19.995, scale=2)
print(price)
# Decimal('20.00')  (ROUND_HALF_EVEN default)

# 3. String input with quantization
val = ensure_decimal("1.2345", scale=3)
print(val)
# Decimal('1.235')

# 4. Normalizing (remove trailing zeros)
norm = ensure_decimal("1.2300", scale=4, normalize=True)
print(norm)
# Decimal('1.23')

⚙️ API

to_decimal_exact(value: float | Decimal) -> Decimal

Convert a float or Decimal to a Decimal exactly:

  • floatDecimal.from_float(value)
  • Decimal → returned as-is Raises TypeError for other types.

ensure_decimal(value, *, scale=None, rounding=ROUND_HALF_EVEN, clamp_exp=True, normalize=False) -> Decimal

Convert and coerce input to Decimal.

  • scale: number of fractional digits to quantize (e.g., 2 → cents).
  • rounding: rounding mode (default: bankers rounding).
  • clamp_exp: clamp exponents to context limits.
  • normalize: trim trailing zeros.

🧪 Running Tests

make test

or directly:

pytest

📄 License

MIT


🙌 Contributing

Issues and PRs are welcome! Please format with ruff, type-check with mypy, and run pytest before submitting.

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

always_decimal-1.0.1.tar.gz (39.3 kB view details)

Uploaded Source

Built Distribution

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

always_decimal-1.0.1-py3-none-any.whl (4.8 kB view details)

Uploaded Python 3

File details

Details for the file always_decimal-1.0.1.tar.gz.

File metadata

  • Download URL: always_decimal-1.0.1.tar.gz
  • Upload date:
  • Size: 39.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for always_decimal-1.0.1.tar.gz
Algorithm Hash digest
SHA256 850eaafc53b02cc2c98359e9fdd6753b18e15b91f4f7cac6b59f76ca88d1cf62
MD5 e6426629bd892e51511189b6f548f31d
BLAKE2b-256 dca81a8a5ecb05cdbb6d13562f7a21a80d7c92ae4fb14cc8892dc3491e5828eb

See more details on using hashes here.

Provenance

The following attestation bundles were made for always_decimal-1.0.1.tar.gz:

Publisher: ci-publish.yml on vib795/always-decimal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file always_decimal-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: always_decimal-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 4.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for always_decimal-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bf606e7ba2dba22dbe82381d3a0ded9041328580b9adc3d7ceff22c18202a42a
MD5 767116f0e7f29797e981cbf7d0be06e9
BLAKE2b-256 673665fcb697d0d6898486529fe0409a92f33e1279cfad35a2b392fb5f97a26d

See more details on using hashes here.

Provenance

The following attestation bundles were made for always_decimal-1.0.1-py3-none-any.whl:

Publisher: ci-publish.yml on vib795/always-decimal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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