[Python-Dev] Example for PEP 343

Michael Chermside mcherm at mcherm.com
Wed May 18 18:12:13 CEST 2005


Phillip writes:
> >@do_template
> >def with_extra_precision(places=2):
> >     "Performs nested computation with extra digits of precision."
> >     decimal.getcontext().prec += 2
> >     yield None
> >     decimal.getcontext().prec -= 2
>
> Won't this do the wrong thing if something within the block alters
> the precision?

Depends on what behavior you want. I wrote it this way partly because
that's how the example in the manual was written, and partly because
I was thinking "if someone increased the precision by 3 within the
block, then we probably want to leave it increased by 3 on block
exit".

On careful re-consideration, I think it'd be better to require that
the block NOT make unbalanced changes to the precision... we
could verify it using an assert statement.

I avoided caching the context and restoring it, because I WANTED to
allow code in the block to make OTHER alterations to the context and
not clobber them after the block exits (eg: setting or clearing some
trap). It's debatable whether that was a good design choice... there's
a great deal of elegence to Guido's version used like this:

Guido:
>   do with_decimal_context() as ctx:
>       ctx.prec += 2
>       # change other settings
>       # algorithm goes here

However, all of these are minor details compared to the bug that
Raymond points out:

Raymond:
> The final "return +s" should be unindented.  It should
> be at the same level as the "do with_extra_precision()".  The purpose of
> the "+s" is to force the result to be rounded back to the *original*
> precision.

In effect, the "with_extra_precision" wrapper causes the calculations
to be done with higher precision, AND causes any variables set during
the block will retain their higher precision. (It's because context
controls OPERATIONS but changing context never affects individual
Decimal OBJECTS.) So I fear that the whole with_extra_precision()
idea is just likely to tempt people into introducing subtle bugs, and
it should probably be scrapped anyhow. Guido's approach to save-and-
restore context works fine.

-- Michael Chermside

(PS: Another reason that I avoided a basic save-and-restore is that we
have plenty of examples already of 'do' statements that save-and-restore,
I was trying to do something different. It's interesting that what I
tried may have turned out to be a poor idea.)



More information about the Python-Dev mailing list