Python decimal custom context

The context manager decimal.localcontext apparently is ignored when used inside another context. The following example illustrates this (Python 2.7):

from decimal import Decimal, Context, localcontext
from contextlib import contextmanager

@contextmanager
def precision_context(precision):
    yield localcontext(Context(prec=precision))

PRECISION=4
SMALL_NUMBER=Decimal('0.0001')

with localcontext(Context(prec=PRECISION)):
    # This is working as it should
    print SMALL_NUMBER + 1 # prints 1.000

with precision_context(PRECISION):
    # But this is not
    print SMALL_NUMBER + 1 # prints 1.0001

Why this happens, and how to solve it?

Upvotes: 3

Views: 961

Answers (1)

vaultah
vaultah

Reputation: 46573

This happens because you don't actually enter the context manager (invoke the __enter__ method). Nothing calls localcontext(Context(prec=precision)).__enter__ because

with precision_context(PRECISION):

only enters the precision_context context manager.

You can solve the problem by adding another with statement:

with precision_context(PRECISION) as ctx:
    # Enter `localcontext(Context(prec=precision))`
    with ctx:
        print(SMALL_NUMBER + 1) # prints 1.000

Upvotes: 4

Related Questions