On Friday 11 July 2008 09:36:22 Oleg Broytmann wrote:
>    size is not used in the __init__().

I don't think size is very important for python Decimals (only for storage 
engines).  In working with decimals, the problem is always with precision, 
rounding, strict equality, and so forth.  Maybe I am just short-sighted?

It would not be difficult to strictly validate size, if desired.

>    ? Without str() the query is
>
> INSERT INTO test (d) VALUES (10.0000)
>
>    but converting to floats is exactly what we want to prevent. With str()
> the query is
>
> INSERT INTO test (d) VALUES ('10.0000')

Of course you are correct.  I apologize for the careless error.

How about this:
====
class DecimalStringValidator(DecimalValidator):
    def __init__(self, *args, **kw):
        precision = kw.pop('precision', NoDefault)
        assert precision >= 0, \
                "You must give a precision argument as a positive integer"
        self.precision = Decimal('10') ** (-1 * int(precision))
        size = kw.pop('size', NoDefault)
        assert size >= precision, \
                "Precision argument can't be larger than size"
        self.max = Decimal('10') ** (int(size) - int(precision))
        super(DecimalStringValidator, self).__init__(*args, **kw)

    def to_python(self, value, state):
        value = super(DecimalStringValidator, self).to_python(value, state)
        if isinstance(value, Decimal):
            value = value.quantize(self.precision)
        assert value < self.max, \
            "Value must be less than %s" % int(self.max)
        return value

    def from_python(self, value, state):
        value = super(DecimalStringValidator, self).from_python(value, state)
        if isinstance(value, Decimal):
            value = value.quantize(self.precision)
        assert value < self.max, \
            "Value must be less than %s" % int(self.max)
        return str(value)

class SODecimalStringCol(SOStringCol):
    def __init__(self, **kw):
        self.size = kw.pop('size', NoDefault)
        assert self.size >= 0, \
               "You must give a size argument as a positive integer"
        self.precision = kw.pop('precision', NoDefault)
        assert self.precision >= 0, \
               "You must give a precision argument as a positive integer"
        kw['length'] = int(self.size) + int(self.precision)
        self.quantize = kw.pop('quantize', False)
        assert isinstance(self.quantize, bool), \
                "quantize argument must be Boolean True/False"
        super(SODecimalStringCol, self).__init__(**kw)

    def createValidators(self):
        validators = super(SODecimalStringCol, self).createValidators()
        if self.quantize:
            validators.insert(0, DecimalStringValidator(size=self.size, 
precision=self.precision))

class DecimalStringCol(StringCol):
    baseClass = SODecimalStringCol

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss

Reply via email to