This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add precision property to decimal.Decimal
Type: Stage:
Components: Library (Lib) Versions: Python 3.0, Python 2.4, Python 3.1, Python 2.7, Python 2.6, Python 2.5
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: dlesco, rhettinger
Priority: normal Keywords:

Created on 2009-03-08 20:23 by dlesco, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (3)
msg83328 - (view) Author: Daniel Lescohier (dlesco) Date: 2009-03-08 20:23
I would like to get the decimal precision of decimal.Decimal objects 
(for my application, in order to validate whether a Decimal value will 
fit in the defined decimal precision of a database field). The way I 
found to get it was with:

precision = len(value._int)

where value is a decimal.Decimal object.

However, this uses a private API (_int). I would like to have a public 
API to get the decimal precision of a Decimal.  I propose we add the 
following to the decimal.Decimal class:

    @property
    def precision(self):
        """The precision of this Decimal value."""
        return len(self._int)

decimal.Context has a precision for calculations. 
decimal.Decimal.precision is the minimum precision needed to represent 
that value, not the precision that was used in calculating it.  If one 
wants to, one can actually use Decimal.precision to set your Context's 
precision:

d1 = decimal.Decimal('999')
d2 = d1
context.prec = d1.precision + d2.precision
d3 = d1 * d2

Open for debate is whether to name it Decimal.prec to mirror 
Context.prec.  We'd have to choose one or the other or both:

    @property
    def precision(self):
        """The precision of this Decimal value."""
        return len(self._int)
    prec = precision
msg83369 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-03-09 11:30
FWIW, there is a public API to get at the same information: 
Decimal.as_tuple().

That being said, I don't see how your len(value._int) test could be
correct.  The exponent will potentially shift the value way
out-of-bounds for a database.  Consider Decimal('999E+10') or
Decimal('999E-10') whose database storage sizes do not fit in a
DECIMAL(7,4) field eventhough their len(value._int) is three.


To see if the fractional part of a decimal number fits in a database,
set the context precision to the database precision and quantize the
decimal to the allowed number of decimal places.  If the Inexact flag
gets set, then it didn't fit.

-1 on extending the API any further from the underlying IBM specification.
msg83393 - (view) Author: Daniel Lescohier (dlesco) Date: 2009-03-09 16:13
I had other code to check scale, but you are right, I should use 
quantize. There is certainly a lot to absorb in the IBM decimal 
specification.  I really appreciate you pointing me to quantize and 
Inexact. I guess I inadvertently used the issue tracker for help on 
the decimal module, I didn't really mean to do that, I really thought 
there was a need for Decimal.precision. The other unrelated issue I 
entered (#5445) should be more of a real issue.

My code constructs a conversion/validation closure for every field in 
the Schema, based on a SchemaField definition for each field. My 
SchemaFieldDecimal class includes precision and scale parameters, and 
now I'm going to add a rounding parameter, with None meaning raise an 
error on Inexact.

So pseudo-code for the fix:

scale = None if scale is None else Decimal((0,(1,),-scale))
traps = (InvalidOperation, Inexact) if rounding is None else 
(InvalidOperation,)
context = Context(prec=precision, rounding=rounding, traps=traps)

doing the conversion/validation:

For case if scale is not None:

try:
    with context:
        value = Decimal(value).quantize(scale)
except handlers...

For case if scale is None:

try:
   with context:
       value = Decimal(value)+Decimal(0) # will round or raise Inexact
except handlers...
History
Date User Action Args
2022-04-11 14:56:46adminsetgithub: 49698
2009-03-09 16:13:41dlescosetmessages: + msg83393
2009-03-09 11:30:08rhettingersetstatus: open -> closed

nosy: + rhettinger
messages: + msg83369

resolution: rejected
2009-03-08 20:23:44dlescocreate