[Python-checkins] python/nondist/sandbox/decimal Decimal.py, 1.24, 1.25 test_Decimal.py, 1.19, 1.20

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Tue Jun 29 06:08:39 EDT 2004


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 at tjhsst.edu>
! # and Facundo Batista <facundo at taniquetil.com.ar>
! # Based on code written by Aahz (aahz at 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 at tjhsst.edu>
! # and Facundo Batista <facundo at 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]"


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /