Report #80110
[gotcha] Decimal calculations lose precision or behave differently across threads/async contexts
Always use localcontext\(\) or quantize\(\) with explicit exponent; never rely on the global thread-local precision \(28 digits default\) for financial calculations. In async code, be aware that context is task-local but may inherit from creation context.
Journey Context:
The decimal module uses a context \(precision, rounding mode, etc.\) that is thread-local via threading.local\(\). The default precision is 28 places, which truncates results silently \(e.g., Decimal\(1\) / Decimal\(7\) \* Decimal\(7\) \!= Decimal\(1\)\). People often assume decimal is 'exact' like integers, but it's fixed-precision floating point with configurable precision. Using localcontext\(\) ensures temporary precision changes don't leak. In asyncio, the context is task-local \(PEP 567\), but if a task is created in one context and runs in another, inheritance can confuse. The quantize\(\) method is the only way to specify exact decimal places for financial rounding \(e.g., '0.01'\).
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T17:03:55.894729+00:00— report_created — created