python/nondist/sandbox/decimal Decimal.py, 1.24, 1.25 test_Decimal.py, 1.19, 1.20

Update of /cvsroot/python/python/nondist/sandbox/decimal In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10586 Modified Files: Decimal.py test_Decimal.py Log Message: Prepare Decimal to move into the core. * With agreement from the principal contributors, removed the BSD license and added a PSF copyright. * Remove version history. CVS will track that now. * Add a todo list. * Made Decimal() == Decimal("0"). * Added pickle support for Decimal objects. * Copy and deepcopy now return self (as all good immutables do). * Run doctest on the docstrings. * Group the test suites together so their results can be aggregated. * Replaced variable names that shadowed imports or builtins (this excludes "divmod" which seemed to be the variable name). Index: Decimal.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/decimal/Decimal.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** Decimal.py 25 Jun 2004 17:46:20 -0000 1.24 --- Decimal.py 29 Jun 2004 10:08:35 -0000 1.25 *************** *** 1,7 **** ! # Class Decimal, version 0.7.1 ! # Written by Eric Price <eprice@tjhsst.edu> ! # and Facundo Batista <facundo@taniquetil.com.ar> ! # Based on code written by Aahz (aahz@pobox.com) ! # Currently under BSD-style license (copyright 2003) """ This is a stab at a decimal arithmetic module based on the decimal --- 1,19 ---- ! # Copyright (c) 2004 Python Software Foundation. ! # All rights reserved. ! ! # Written by Eric Price <eprice at tjhsst.edu> ! # and Facundo Batista <facundo at taniquetil.com.ar> ! # and Raymond Hettinger <python at rcn.com> ! # and Aahz (aahz at pobox.com) ! # and Tim Peters ! ! ! # Todo: ! # Add deepcopy and pickle support for contexts ! # Rename to decimal.Decimal before moving into production ! # Consider having a SimpleDecimal subclass implementing X3.274 semantics ! # Add an __all__ attribute ! # Improve docstrings and add more doctests ! """ This is a stab at a decimal arithmetic module based on the decimal *************** *** 95,132 **** """ ! # facundobatista: ! # 0.8.2 2004.06.24 Lot of small clean-ups from Raymond Hettinger. ! # 0.8.1 2004.06.23 Complies with immutability-near as discussed in c.l.py. ! # 0.8.0 2004.06.21 Using the updated Spec (and complies with new test cases) from ! # Cowlishaw. Deprecated trim and rescale. Changed __str__ and ! # __repr__ to return in sci format, added as_tuple(). Fixed the ! # initial examples. Extracted lt, gt and eq methods from context. ! # Added copy method to context. ! # 0.7.6 2004.06.20 More name changes. Extracted InsufficientStorage exception. ! # Added create_decimal to context. ! # 0.7.5 2004.06.19 Lots of name changes. ! # 0.7.4 2004.04.05 Added rdiv, rdivmod, rmod, rpow, rfloordiv special methods. ! # Fixed sub. ! # 0.7.3 2004.04.04 Added _convert_other method, for implicit constructions, ! # and more checks when constructing from tuples. Fixed ! # __sub__ to modify a copy of the instance. ! # 0.7.2 2004.04.02 Fixed __pow__ to run the example ok. Added from_float ! # method. Fixed isnan to accept empty strings. ! # 0.7.1 2004.03.08 Corrected initial examples ! ! # eprice: ! # 0.7.0 2003.2.28 More changes. Contexts done nicely, exponent limits ! # 0.6.0 2003.2.24 Many changes. No exponent limits ! ! # Aahz: ! # 0.0.8 2001.5.24 Fixed multiplication with trailing zeroes ! # 0.0.7 2001.5.23 Fixed string conversion to follow spec ! # 0.0.6 2001.5.20 Tim Peters's _floatToString() ! # 0.0.5 2001.5.20 Now with multiplication, round(), and conversions ! # 0.0.0 2001.5.18 First public release with just addition/subtraction ! ! # To-do list: ! # ! # Cleanup, hunt and kill bugs import threading --- 107,111 ---- """ ! # XXX Add an __all__ attribute import threading *************** *** 137,141 **** #Capitals: 1E+10, not 1e10 - CAPITALS = 1 --- 116,119 ---- *************** *** 401,404 **** --- 379,383 ---- return context + class Decimal(object): """Floating point class for decimal arithmetic.""" *************** *** 406,410 **** __slots__ = ('_exp','_int','_sign') ! def __init__(self, value, context = None): """Initialize the Decimal class. --- 385,389 ---- __slots__ = ('_exp','_int','_sign') ! def __init__(self, value="0", context=None): """Initialize the Decimal class. *************** *** 420,423 **** --- 399,403 ---- if context is None: context = getcontext() + # String? # REs insist on real strings, so we can too. *************** *** 448,451 **** --- 428,432 ---- return + ### XXX Hmm, with precision=3, Decimal(12345) fails with Decimal('12345') works if isinstance(value, (int,long)): # checking that the int or long doesn't exceed precision *************** *** 1795,1810 **** return ans ! copy = self._fix(context=context) ! if copy._isinfinity(): ! return copy ! if not copy: ! return Decimal( (copy._sign, (0,), 0) ) ! end = len(copy._int) ! exp = copy._exp ! while copy._int[end-1] == 0: exp += 1 end -= 1 ! return Decimal( (copy._sign, copy._int[:end], exp) ) --- 1776,1791 ---- return ans ! dup = self._fix(context=context) ! if dup._isinfinity(): ! return dup ! if not dup: ! return Decimal( (dup._sign, (0,), 0) ) ! end = len(dup._int) ! exp = dup._exp ! while dup._int[end-1] == 0: exp += 1 end -= 1 ! return Decimal( (dup._sign, dup._int[:end], exp) ) *************** *** 2110,2113 **** --- 2091,2104 ---- exp = property(_get_exp) + # support for pickling, copy, and deepcopy + def __reduce__(self): + return (self.__class__, (str(self),)) + + def __copy__(self): + return self # I'm immutable; therefore I am my own clone + + def __deepcopy__(self, memo): + return self # My components are also immutable + # get rounding method function: *************** *** 2202,2205 **** --- 2193,2197 ---- """Returns Etiny (= Emin - prec + 1)""" return long(self.Emin - self.prec + 1) + def Etop(self): """Returns maximum exponent (= Emin - prec + 1)""" *************** *** 2375,2379 **** curspot -= 1 ! def subtract(self, list): """Subtract a list from the current int (in place). --- 2367,2371 ---- curspot -= 1 ! def subtract(self, alist): """Subtract a list from the current int (in place). *************** *** 2384,2392 **** self.int.reverse() ! list.reverse() carry = 0 ! for x in xrange(len(list)): ! self.int[x] -= list[x] + carry if self.int[x] < 0: carry = 1 --- 2376,2384 ---- self.int.reverse() ! alist.reverse() carry = 0 ! for x in xrange(len(alist)): ! self.int[x] -= alist[x] + carry if self.int[x] < 0: carry = 1 *************** *** 2403,2407 **** self.int[last+1:]=[] self.int.reverse() ! list.reverse() return --- 2395,2399 ---- self.int[last+1:]=[] self.int.reverse() ! alist.reverse() return *************** *** 2753,2755 **** return "%s%se%d" % (sign, str(top), e) - --- 2745,2746 ---- Index: test_Decimal.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/decimal/test_Decimal.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_Decimal.py 25 Jun 2004 01:30:49 -0000 1.19 --- test_Decimal.py 29 Jun 2004 10:08:35 -0000 1.20 *************** *** 1,5 **** ! # Test Cases for Decimal module, version 0.1.1 ! # Written by Eric Price <eprice@tjhsst.edu> ! # and Facundo Batista <facundo@taniquetil.com.ar> """ These are the test cases for the Decimal module. --- 1,11 ---- ! # Copyright (c) 2004 Python Software Foundation. ! # All rights reserved. ! ! # Written by Eric Price <eprice at tjhsst.edu> ! # and Facundo Batista <facundo at taniquetil.com.ar> ! # and Raymond Hettinger <python at rcn.com> ! # and Aahz (aahz at pobox.com) ! # and Tim Peters ! """ These are the test cases for the Decimal module. *************** *** 15,43 **** """ - # 0.2.1 2004.06.23 fb: Added immutability test for operations. - # 0.2.0 2004.06.21 fb: Using the new test cases from Cowlishaw. Deprecated trim - # test case and use of result in inexact test case. Added - # as_tuple() test case. - # 0.1.9 2004.06.20 fb: More fixes because of the name changes. Added test case for - # context.create_decimal(). - # 0.1.8 2004.06.19 fb: Adjusted threading test case. Taken out the immutability - # test. Added tearDown method to DecimalTest class. Some fixes - # because of the name changes. - # 0.1.7 2004.04.05 fb: Adjusted several test cases. Eliminated interaction - # with float in comparations and min/max test cases. - # 0.1.6 2004.04.04 fb: Extended explicit construction test case from tuples. - # 0.1.5 2004.04.02 fb: Adjusted explicit construction test cases. - # 0.1.4 2004.03.28 fb: Added Use of Context and Decimal Usability test cases. - # Corrected tests using try/except/else. - # 0.1.3 2004.03.23 fb: Added arithmetic operators test and corrected minor - # method case issues. - # 0.1.2 2004.03.20 fb: Added from_float to explicit construction test cases - # and all implicit construction test cases. Also upgraded - # method names to new GvR definiton. - # 0.1.1 2004.03.11 fb: Added Explicit Construction tests - # 0.1.0 2004.03.11 fb: Placed the structure to run separate test groups - # - # fb = facundobatista - from __future__ import division --- 21,24 ---- *************** *** 45,51 **** import glob import os, sys from Decimal import * ! from test.test_support import TestSkipped, run_unittest --- 26,33 ---- import glob import os, sys + import pickle, copy from Decimal import * ! from test.test_support import TestSkipped, run_unittest, run_doctest *************** *** 90,94 **** # Name adapter to be able to change the Decimal and Context ! # interface without changing the test files from Cowlishaw nameAdapter = {'toeng':'to_eng_string', 'tosci':'to_sci_string', --- 72,76 ---- # Name adapter to be able to change the Decimal and Context ! # interface without changing the test files from Cowlishaw nameAdapter = {'toeng':'to_eng_string', 'tosci':'to_sci_string', *************** *** 144,148 **** #Exception raised where there shoudn't have been one. self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line) ! return --- 126,130 ---- #Exception raised where there shoudn't have been one. self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line) ! return *************** *** 200,204 **** fname = nameAdapter.get(funct, funct) if fname == 'rescale': ! return funct = getattr(self.context, fname) vals = [] --- 182,186 ---- fname = nameAdapter.get(funct, funct) if fname == 'rescale': ! return funct = getattr(self.context, fname) vals = [] *************** *** 234,238 **** else: self.fail("Did not raise %s in %s" % (error, s)) ! self.context.trap_enablers[error] = 0 v = self.context.create_decimal(v) else: --- 216,220 ---- else: self.fail("Did not raise %s in %s" % (error, s)) ! self.context.trap_enablers[error] = 0 v = self.context.create_decimal(v) else: *************** *** 241,245 **** ans = FixQuotes(ans) ! if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'): for error in theirexceptions: --- 223,227 ---- ans = FixQuotes(ans) ! if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'): for error in theirexceptions: *************** *** 254,258 **** else: self.fail("Did not raise %s in %s" % (error, s)) ! self.context.trap_enablers[error] = 0 try: result = str(funct(*vals)) --- 236,240 ---- else: self.fail("Did not raise %s in %s" % (error, s)) ! self.context.trap_enablers[error] = 0 try: result = str(funct(*vals)) *************** *** 490,494 **** def test_empty(self): '''Explicit construction without parameters.''' ! self.assertRaises(TypeError, Decimal) def test_from_None(self): --- 472,476 ---- def test_empty(self): '''Explicit construction without parameters.''' ! self.assertEqual(Decimal(), Decimal("0")) def test_from_None(self): *************** *** 510,514 **** d = Decimal(-45) self.assertEqual(str(d), '-45') ! #zero d = Decimal(0) --- 492,496 ---- d = Decimal(-45) self.assertEqual(str(d), '-45') ! #zero d = Decimal(0) *************** *** 525,529 **** d = Decimal('45') self.assertEqual(str(d), '45') ! #float d = Decimal('45.34') --- 507,511 ---- d = Decimal('45') self.assertEqual(str(d), '45') ! #float d = Decimal('45.34') *************** *** 548,552 **** d = Decimal.from_float(-32.0) self.assertEqual(str(d), '-32') ! #zero d = Decimal.from_float(0.0) --- 530,534 ---- d = Decimal.from_float(-32.0) self.assertEqual(str(d), '-32') ! #zero d = Decimal.from_float(0.0) *************** *** 565,573 **** d = Decimal.from_float(2.2) self.assertEqual(str(d), '2.20000000000000017763568394002504646778106689453125') ! #inexact float, rounded to some positions d = Decimal.from_float(2.2, 16) self.assertEqual(str(d), '2.2000000000000002') ! #inexact float, rounded to less positions d = Decimal.from_float(2.2, 5) --- 547,555 ---- d = Decimal.from_float(2.2) self.assertEqual(str(d), '2.20000000000000017763568394002504646778106689453125') ! #inexact float, rounded to some positions d = Decimal.from_float(2.2, 16) self.assertEqual(str(d), '2.2000000000000002') ! #inexact float, rounded to less positions d = Decimal.from_float(2.2, 5) *************** *** 584,588 **** d = Decimal( (1, (4, 5), 0) ) self.assertEqual(str(d), '-45') ! #float d = Decimal( (0, (4, 5, 3, 4), -2) ) --- 566,570 ---- d = Decimal( (1, (4, 5), 0) ) self.assertEqual(str(d), '-45') ! #float d = Decimal( (0, (4, 5, 3, 4), -2) ) *************** *** 626,630 **** self.assertEqual(str(e), '-45') self.assertNotEqual(id(d), id(e)) ! #zero d = Decimal(0) --- 608,612 ---- self.assertEqual(str(e), '-45') self.assertNotEqual(id(d), id(e)) ! #zero d = Decimal(0) *************** *** 688,692 **** else: self.fail('Did not raised an error!') ! def test_from_int(self): '''Implicit construction with int or long.''' --- 670,674 ---- else: self.fail('Did not raised an error!') ! def test_from_int(self): '''Implicit construction with int or long.''' *************** *** 704,708 **** else: self.fail('Did not raised an error!') ! def test_from_string(self): '''Implicit construction with string.''' --- 686,690 ---- else: self.fail('Did not raised an error!') ! def test_from_string(self): '''Implicit construction with string.''' *************** *** 1010,1014 **** def test_threading(self): '''Test the "threading isolation" of a Context.''' ! self.synchro = threading.Event() self.finish1 = threading.Event() --- 992,996 ---- def test_threading(self): '''Test the "threading isolation" of a Context.''' ! self.synchro = threading.Event() self.finish1 = threading.Event() *************** *** 1073,1088 **** '''Test copy and deepcopy.''' - import copy d = Decimal('43.24') - - #copy c = copy.copy(d) ! self.assertEqual(c, d) ! self.assertNotEqual(id(c), id(d)) ! ! #deepcopy dc = copy.deepcopy(d) ! self.assertEqual(dc, d) ! self.assertNotEqual(id(dc), id(d)) def test_hash_method(self): --- 1055,1063 ---- '''Test copy and deepcopy.''' d = Decimal('43.24') c = copy.copy(d) ! self.assertEqual(id(c), id(d)) dc = copy.deepcopy(d) ! self.assertEqual(id(dc), id(d)) def test_hash_method(self): *************** *** 1123,1127 **** #as true self.failUnless(Decimal('0.372')) ! def test_tostring_methods(self): '''Test str and repr methods.''' --- 1098,1102 ---- #as true self.failUnless(Decimal('0.372')) ! def test_tostring_methods(self): '''Test str and repr methods.''' *************** *** 1134,1138 **** #repr self.assertEqual(repr(d), 'Decimal("15.32")') ! def test_tonum_methods(self): '''Test float, int and long methods.''' --- 1109,1113 ---- #repr self.assertEqual(repr(d), 'Decimal("15.32")') ! def test_tonum_methods(self): '''Test float, int and long methods.''' *************** *** 1163,1167 **** d = Decimal( (1, (4, 5), 0) ) self.assertEqual(d, eval(repr(d))) ! #float d = Decimal( (0, (4, 5, 3, 4), -2) ) --- 1138,1142 ---- d = Decimal( (1, (4, 5), 0) ) self.assertEqual(d, eval(repr(d))) ! #float d = Decimal( (0, (4, 5, 3, 4), -2) ) *************** *** 1182,1186 **** d = Decimal(-45) self.assertEqual(d.as_tuple(), (1, (4, 5), 0) ) ! #complicated string d = Decimal("-4.34913534E-17") --- 1157,1161 ---- d = Decimal(-45) self.assertEqual(d.as_tuple(), (1, (4, 5), 0) ) ! #complicated string d = Decimal("-4.34913534E-17") *************** *** 1247,1251 **** self.assertEqual(d1._int, b1._int) self.assertEqual(d1._exp, b1._exp) ! checkSameDec("__abs__") checkSameDec("__add__", True) --- 1222,1226 ---- self.assertEqual(d1._int, b1._int) self.assertEqual(d1._exp, b1._exp) ! checkSameDec("__abs__") checkSameDec("__add__", True) *************** *** 1289,1295 **** checkSameDec("to_integral") ! def test_main(which=None): """ Execute the tests. --- 1264,1276 ---- checkSameDec("to_integral") + class DecimalPythonAPItests(unittest.TestCase): + def test_pickle(self): + d = Decimal('-3.141590000') + p = pickle.dumps(d) + e = pickle.loads(p) + self.assertEqual(d, e) ! def test_main(which=None, verbose=None): """ Execute the tests. *************** *** 1298,1312 **** Otherwise, executes both of them. """ if which == "Arithmetic" or which is None: ! run_unittest(DecimalTest) if which == "Behaviour" or which is None: ! run_unittest(DecimalExplicitConstructionTest) ! run_unittest(DecimalImplicitConstructionTest) ! run_unittest(DecimalArithmeticOperatorsTest) ! run_unittest(DecimalUseOfContextTest) ! run_unittest(DecimalUsabilityTest) ! return --- 1279,1300 ---- Otherwise, executes both of them. """ + test_classes = [] if which == "Arithmetic" or which is None: ! test_classes.extend([DecimalTest]) if which == "Behaviour" or which is None: ! test_classes.extend([ ! DecimalExplicitConstructionTest, ! DecimalImplicitConstructionTest, ! DecimalArithmeticOperatorsTest, ! DecimalUseOfContextTest, ! DecimalUsabilityTest, ! DecimalPythonAPItests, ! ]) ! ! run_unittest(*test_classes) ! import Decimal as DecimalModule ! run_doctest(DecimalModule, verbose) return *************** *** 1314,1320 **** if __name__ == '__main__': if len(sys.argv) == 1: ! test_main() elif len(sys.argv) == 2: ! test_main(sys.argv[1]) else: raise ValueError, "test called with wrong arguments, use test_Decimal [Arithmetic|Behaviour]" --- 1302,1308 ---- if __name__ == '__main__': if len(sys.argv) == 1: ! test_main(verbose=True) elif len(sys.argv) == 2: ! test_main(sys.argv[1], verbose=True) else: raise ValueError, "test called with wrong arguments, use test_Decimal [Arithmetic|Behaviour]"
participants (1)
-
rhettingerīŧ users.sourceforge.net