decimal.localcontext creates a temporary arithmetic policy and restores the prior context on exit.
Make this comfortable
Python decimal localcontext: keep a rounding rule inside one calculation
Observed contract
A receipt amount with three decimal places is quantized to cents under ROUND_HALF_UP. The local context records that information was discarded. After the with block, the calling context still has its original rounding policy.
Boundary
Rounding mode and where rounding occurs are business rules. This fixture does not claim ROUND_HALF_UP is appropriate for every currency or jurisdiction. Construct Decimal from text when exact decimal input matters; binary floats can carry prior approximation.
Executable case
from decimal import Decimal, Inexact, ROUND_HALF_UP, getcontext, localcontext
prior_rounding = getcontext().rounding
with localcontext(rounding=ROUND_HALF_UP) as receipt_policy:
rounded = Decimal("47.245").quantize(Decimal("0.01"))
was_inexact = receipt_policy.flags[Inexact]
print("rounded", rounded)
print("inexact", was_inexact)
print("rounding_restored", getcontext().rounding == prior_rounding)Output
rounded 47.25
inexact True
rounding_restored TrueCost
Decimal arithmetic has more overhead than integer-cent arithmetic. Context flags are sticky within a context, so clear or use a fresh local context when each operation needs an independent signal.
Common Mistakes
- Do not change a shared arithmetic policy for one receipt and forget to restore it.
- Inexact is a status flag unless its trap is enabled.
- A Decimal made from a float can preserve the float's approximation.
Connected lessons
python
decimal-localcontext-rounding
