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.0.tar.gz (39.4 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.0-py3-none-any.whl (4.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: always_decimal-1.0.0.tar.gz
  • Upload date:
  • Size: 39.4 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.0.tar.gz
Algorithm Hash digest
SHA256 637dd11f3d14c9009f40df400ef98961618ec6b7c9ae0da65f60e8395daeb918
MD5 f3f30648f15e27a2ed58b73182f1b1de
BLAKE2b-256 5083d8ab2b1e151f1d0a86b3afe2c7eb760087e9421c67cf4c4340c69e2e6a58

See more details on using hashes here.

Provenance

The following attestation bundles were made for always_decimal-1.0.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: always_decimal-1.0.0-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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6726d95e68f15f2c47d522433ae518f26a06fd4e97eece4657118a9a1d81b434
MD5 4bf3cb18cfc84e24d682ff319b52afe1
BLAKE2b-256 838c954ad5b851a1b460771f24d94739d8c1ce41b200e7417173f9b613626084

See more details on using hashes here.

Provenance

The following attestation bundles were made for always_decimal-1.0.0-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