Batu Lab NotesPractical developer guides

Use localcontext to isolate a temporary Decimal precision change

By Batu · English technical notes

Also published in our primary archive.

Python can use localcontext() to isolate a temporary Decimal precision change: enter the context, set ctx.prec, and perform the calculation there. Changing getcontext().prec directly changes the active context, so later calculations in that thread observe the new precision unless code restores it.

The fixture begins with outer precision 4 and keeps the operands as a two-item list. The failing transformation directly assigns precision 8, so 1 / 7 becomes 0.14285714 and the setting still reads 8 afterward. The example restores precision 4 solely to make the correction’s starting state explicit. Its corrected calculation uses with localcontext() as ctx: and sets precision 4 inside the temporary context. It produces 0.1429; after the block, the outer precision is still 4.

This is an isolation mechanism for Decimal context state, not an immutability guarantee for every input object or a substitute for choosing an appropriate precision. The outer context is thread-local, and other Decimal settings such as rounding and traps can also be adjusted in the copied local context when needed. The assertions verify the values and context precision in this self-contained execution. localcontext and getcontext are standard-library APIs available in Python 3.4 and later.

The decimal.localcontext documentation describes the temporary copy and restoration behavior, and the getcontext documentation describes access to the current context.

AI assistance disclosure: This article was prepared with AI assistance and checked with the shown synthetic example.

from decimal import Decimal, getcontext, localcontext

operands = [Decimal(1), Decimal(7)]
outer = getcontext()
outer.prec = 4

outer.prec = 8
leaked_result = operands[0] / operands[1]
leaked_precision = outer.prec

outer.prec = 4
with localcontext() as ctx:
    ctx.prec = 4
    isolated_result = operands[0] / operands[1]
outer_precision_after = outer.prec

assert operands == [Decimal(1), Decimal(7)]
assert (str(leaked_result), leaked_precision) == ("0.14285714", 8)
assert (str(isolated_result), outer_precision_after) == ("0.1429", 4)

print("input:", [str(value) for value in operands])
print("global change:", leaked_result, "precision", leaked_precision)
print("localcontext:", isolated_result, "outer precision", outer_precision_after)
input: ['1', '7']
global change: 0.14285714 precision 8
localcontext: 0.1429 outer precision 4