blob: d0de64d311d006488c0211303ebc779d63c51950 [file] [log] [blame]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001# Copyright (c) 2004 Python Software Foundation.
2# All rights reserved.
3
4# Written by Eric Price <eprice at tjhsst.edu>
5# and Facundo Batista <facundo at taniquetil.com.ar>
6# and Raymond Hettinger <python at rcn.com>
7# and Aahz (aahz at pobox.com)
8# and Tim Peters
9
10"""
11These are the test cases for the Decimal module.
12
13There are two groups of tests, Arithmetic and Behaviour. The former test
14the Decimal arithmetic using the tests provided by Mike Cowlishaw. The latter
15test the pythonic behaviour according to PEP 327.
16
17Cowlishaw's tests can be downloaded from:
18
19 www2.hursley.ibm.com/decimal/dectest.zip
20
21This test module can be called from command line with one parameter (Arithmetic
22or Behaviour) to test each part, or without parameter to test both parts. If
23you're working through IDLE, you can import this test module and call test_main()
24with the corresponding argument.
25"""
26
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000027import glob
Christian Heimes400adb02008-02-01 08:12:03 +000028import math
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000029import os, sys
30import pickle, copy
Christian Heimes400adb02008-02-01 08:12:03 +000031import unittest
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000032from decimal import *
Benjamin Petersonee8712c2008-05-20 21:35:26 +000033from test.support import (TestSkipped, run_unittest, run_doctest,
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000034 is_resource_enabled)
Raymond Hettinger0aeac102004-07-05 22:53:03 +000035import random
Raymond Hettinger7e71fa52004-12-18 19:07:19 +000036try:
37 import threading
38except ImportError:
39 threading = None
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000040
Raymond Hettingerfed52962004-07-14 15:41:57 +000041# Useful Test Constant
Guido van Rossumc1f779c2007-07-03 08:25:58 +000042Signals = tuple(getcontext().flags.keys())
Raymond Hettingerfed52962004-07-14 15:41:57 +000043
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000044# Tests are built around these assumed context defaults.
45# test_main() restores the original context.
46def init():
47 global ORIGINAL_CONTEXT
48 ORIGINAL_CONTEXT = getcontext().copy()
Christian Heimes81ee3ef2008-05-04 22:42:01 +000049 DefaultTestContext = Context(
50 prec = 9,
51 rounding = ROUND_HALF_EVEN,
52 traps = dict.fromkeys(Signals, 0)
53 )
54 setcontext(DefaultTestContext)
Raymond Hettinger6ea48452004-07-03 12:26:21 +000055
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000056TESTDATADIR = 'decimaltestdata'
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +000057if __name__ == '__main__':
58 file = sys.argv[0]
59else:
60 file = __file__
61testdir = os.path.dirname(file) or os.curdir
Raymond Hettinger267b8682005-03-27 10:47:39 +000062directory = testdir + os.sep + TESTDATADIR + os.sep
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000063
Raymond Hettinger267b8682005-03-27 10:47:39 +000064skip_expected = not os.path.isdir(directory)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000065
66# Make sure it actually raises errors when not expected and caught in flags
67# Slower, since it runs some things several times.
68EXTENDEDERRORTEST = False
69
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000070#Map the test cases' error names to the actual errors
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000071ErrorNames = {'clamped' : Clamped,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000072 'conversion_syntax' : InvalidOperation,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000073 'division_by_zero' : DivisionByZero,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000074 'division_impossible' : InvalidOperation,
75 'division_undefined' : InvalidOperation,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000076 'inexact' : Inexact,
Raymond Hettinger5aa478b2004-07-09 10:02:53 +000077 'invalid_context' : InvalidOperation,
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000078 'invalid_operation' : InvalidOperation,
79 'overflow' : Overflow,
80 'rounded' : Rounded,
81 'subnormal' : Subnormal,
82 'underflow' : Underflow}
83
84
85def Nonfunction(*args):
86 """Doesn't do anything."""
87 return None
88
89RoundingDict = {'ceiling' : ROUND_CEILING, #Maps test-case names to roundings.
90 'down' : ROUND_DOWN,
91 'floor' : ROUND_FLOOR,
92 'half_down' : ROUND_HALF_DOWN,
93 'half_even' : ROUND_HALF_EVEN,
94 'half_up' : ROUND_HALF_UP,
Thomas Wouters1b7f8912007-09-19 03:06:30 +000095 'up' : ROUND_UP,
96 '05up' : ROUND_05UP}
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000097
98# Name adapter to be able to change the Decimal and Context
99# interface without changing the test files from Cowlishaw
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000100nameAdapter = {'and':'logical_and',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000101 'apply':'_apply',
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000102 'class':'number_class',
103 'comparesig':'compare_signal',
104 'comparetotal':'compare_total',
105 'comparetotmag':'compare_total_mag',
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000106 'copy':'copy_decimal',
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000107 'copyabs':'copy_abs',
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000108 'copynegate':'copy_negate',
109 'copysign':'copy_sign',
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000110 'divideint':'divide_int',
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000111 'invert':'logical_invert',
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000112 'iscanonical':'is_canonical',
113 'isfinite':'is_finite',
114 'isinfinite':'is_infinite',
115 'isnan':'is_nan',
116 'isnormal':'is_normal',
117 'isqnan':'is_qnan',
118 'issigned':'is_signed',
119 'issnan':'is_snan',
120 'issubnormal':'is_subnormal',
121 'iszero':'is_zero',
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000122 'maxmag':'max_mag',
123 'minmag':'min_mag',
124 'nextminus':'next_minus',
125 'nextplus':'next_plus',
126 'nexttoward':'next_toward',
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000127 'or':'logical_or',
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000128 'reduce':'normalize',
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000129 'remaindernear':'remainder_near',
130 'samequantum':'same_quantum',
131 'squareroot':'sqrt',
132 'toeng':'to_eng_string',
133 'tointegral':'to_integral_value',
134 'tointegralx':'to_integral_exact',
135 'tosci':'to_sci_string',
136 'xor':'logical_xor',
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000137 }
138
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000139# The following functions return True/False rather than a Decimal instance
140
141LOGICAL_FUNCTIONS = (
142 'is_canonical',
143 'is_finite',
144 'is_infinite',
145 'is_nan',
146 'is_normal',
147 'is_qnan',
148 'is_signed',
149 'is_snan',
150 'is_subnormal',
151 'is_zero',
152 'same_quantum',
153 )
154
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000155# For some operations (currently exp, ln, log10, power), the decNumber
156# reference implementation imposes additional restrictions on the
157# context and operands. These restrictions are not part of the
158# specification; however, the effect of these restrictions does show
159# up in some of the testcases. We skip testcases that violate these
160# restrictions, since Decimal behaves differently from decNumber for
161# these testcases so these testcases would otherwise fail.
162
163decNumberRestricted = ('power', 'ln', 'log10', 'exp')
164DEC_MAX_MATH = 999999
165def outside_decNumber_bounds(v, context):
166 if (context.prec > DEC_MAX_MATH or
167 context.Emax > DEC_MAX_MATH or
168 -context.Emin > DEC_MAX_MATH):
169 return True
170 if not v._is_special and v and (
171 len(v._int) > DEC_MAX_MATH or
172 v.adjusted() > DEC_MAX_MATH or
173 v.adjusted() < 1-2*DEC_MAX_MATH):
174 return True
175 return False
176
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000177class DecimalTest(unittest.TestCase):
178 """Class which tests the Decimal class against the test cases.
179
180 Changed for unittest.
181 """
182 def setUp(self):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000183 self.context = Context()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000184 self.ignore_list = ['#']
185 # Basically, a # means return NaN InvalidOperation.
186 # Different from a sNaN in trim
187
188 self.ChangeDict = {'precision' : self.change_precision,
189 'rounding' : self.change_rounding_method,
190 'maxexponent' : self.change_max_exponent,
191 'minexponent' : self.change_min_exponent,
192 'clamp' : self.change_clamp}
193
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000194 def eval_file(self, file):
195 global skip_expected
196 if skip_expected:
197 raise TestSkipped
198 return
Neal Norwitz70967602006-03-17 08:29:44 +0000199 for line in open(file):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000200 line = line.replace('\r\n', '').replace('\n', '')
Raymond Hettinger5aa478b2004-07-09 10:02:53 +0000201 #print line
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000202 try:
203 t = self.eval_line(line)
Guido van Rossumb940e112007-01-10 16:19:56 +0000204 except DecimalException as exception:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000205 #Exception raised where there shoudn't have been one.
206 self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line)
207
208 return
209
210 def eval_line(self, s):
211 if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith(' --'):
212 s = (s.split('->')[0] + '->' +
213 s.split('->')[1].split('--')[0]).strip()
214 else:
215 s = s.split('--')[0].strip()
216
217 for ignore in self.ignore_list:
218 if s.find(ignore) >= 0:
219 #print s.split()[0], 'NotImplemented--', ignore
220 return
221 if not s:
222 return
223 elif ':' in s:
224 return self.eval_directive(s)
225 else:
226 return self.eval_equation(s)
227
228 def eval_directive(self, s):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000229 funct, value = (x.strip().lower() for x in s.split(':'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000230 if funct == 'rounding':
231 value = RoundingDict[value]
232 else:
233 try:
234 value = int(value)
235 except ValueError:
236 pass
237
238 funct = self.ChangeDict.get(funct, Nonfunction)
239 funct(value)
240
241 def eval_equation(self, s):
242 #global DEFAULT_PRECISION
243 #print DEFAULT_PRECISION
Raymond Hettingered20ad82004-09-04 20:09:13 +0000244
245 if not TEST_ALL and random.random() < 0.90:
246 return
247
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000248 try:
249 Sides = s.split('->')
250 L = Sides[0].strip().split()
251 id = L[0]
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000252 if DEBUG:
253 print("Test ", id, end=" ")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000254 funct = L[1].lower()
255 valstemp = L[2:]
256 L = Sides[1].strip().split()
257 ans = L[0]
258 exceptions = L[1:]
259 except (TypeError, AttributeError, IndexError):
Raymond Hettingerd87ac8f2004-07-09 10:52:54 +0000260 raise InvalidOperation
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000261 def FixQuotes(val):
262 val = val.replace("''", 'SingleQuote').replace('""', 'DoubleQuote')
263 val = val.replace("'", '').replace('"', '')
264 val = val.replace('SingleQuote', "'").replace('DoubleQuote', '"')
265 return val
266 fname = nameAdapter.get(funct, funct)
267 if fname == 'rescale':
268 return
269 funct = getattr(self.context, fname)
270 vals = []
271 conglomerate = ''
272 quote = 0
273 theirexceptions = [ErrorNames[x.lower()] for x in exceptions]
274
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +0000275 for exception in Signals:
Raymond Hettingerbf440692004-07-10 14:14:37 +0000276 self.context.traps[exception] = 1 #Catch these bugs...
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000277 for exception in theirexceptions:
Raymond Hettingerbf440692004-07-10 14:14:37 +0000278 self.context.traps[exception] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000279 for i, val in enumerate(valstemp):
280 if val.count("'") % 2 == 1:
281 quote = 1 - quote
282 if quote:
283 conglomerate = conglomerate + ' ' + val
284 continue
285 else:
286 val = conglomerate + val
287 conglomerate = ''
288 v = FixQuotes(val)
289 if fname in ('to_sci_string', 'to_eng_string'):
290 if EXTENDEDERRORTEST:
291 for error in theirexceptions:
Raymond Hettingerbf440692004-07-10 14:14:37 +0000292 self.context.traps[error] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000293 try:
294 funct(self.context.create_decimal(v))
295 except error:
296 pass
Guido van Rossumb940e112007-01-10 16:19:56 +0000297 except Signals as e:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000298 self.fail("Raised %s in %s when %s disabled" % \
299 (e, s, error))
300 else:
301 self.fail("Did not raise %s in %s" % (error, s))
Raymond Hettingerbf440692004-07-10 14:14:37 +0000302 self.context.traps[error] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000303 v = self.context.create_decimal(v)
304 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000305 v = Decimal(v, self.context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000306 vals.append(v)
307
308 ans = FixQuotes(ans)
309
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000310 # skip tests that are related to bounds imposed in the decNumber
311 # reference implementation
312 if fname in decNumberRestricted:
313 if fname == 'power':
314 if not (vals[1]._isinteger() and
315 -1999999997 <= vals[1] <= 999999999):
316 if outside_decNumber_bounds(vals[0], self.context) or \
317 outside_decNumber_bounds(vals[1], self.context):
318 #print "Skipping test %s" % s
319 return
320 else:
321 if outside_decNumber_bounds(vals[0], self.context):
322 #print "Skipping test %s" % s
323 return
324
325
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000326 if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'):
327 for error in theirexceptions:
Raymond Hettingerbf440692004-07-10 14:14:37 +0000328 self.context.traps[error] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000329 try:
330 funct(*vals)
331 except error:
332 pass
Guido van Rossumb940e112007-01-10 16:19:56 +0000333 except Signals as e:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000334 self.fail("Raised %s in %s when %s disabled" % \
335 (e, s, error))
336 else:
337 self.fail("Did not raise %s in %s" % (error, s))
Raymond Hettingerbf440692004-07-10 14:14:37 +0000338 self.context.traps[error] = 0
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000339 if DEBUG:
340 print("--", self.context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000341 try:
342 result = str(funct(*vals))
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000343 if fname in LOGICAL_FUNCTIONS:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000344 result = str(int(eval(result))) # 'True', 'False' -> '1', '0'
Guido van Rossumb940e112007-01-10 16:19:56 +0000345 except Signals as error:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000346 self.fail("Raised %s in %s" % (error, s))
347 except: #Catch any error long enough to state the test case.
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000348 print("ERROR:", s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000349 raise
350
351 myexceptions = self.getexceptions()
Raymond Hettingerbf440692004-07-10 14:14:37 +0000352 self.context.clear_flags()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000353
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000354 myexceptions.sort(key=repr)
355 theirexceptions.sort(key=repr)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000356
357 self.assertEqual(result, ans,
358 'Incorrect answer for ' + s + ' -- got ' + result)
359 self.assertEqual(myexceptions, theirexceptions,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000360 'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000361 return
362
363 def getexceptions(self):
Raymond Hettingerf63ba432004-08-17 05:42:09 +0000364 return [e for e in Signals if self.context.flags[e]]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000365
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000366 def change_precision(self, prec):
367 self.context.prec = prec
368 def change_rounding_method(self, rounding):
369 self.context.rounding = rounding
370 def change_min_exponent(self, exp):
371 self.context.Emin = exp
372 def change_max_exponent(self, exp):
373 self.context.Emax = exp
374 def change_clamp(self, clamp):
375 self.context._clamp = clamp
376
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000377
378
379# The following classes test the behaviour of Decimal according to PEP 327
380
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000381class DecimalExplicitConstructionTest(unittest.TestCase):
382 '''Unit tests for Explicit Construction cases of Decimal.'''
383
384 def test_explicit_empty(self):
385 self.assertEqual(Decimal(), Decimal("0"))
386
387 def test_explicit_from_None(self):
388 self.assertRaises(TypeError, Decimal, None)
389
390 def test_explicit_from_int(self):
391
392 #positive
393 d = Decimal(45)
394 self.assertEqual(str(d), '45')
395
396 #very large positive
397 d = Decimal(500000123)
398 self.assertEqual(str(d), '500000123')
399
400 #negative
401 d = Decimal(-45)
402 self.assertEqual(str(d), '-45')
403
404 #zero
405 d = Decimal(0)
406 self.assertEqual(str(d), '0')
407
408 def test_explicit_from_string(self):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000409
410 #empty
411 self.assertEqual(str(Decimal('')), 'NaN')
412
413 #int
414 self.assertEqual(str(Decimal('45')), '45')
415
416 #float
417 self.assertEqual(str(Decimal('45.34')), '45.34')
418
419 #engineer notation
420 self.assertEqual(str(Decimal('45e2')), '4.5E+3')
421
422 #just not a number
423 self.assertEqual(str(Decimal('ugly')), 'NaN')
424
Christian Heimesa62da1d2008-01-12 19:39:10 +0000425 #leading and trailing whitespace permitted
426 self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
427 self.assertEqual(str(Decimal(' -7.89')), '-7.89')
428
Benjamin Peterson41181742008-07-02 20:22:54 +0000429 #but alternate unicode digits should not
430 self.assertEqual(str(Decimal('\uff11')), 'NaN')
431
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000432 def test_explicit_from_tuples(self):
433
434 #zero
435 d = Decimal( (0, (0,), 0) )
436 self.assertEqual(str(d), '0')
437
438 #int
439 d = Decimal( (1, (4, 5), 0) )
440 self.assertEqual(str(d), '-45')
441
442 #float
443 d = Decimal( (0, (4, 5, 3, 4), -2) )
444 self.assertEqual(str(d), '45.34')
445
446 #weird
447 d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
448 self.assertEqual(str(d), '-4.34913534E-17')
449
450 #wrong number of items
451 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1)) )
452
453 #bad sign
454 self.assertRaises(ValueError, Decimal, (8, (4, 3, 4, 9, 1), 2) )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000455 self.assertRaises(ValueError, Decimal, (0., (4, 3, 4, 9, 1), 2) )
456 self.assertRaises(ValueError, Decimal, (Decimal(1), (4, 3, 4, 9, 1), 2))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000457
458 #bad exp
459 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 'wrong!') )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000460 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 0.) )
461 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), '1') )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000462
463 #bad coefficients
464 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, None, 1), 2) )
465 self.assertRaises(ValueError, Decimal, (1, (4, -3, 4, 9, 1), 2) )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000466 self.assertRaises(ValueError, Decimal, (1, (4, 10, 4, 9, 1), 2) )
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +0000467 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 'a', 1), 2) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000468
469 def test_explicit_from_Decimal(self):
470
471 #positive
472 d = Decimal(45)
473 e = Decimal(d)
474 self.assertEqual(str(e), '45')
475 self.assertNotEqual(id(d), id(e))
476
477 #very large positive
478 d = Decimal(500000123)
479 e = Decimal(d)
480 self.assertEqual(str(e), '500000123')
481 self.assertNotEqual(id(d), id(e))
482
483 #negative
484 d = Decimal(-45)
485 e = Decimal(d)
486 self.assertEqual(str(e), '-45')
487 self.assertNotEqual(id(d), id(e))
488
489 #zero
490 d = Decimal(0)
491 e = Decimal(d)
492 self.assertEqual(str(e), '0')
493 self.assertNotEqual(id(d), id(e))
494
495 def test_explicit_context_create_decimal(self):
496
497 nc = copy.copy(getcontext())
498 nc.prec = 3
499
500 # empty
Raymond Hettingerfed52962004-07-14 15:41:57 +0000501 d = Decimal()
502 self.assertEqual(str(d), '0')
503 d = nc.create_decimal()
504 self.assertEqual(str(d), '0')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000505
506 # from None
507 self.assertRaises(TypeError, nc.create_decimal, None)
508
509 # from int
510 d = nc.create_decimal(456)
511 self.failUnless(isinstance(d, Decimal))
512 self.assertEqual(nc.create_decimal(45678),
513 nc.create_decimal('457E+2'))
514
515 # from string
516 d = Decimal('456789')
517 self.assertEqual(str(d), '456789')
518 d = nc.create_decimal('456789')
519 self.assertEqual(str(d), '4.57E+5')
Christian Heimesa62da1d2008-01-12 19:39:10 +0000520 # leading and trailing whitespace should result in a NaN;
521 # spaces are already checked in Cowlishaw's test-suite, so
522 # here we just check that a trailing newline results in a NaN
523 self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000524
525 # from tuples
526 d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
527 self.assertEqual(str(d), '-4.34913534E-17')
528 d = nc.create_decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
529 self.assertEqual(str(d), '-4.35E-17')
530
531 # from Decimal
532 prevdec = Decimal(500000123)
533 d = Decimal(prevdec)
534 self.assertEqual(str(d), '500000123')
535 d = nc.create_decimal(prevdec)
536 self.assertEqual(str(d), '5.00E+8')
537
538
539class DecimalImplicitConstructionTest(unittest.TestCase):
540 '''Unit tests for Implicit Construction cases of Decimal.'''
541
542 def test_implicit_from_None(self):
543 self.assertRaises(TypeError, eval, 'Decimal(5) + None', globals())
544
545 def test_implicit_from_int(self):
546 #normal
547 self.assertEqual(str(Decimal(5) + 45), '50')
548 #exceeding precision
549 self.assertEqual(Decimal(5) + 123456789000, Decimal(123456789000))
550
551 def test_implicit_from_string(self):
552 self.assertRaises(TypeError, eval, 'Decimal(5) + "3"', globals())
553
554 def test_implicit_from_float(self):
555 self.assertRaises(TypeError, eval, 'Decimal(5) + 2.2', globals())
556
557 def test_implicit_from_Decimal(self):
558 self.assertEqual(Decimal(5) + Decimal(45), Decimal(50))
559
Raymond Hettinger267b8682005-03-27 10:47:39 +0000560 def test_rop(self):
561 # Allow other classes to be trained to interact with Decimals
562 class E:
563 def __divmod__(self, other):
564 return 'divmod ' + str(other)
565 def __rdivmod__(self, other):
566 return str(other) + ' rdivmod'
567 def __lt__(self, other):
568 return 'lt ' + str(other)
569 def __gt__(self, other):
570 return 'gt ' + str(other)
571 def __le__(self, other):
572 return 'le ' + str(other)
573 def __ge__(self, other):
574 return 'ge ' + str(other)
575 def __eq__(self, other):
576 return 'eq ' + str(other)
577 def __ne__(self, other):
578 return 'ne ' + str(other)
579
580 self.assertEqual(divmod(E(), Decimal(10)), 'divmod 10')
581 self.assertEqual(divmod(Decimal(10), E()), '10 rdivmod')
582 self.assertEqual(eval('Decimal(10) < E()'), 'gt 10')
583 self.assertEqual(eval('Decimal(10) > E()'), 'lt 10')
584 self.assertEqual(eval('Decimal(10) <= E()'), 'ge 10')
585 self.assertEqual(eval('Decimal(10) >= E()'), 'le 10')
586 self.assertEqual(eval('Decimal(10) == E()'), 'eq 10')
587 self.assertEqual(eval('Decimal(10) != E()'), 'ne 10')
588
589 # insert operator methods and then exercise them
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000590 oplist = [
591 ('+', '__add__', '__radd__'),
592 ('-', '__sub__', '__rsub__'),
593 ('*', '__mul__', '__rmul__'),
Thomas Woutersdcc6d322006-04-21 11:30:52 +0000594 ('/', '__truediv__', '__rtruediv__'),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000595 ('%', '__mod__', '__rmod__'),
596 ('//', '__floordiv__', '__rfloordiv__'),
597 ('**', '__pow__', '__rpow__')
598 ]
Raymond Hettinger267b8682005-03-27 10:47:39 +0000599
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000600 for sym, lop, rop in oplist:
Raymond Hettinger267b8682005-03-27 10:47:39 +0000601 setattr(E, lop, lambda self, other: 'str' + lop + str(other))
602 setattr(E, rop, lambda self, other: str(other) + rop + 'str')
603 self.assertEqual(eval('E()' + sym + 'Decimal(10)'),
604 'str' + lop + '10')
605 self.assertEqual(eval('Decimal(10)' + sym + 'E()'),
606 '10' + rop + 'str')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000607
Christian Heimesf16baeb2008-02-29 14:57:44 +0000608class DecimalFormatTest(unittest.TestCase):
609 '''Unit tests for the format function.'''
610 def test_formatting(self):
611 # triples giving a format, a Decimal, and the expected result
612 test_values = [
613 ('e', '0E-15', '0e-15'),
614 ('e', '2.3E-15', '2.3e-15'),
615 ('e', '2.30E+2', '2.30e+2'), # preserve significant zeros
616 ('e', '2.30000E-15', '2.30000e-15'),
617 ('e', '1.23456789123456789e40', '1.23456789123456789e+40'),
618 ('e', '1.5', '1.5e+0'),
619 ('e', '0.15', '1.5e-1'),
620 ('e', '0.015', '1.5e-2'),
621 ('e', '0.0000000000015', '1.5e-12'),
622 ('e', '15.0', '1.50e+1'),
623 ('e', '-15', '-1.5e+1'),
624 ('e', '0', '0e+0'),
625 ('e', '0E1', '0e+1'),
626 ('e', '0.0', '0e-1'),
627 ('e', '0.00', '0e-2'),
628 ('.6e', '0E-15', '0.000000e-9'),
629 ('.6e', '0', '0.000000e+6'),
630 ('.6e', '9.999999', '9.999999e+0'),
631 ('.6e', '9.9999999', '1.000000e+1'),
632 ('.6e', '-1.23e5', '-1.230000e+5'),
633 ('.6e', '1.23456789e-3', '1.234568e-3'),
634 ('f', '0', '0'),
635 ('f', '0.0', '0.0'),
636 ('f', '0E-2', '0.00'),
637 ('f', '0.00E-8', '0.0000000000'),
638 ('f', '0E1', '0'), # loses exponent information
639 ('f', '3.2E1', '32'),
640 ('f', '3.2E2', '320'),
641 ('f', '3.20E2', '320'),
642 ('f', '3.200E2', '320.0'),
643 ('f', '3.2E-6', '0.0000032'),
644 ('.6f', '0E-15', '0.000000'), # all zeros treated equally
645 ('.6f', '0E1', '0.000000'),
646 ('.6f', '0', '0.000000'),
647 ('.0f', '0', '0'), # no decimal point
648 ('.0f', '0e-2', '0'),
649 ('.0f', '3.14159265', '3'),
650 ('.1f', '3.14159265', '3.1'),
651 ('.4f', '3.14159265', '3.1416'),
652 ('.6f', '3.14159265', '3.141593'),
653 ('.7f', '3.14159265', '3.1415926'), # round-half-even!
654 ('.8f', '3.14159265', '3.14159265'),
655 ('.9f', '3.14159265', '3.141592650'),
656
657 ('g', '0', '0'),
658 ('g', '0.0', '0.0'),
659 ('g', '0E1', '0e+1'),
660 ('G', '0E1', '0E+1'),
661 ('g', '0E-5', '0.00000'),
662 ('g', '0E-6', '0.000000'),
663 ('g', '0E-7', '0e-7'),
664 ('g', '-0E2', '-0e+2'),
665 ('.0g', '3.14159265', '3'), # 0 sig fig -> 1 sig fig
666 ('.1g', '3.14159265', '3'),
667 ('.2g', '3.14159265', '3.1'),
668 ('.5g', '3.14159265', '3.1416'),
669 ('.7g', '3.14159265', '3.141593'),
670 ('.8g', '3.14159265', '3.1415926'), # round-half-even!
671 ('.9g', '3.14159265', '3.14159265'),
672 ('.10g', '3.14159265', '3.14159265'), # don't pad
673
674 ('%', '0E1', '0%'),
675 ('%', '0E0', '0%'),
676 ('%', '0E-1', '0%'),
677 ('%', '0E-2', '0%'),
678 ('%', '0E-3', '0.0%'),
679 ('%', '0E-4', '0.00%'),
680
681 ('.3%', '0', '0.000%'), # all zeros treated equally
682 ('.3%', '0E10', '0.000%'),
683 ('.3%', '0E-10', '0.000%'),
684 ('.3%', '2.34', '234.000%'),
685 ('.3%', '1.234567', '123.457%'),
686 ('.0%', '1.23', '123%'),
687
688 ('e', 'NaN', 'NaN'),
689 ('f', '-NaN123', '-NaN123'),
690 ('+g', 'NaN456', '+NaN456'),
691 ('.3e', 'Inf', 'Infinity'),
692 ('.16f', '-Inf', '-Infinity'),
693 ('.0g', '-sNaN', '-sNaN'),
694
695 ('', '1.00', '1.00'),
696 ]
697 for fmt, d, result in test_values:
698 self.assertEqual(format(Decimal(d), fmt), result)
699
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000700class DecimalArithmeticOperatorsTest(unittest.TestCase):
701 '''Unit tests for all arithmetic operators, binary and unary.'''
702
703 def test_addition(self):
704
705 d1 = Decimal('-11.1')
706 d2 = Decimal('22.2')
707
708 #two Decimals
709 self.assertEqual(d1+d2, Decimal('11.1'))
710 self.assertEqual(d2+d1, Decimal('11.1'))
711
712 #with other type, left
713 c = d1 + 5
714 self.assertEqual(c, Decimal('-6.1'))
715 self.assertEqual(type(c), type(d1))
716
717 #with other type, right
718 c = 5 + d1
719 self.assertEqual(c, Decimal('-6.1'))
720 self.assertEqual(type(c), type(d1))
721
722 #inline with decimal
723 d1 += d2
724 self.assertEqual(d1, Decimal('11.1'))
725
726 #inline with other type
727 d1 += 5
728 self.assertEqual(d1, Decimal('16.1'))
729
730 def test_subtraction(self):
731
732 d1 = Decimal('-11.1')
733 d2 = Decimal('22.2')
734
735 #two Decimals
736 self.assertEqual(d1-d2, Decimal('-33.3'))
737 self.assertEqual(d2-d1, Decimal('33.3'))
738
739 #with other type, left
740 c = d1 - 5
741 self.assertEqual(c, Decimal('-16.1'))
742 self.assertEqual(type(c), type(d1))
743
744 #with other type, right
745 c = 5 - d1
746 self.assertEqual(c, Decimal('16.1'))
747 self.assertEqual(type(c), type(d1))
748
749 #inline with decimal
750 d1 -= d2
751 self.assertEqual(d1, Decimal('-33.3'))
752
753 #inline with other type
754 d1 -= 5
755 self.assertEqual(d1, Decimal('-38.3'))
756
757 def test_multiplication(self):
758
759 d1 = Decimal('-5')
760 d2 = Decimal('3')
761
762 #two Decimals
763 self.assertEqual(d1*d2, Decimal('-15'))
764 self.assertEqual(d2*d1, Decimal('-15'))
765
766 #with other type, left
767 c = d1 * 5
768 self.assertEqual(c, Decimal('-25'))
769 self.assertEqual(type(c), type(d1))
770
771 #with other type, right
772 c = 5 * d1
773 self.assertEqual(c, Decimal('-25'))
774 self.assertEqual(type(c), type(d1))
775
776 #inline with decimal
777 d1 *= d2
778 self.assertEqual(d1, Decimal('-15'))
779
780 #inline with other type
781 d1 *= 5
782 self.assertEqual(d1, Decimal('-75'))
783
784 def test_division(self):
785
786 d1 = Decimal('-5')
787 d2 = Decimal('2')
788
789 #two Decimals
790 self.assertEqual(d1/d2, Decimal('-2.5'))
791 self.assertEqual(d2/d1, Decimal('-0.4'))
792
793 #with other type, left
794 c = d1 / 4
795 self.assertEqual(c, Decimal('-1.25'))
796 self.assertEqual(type(c), type(d1))
797
798 #with other type, right
799 c = 4 / d1
800 self.assertEqual(c, Decimal('-0.8'))
801 self.assertEqual(type(c), type(d1))
802
803 #inline with decimal
804 d1 /= d2
805 self.assertEqual(d1, Decimal('-2.5'))
806
807 #inline with other type
808 d1 /= 4
809 self.assertEqual(d1, Decimal('-0.625'))
810
811 def test_floor_division(self):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000812
813 d1 = Decimal('5')
814 d2 = Decimal('2')
815
816 #two Decimals
817 self.assertEqual(d1//d2, Decimal('2'))
818 self.assertEqual(d2//d1, Decimal('0'))
819
820 #with other type, left
821 c = d1 // 4
822 self.assertEqual(c, Decimal('1'))
823 self.assertEqual(type(c), type(d1))
824
825 #with other type, right
826 c = 7 // d1
827 self.assertEqual(c, Decimal('1'))
828 self.assertEqual(type(c), type(d1))
829
830 #inline with decimal
831 d1 //= d2
832 self.assertEqual(d1, Decimal('2'))
833
834 #inline with other type
835 d1 //= 2
836 self.assertEqual(d1, Decimal('1'))
837
838 def test_powering(self):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000839
840 d1 = Decimal('5')
841 d2 = Decimal('2')
842
843 #two Decimals
844 self.assertEqual(d1**d2, Decimal('25'))
845 self.assertEqual(d2**d1, Decimal('32'))
846
847 #with other type, left
848 c = d1 ** 4
849 self.assertEqual(c, Decimal('625'))
850 self.assertEqual(type(c), type(d1))
851
852 #with other type, right
853 c = 7 ** d1
854 self.assertEqual(c, Decimal('16807'))
855 self.assertEqual(type(c), type(d1))
856
857 #inline with decimal
858 d1 **= d2
859 self.assertEqual(d1, Decimal('25'))
860
861 #inline with other type
862 d1 **= 4
863 self.assertEqual(d1, Decimal('390625'))
864
865 def test_module(self):
866
867 d1 = Decimal('5')
868 d2 = Decimal('2')
869
870 #two Decimals
871 self.assertEqual(d1%d2, Decimal('1'))
872 self.assertEqual(d2%d1, Decimal('2'))
873
874 #with other type, left
875 c = d1 % 4
876 self.assertEqual(c, Decimal('1'))
877 self.assertEqual(type(c), type(d1))
878
879 #with other type, right
880 c = 7 % d1
881 self.assertEqual(c, Decimal('2'))
882 self.assertEqual(type(c), type(d1))
883
884 #inline with decimal
885 d1 %= d2
886 self.assertEqual(d1, Decimal('1'))
887
888 #inline with other type
889 d1 %= 4
890 self.assertEqual(d1, Decimal('1'))
891
892 def test_floor_div_module(self):
893
894 d1 = Decimal('5')
895 d2 = Decimal('2')
896
897 #two Decimals
898 (p, q) = divmod(d1, d2)
899 self.assertEqual(p, Decimal('2'))
900 self.assertEqual(q, Decimal('1'))
901 self.assertEqual(type(p), type(d1))
902 self.assertEqual(type(q), type(d1))
903
904 #with other type, left
905 (p, q) = divmod(d1, 4)
906 self.assertEqual(p, Decimal('1'))
907 self.assertEqual(q, Decimal('1'))
908 self.assertEqual(type(p), type(d1))
909 self.assertEqual(type(q), type(d1))
910
911 #with other type, right
912 (p, q) = divmod(7, d1)
913 self.assertEqual(p, Decimal('1'))
914 self.assertEqual(q, Decimal('2'))
915 self.assertEqual(type(p), type(d1))
916 self.assertEqual(type(q), type(d1))
917
918 def test_unary_operators(self):
919 self.assertEqual(+Decimal(45), Decimal(+45)) # +
920 self.assertEqual(-Decimal(45), Decimal(-45)) # -
921 self.assertEqual(abs(Decimal(45)), abs(Decimal(-45))) # abs
922
Christian Heimes77c02eb2008-02-09 02:18:51 +0000923 def test_nan_comparisons(self):
924 n = Decimal('NaN')
925 s = Decimal('sNaN')
926 i = Decimal('Inf')
927 f = Decimal('2')
928 for x, y in [(n, n), (n, i), (i, n), (n, f), (f, n),
929 (s, n), (n, s), (s, i), (i, s), (s, f), (f, s), (s, s)]:
930 self.assert_(x != y)
931 self.assert_(not (x == y))
932 self.assert_(not (x < y))
933 self.assert_(not (x <= y))
934 self.assert_(not (x > y))
935 self.assert_(not (x >= y))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000936
937# The following are two functions used to test threading in the next class
938
939def thfunc1(cls):
940 d1 = Decimal(1)
941 d3 = Decimal(3)
Christian Heimesfe337bf2008-03-23 21:54:12 +0000942 test1 = d1/d3
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000943 cls.synchro.wait()
Christian Heimesfe337bf2008-03-23 21:54:12 +0000944 test2 = d1/d3
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000945 cls.finish1.set()
Christian Heimesfe337bf2008-03-23 21:54:12 +0000946
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000947 cls.assertEqual(test1, Decimal('0.3333333333333333333333333333'))
948 cls.assertEqual(test2, Decimal('0.3333333333333333333333333333'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000949 return
950
951def thfunc2(cls):
952 d1 = Decimal(1)
953 d3 = Decimal(3)
Christian Heimesfe337bf2008-03-23 21:54:12 +0000954 test1 = d1/d3
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000955 thiscontext = getcontext()
956 thiscontext.prec = 18
Christian Heimesfe337bf2008-03-23 21:54:12 +0000957 test2 = d1/d3
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000958 cls.synchro.set()
959 cls.finish2.set()
Christian Heimesfe337bf2008-03-23 21:54:12 +0000960
Christian Heimes81ee3ef2008-05-04 22:42:01 +0000961 cls.assertEqual(test1, Decimal('0.3333333333333333333333333333'))
Christian Heimesfe337bf2008-03-23 21:54:12 +0000962 cls.assertEqual(test2, Decimal('0.333333333333333333'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000963 return
964
965
966class DecimalUseOfContextTest(unittest.TestCase):
967 '''Unit tests for Use of Context cases in Decimal.'''
968
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000969 try:
970 import threading
971 except ImportError:
972 threading = None
973
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000974 # Take care executing this test from IDLE, there's an issue in threading
975 # that hangs IDLE and I couldn't find it
976
977 def test_threading(self):
978 #Test the "threading isolation" of a Context.
979
980 self.synchro = threading.Event()
981 self.finish1 = threading.Event()
982 self.finish2 = threading.Event()
983
984 th1 = threading.Thread(target=thfunc1, args=(self,))
985 th2 = threading.Thread(target=thfunc2, args=(self,))
986
987 th1.start()
988 th2.start()
989
990 self.finish1.wait()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000991 self.finish2.wait()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000992 return
993
Raymond Hettinger7e71fa52004-12-18 19:07:19 +0000994 if threading is None:
995 del test_threading
996
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000997
998class DecimalUsabilityTest(unittest.TestCase):
999 '''Unit tests for Usability cases of Decimal.'''
1000
1001 def test_comparison_operators(self):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001002
1003 da = Decimal('23.42')
1004 db = Decimal('23.42')
1005 dc = Decimal('45')
1006
1007 #two Decimals
1008 self.failUnless(dc > da)
1009 self.failUnless(dc >= da)
1010 self.failUnless(da < dc)
1011 self.failUnless(da <= dc)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001012 self.assertEqual(da, db)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001013 self.failUnless(da != dc)
1014 self.failUnless(da <= db)
1015 self.failUnless(da >= db)
1016 self.assertEqual(cmp(dc,da), 1)
1017 self.assertEqual(cmp(da,dc), -1)
1018 self.assertEqual(cmp(da,db), 0)
1019
1020 #a Decimal and an int
1021 self.failUnless(dc > 23)
1022 self.failUnless(23 < dc)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001023 self.assertEqual(dc, 45)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001024 self.assertEqual(cmp(dc,23), 1)
1025 self.assertEqual(cmp(23,dc), -1)
1026 self.assertEqual(cmp(dc,45), 0)
1027
1028 #a Decimal and uncomparable
Raymond Hettinger0aeac102004-07-05 22:53:03 +00001029 self.assertNotEqual(da, 'ugly')
1030 self.assertNotEqual(da, 32.7)
1031 self.assertNotEqual(da, object())
1032 self.assertNotEqual(da, object)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001033
Raymond Hettinger0aeac102004-07-05 22:53:03 +00001034 # sortable
Guido van Rossumc1f779c2007-07-03 08:25:58 +00001035 a = list(map(Decimal, range(100)))
Raymond Hettinger0aeac102004-07-05 22:53:03 +00001036 b = a[:]
1037 random.shuffle(a)
1038 a.sort()
1039 self.assertEqual(a, b)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001040
1041 def test_copy_and_deepcopy_methods(self):
1042 d = Decimal('43.24')
1043 c = copy.copy(d)
1044 self.assertEqual(id(c), id(d))
1045 dc = copy.deepcopy(d)
1046 self.assertEqual(id(dc), id(d))
1047
1048 def test_hash_method(self):
1049 #just that it's hashable
1050 hash(Decimal(23))
Thomas Wouters8ce81f72007-09-20 18:22:40 +00001051
1052 test_values = [Decimal(sign*(2**m + n))
1053 for m in [0, 14, 15, 16, 17, 30, 31,
1054 32, 33, 62, 63, 64, 65, 66]
1055 for n in range(-10, 10)
1056 for sign in [-1, 1]]
1057 test_values.extend([
1058 Decimal("-0"), # zeros
1059 Decimal("0.00"),
1060 Decimal("-0.000"),
1061 Decimal("0E10"),
1062 Decimal("-0E12"),
1063 Decimal("10.0"), # negative exponent
1064 Decimal("-23.00000"),
1065 Decimal("1230E100"), # positive exponent
1066 Decimal("-4.5678E50"),
1067 # a value for which hash(n) != hash(n % (2**64-1))
1068 # in Python pre-2.6
1069 Decimal(2**64 + 2**32 - 1),
1070 # selection of values which fail with the old (before
1071 # version 2.6) long.__hash__
1072 Decimal("1.634E100"),
1073 Decimal("90.697E100"),
1074 Decimal("188.83E100"),
1075 Decimal("1652.9E100"),
1076 Decimal("56531E100"),
1077 ])
1078
1079 # check that hash(d) == hash(int(d)) for integral values
1080 for value in test_values:
1081 self.assertEqual(hash(value), hash(int(value)))
1082
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001083 #the same hash that to an int
1084 self.assertEqual(hash(Decimal(23)), hash(23))
Raymond Hettingerbea3f6f2005-03-15 04:59:17 +00001085 self.assertRaises(TypeError, hash, Decimal('NaN'))
1086 self.assert_(hash(Decimal('Inf')))
1087 self.assert_(hash(Decimal('-Inf')))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001088
Christian Heimes2380ac72008-01-09 00:17:24 +00001089 # check that the value of the hash doesn't depend on the
1090 # current context (issue #1757)
1091 c = getcontext()
1092 old_precision = c.prec
1093 x = Decimal("123456789.1")
1094
1095 c.prec = 6
1096 h1 = hash(x)
1097 c.prec = 10
1098 h2 = hash(x)
1099 c.prec = 16
1100 h3 = hash(x)
1101
1102 self.assertEqual(h1, h2)
1103 self.assertEqual(h1, h3)
1104 c.prec = old_precision
1105
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001106 def test_min_and_max_methods(self):
1107
1108 d1 = Decimal('15.32')
1109 d2 = Decimal('28.5')
1110 l1 = 15
1111 l2 = 28
1112
1113 #between Decimals
1114 self.failUnless(min(d1,d2) is d1)
1115 self.failUnless(min(d2,d1) is d1)
1116 self.failUnless(max(d1,d2) is d2)
1117 self.failUnless(max(d2,d1) is d2)
1118
1119 #between Decimal and long
1120 self.failUnless(min(d1,l2) is d1)
1121 self.failUnless(min(l2,d1) is d1)
1122 self.failUnless(max(l1,d2) is d2)
1123 self.failUnless(max(d2,l1) is d2)
1124
1125 def test_as_nonzero(self):
1126 #as false
1127 self.failIf(Decimal(0))
1128 #as true
1129 self.failUnless(Decimal('0.372'))
1130
1131 def test_tostring_methods(self):
1132 #Test str and repr methods.
1133
1134 d = Decimal('15.32')
1135 self.assertEqual(str(d), '15.32') # str
Christian Heimes68f5fbe2008-02-14 08:27:37 +00001136 self.assertEqual(repr(d), "Decimal('15.32')") # repr
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001137
1138 def test_tonum_methods(self):
1139 #Test float, int and long methods.
1140
1141 d1 = Decimal('66')
1142 d2 = Decimal('15.32')
1143
1144 #int
1145 self.assertEqual(int(d1), 66)
1146 self.assertEqual(int(d2), 15)
1147
1148 #long
Guido van Rossume2a383d2007-01-15 16:59:06 +00001149 self.assertEqual(int(d1), 66)
1150 self.assertEqual(int(d2), 15)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001151
1152 #float
1153 self.assertEqual(float(d1), 66)
1154 self.assertEqual(float(d2), 15.32)
1155
Mark Dickinsonb27406c2008-05-09 13:42:33 +00001156 #floor
1157 test_pairs = [
1158 ('123.00', 123),
1159 ('3.2', 3),
1160 ('3.54', 3),
1161 ('3.899', 3),
1162 ('-2.3', -3),
1163 ('-11.0', -11),
1164 ('0.0', 0),
1165 ('-0E3', 0),
1166 ]
1167 for d, i in test_pairs:
1168 self.assertEqual(math.floor(Decimal(d)), i)
1169 self.assertRaises(ValueError, math.floor, Decimal('-NaN'))
1170 self.assertRaises(ValueError, math.floor, Decimal('sNaN'))
1171 self.assertRaises(ValueError, math.floor, Decimal('NaN123'))
1172 self.assertRaises(OverflowError, math.floor, Decimal('Inf'))
1173 self.assertRaises(OverflowError, math.floor, Decimal('-Inf'))
1174
1175 #ceiling
1176 test_pairs = [
1177 ('123.00', 123),
1178 ('3.2', 4),
1179 ('3.54', 4),
1180 ('3.899', 4),
1181 ('-2.3', -2),
1182 ('-11.0', -11),
1183 ('0.0', 0),
1184 ('-0E3', 0),
1185 ]
1186 for d, i in test_pairs:
1187 self.assertEqual(math.ceil(Decimal(d)), i)
1188 self.assertRaises(ValueError, math.ceil, Decimal('-NaN'))
1189 self.assertRaises(ValueError, math.ceil, Decimal('sNaN'))
1190 self.assertRaises(ValueError, math.ceil, Decimal('NaN123'))
1191 self.assertRaises(OverflowError, math.ceil, Decimal('Inf'))
1192 self.assertRaises(OverflowError, math.ceil, Decimal('-Inf'))
1193
1194 #round, single argument
1195 test_pairs = [
1196 ('123.00', 123),
1197 ('3.2', 3),
1198 ('3.54', 4),
1199 ('3.899', 4),
1200 ('-2.3', -2),
1201 ('-11.0', -11),
1202 ('0.0', 0),
1203 ('-0E3', 0),
1204 ('-3.5', -4),
1205 ('-2.5', -2),
1206 ('-1.5', -2),
1207 ('-0.5', 0),
1208 ('0.5', 0),
1209 ('1.5', 2),
1210 ('2.5', 2),
1211 ('3.5', 4),
1212 ]
1213 for d, i in test_pairs:
1214 self.assertEqual(round(Decimal(d)), i)
1215 self.assertRaises(ValueError, round, Decimal('-NaN'))
1216 self.assertRaises(ValueError, round, Decimal('sNaN'))
1217 self.assertRaises(ValueError, round, Decimal('NaN123'))
1218 self.assertRaises(OverflowError, round, Decimal('Inf'))
1219 self.assertRaises(OverflowError, round, Decimal('-Inf'))
1220
1221 #round, two arguments; this is essentially equivalent
1222 #to quantize, which is already extensively tested
1223 test_triples = [
1224 ('123.456', -4, '0E+4'),
1225 ('123.456', -3, '0E+3'),
1226 ('123.456', -2, '1E+2'),
1227 ('123.456', -1, '1.2E+2'),
1228 ('123.456', 0, '123'),
1229 ('123.456', 1, '123.5'),
1230 ('123.456', 2, '123.46'),
1231 ('123.456', 3, '123.456'),
1232 ('123.456', 4, '123.4560'),
1233 ('123.455', 2, '123.46'),
1234 ('123.445', 2, '123.44'),
1235 ('Inf', 4, 'NaN'),
1236 ('-Inf', -23, 'NaN'),
1237 ('sNaN314', 3, 'NaN314'),
1238 ]
1239 for d, n, r in test_triples:
1240 self.assertEqual(str(round(Decimal(d), n)), r)
1241
1242
1243
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001244 def test_eval_round_trip(self):
1245
1246 #with zero
1247 d = Decimal( (0, (0,), 0) )
1248 self.assertEqual(d, eval(repr(d)))
1249
1250 #int
1251 d = Decimal( (1, (4, 5), 0) )
1252 self.assertEqual(d, eval(repr(d)))
1253
1254 #float
1255 d = Decimal( (0, (4, 5, 3, 4), -2) )
1256 self.assertEqual(d, eval(repr(d)))
1257
1258 #weird
1259 d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
1260 self.assertEqual(d, eval(repr(d)))
1261
1262 def test_as_tuple(self):
1263
1264 #with zero
1265 d = Decimal(0)
1266 self.assertEqual(d.as_tuple(), (0, (0,), 0) )
1267
1268 #int
1269 d = Decimal(-45)
1270 self.assertEqual(d.as_tuple(), (1, (4, 5), 0) )
1271
1272 #complicated string
1273 d = Decimal("-4.34913534E-17")
1274 self.assertEqual(d.as_tuple(), (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
1275
1276 #inf
1277 d = Decimal("Infinity")
1278 self.assertEqual(d.as_tuple(), (0, (0,), 'F') )
1279
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001280 #leading zeros in coefficient should be stripped
1281 d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), -2) )
1282 self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), -2) )
1283 d = Decimal( (1, (0, 0, 0), 37) )
1284 self.assertEqual(d.as_tuple(), (1, (0,), 37))
1285 d = Decimal( (1, (), 37) )
1286 self.assertEqual(d.as_tuple(), (1, (0,), 37))
1287
1288 #leading zeros in NaN diagnostic info should be stripped
1289 d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), 'n') )
1290 self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), 'n') )
1291 d = Decimal( (1, (0, 0, 0), 'N') )
1292 self.assertEqual(d.as_tuple(), (1, (), 'N') )
1293 d = Decimal( (1, (), 'n') )
1294 self.assertEqual(d.as_tuple(), (1, (), 'n') )
1295
1296 #coefficient in infinity should be ignored
1297 d = Decimal( (0, (4, 5, 3, 4), 'F') )
1298 self.assertEqual(d.as_tuple(), (0, (0,), 'F'))
1299 d = Decimal( (1, (0, 2, 7, 1), 'F') )
1300 self.assertEqual(d.as_tuple(), (1, (0,), 'F'))
1301
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001302 def test_immutability_operations(self):
1303 # Do operations and check that it didn't change change internal objects.
1304
1305 d1 = Decimal('-25e55')
1306 b1 = Decimal('-25e55')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001307 d2 = Decimal('33e+33')
1308 b2 = Decimal('33e+33')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001309
1310 def checkSameDec(operation, useOther=False):
1311 if useOther:
1312 eval("d1." + operation + "(d2)")
1313 self.assertEqual(d1._sign, b1._sign)
1314 self.assertEqual(d1._int, b1._int)
1315 self.assertEqual(d1._exp, b1._exp)
1316 self.assertEqual(d2._sign, b2._sign)
1317 self.assertEqual(d2._int, b2._int)
1318 self.assertEqual(d2._exp, b2._exp)
1319 else:
1320 eval("d1." + operation + "()")
1321 self.assertEqual(d1._sign, b1._sign)
1322 self.assertEqual(d1._int, b1._int)
1323 self.assertEqual(d1._exp, b1._exp)
1324 return
1325
1326 Decimal(d1)
1327 self.assertEqual(d1._sign, b1._sign)
1328 self.assertEqual(d1._int, b1._int)
1329 self.assertEqual(d1._exp, b1._exp)
1330
1331 checkSameDec("__abs__")
1332 checkSameDec("__add__", True)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001333 checkSameDec("__divmod__", True)
Christian Heimes77c02eb2008-02-09 02:18:51 +00001334 checkSameDec("__eq__", True)
1335 checkSameDec("__ne__", True)
1336 checkSameDec("__le__", True)
1337 checkSameDec("__lt__", True)
1338 checkSameDec("__ge__", True)
1339 checkSameDec("__gt__", True)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001340 checkSameDec("__float__")
1341 checkSameDec("__floordiv__", True)
1342 checkSameDec("__hash__")
1343 checkSameDec("__int__")
Christian Heimes969fe572008-01-25 11:23:10 +00001344 checkSameDec("__trunc__")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001345 checkSameDec("__mod__", True)
1346 checkSameDec("__mul__", True)
1347 checkSameDec("__neg__")
Jack Diederich4dafcc42006-11-28 19:15:13 +00001348 checkSameDec("__bool__")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001349 checkSameDec("__pos__")
1350 checkSameDec("__pow__", True)
1351 checkSameDec("__radd__", True)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001352 checkSameDec("__rdivmod__", True)
1353 checkSameDec("__repr__")
1354 checkSameDec("__rfloordiv__", True)
1355 checkSameDec("__rmod__", True)
1356 checkSameDec("__rmul__", True)
1357 checkSameDec("__rpow__", True)
1358 checkSameDec("__rsub__", True)
1359 checkSameDec("__str__")
1360 checkSameDec("__sub__", True)
1361 checkSameDec("__truediv__", True)
1362 checkSameDec("adjusted")
1363 checkSameDec("as_tuple")
1364 checkSameDec("compare", True)
1365 checkSameDec("max", True)
1366 checkSameDec("min", True)
1367 checkSameDec("normalize")
1368 checkSameDec("quantize", True)
1369 checkSameDec("remainder_near", True)
1370 checkSameDec("same_quantum", True)
1371 checkSameDec("sqrt")
1372 checkSameDec("to_eng_string")
1373 checkSameDec("to_integral")
1374
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001375 def test_subclassing(self):
1376 # Different behaviours when subclassing Decimal
1377
1378 class MyDecimal(Decimal):
1379 pass
1380
1381 d1 = MyDecimal(1)
1382 d2 = MyDecimal(2)
1383 d = d1 + d2
1384 self.assertTrue(type(d) is Decimal)
1385
1386 d = d1.max(d2)
1387 self.assertTrue(type(d) is Decimal)
1388
Christian Heimes0348fb62008-03-26 12:55:56 +00001389 def test_implicit_context(self):
1390 # Check results when context given implicitly. (Issue 2478)
1391 c = getcontext()
1392 self.assertEqual(str(Decimal(0).sqrt()),
1393 str(c.sqrt(Decimal(0))))
1394
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001395
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001396class DecimalPythonAPItests(unittest.TestCase):
1397
1398 def test_pickle(self):
1399 d = Decimal('-3.141590000')
1400 p = pickle.dumps(d)
1401 e = pickle.loads(p)
1402 self.assertEqual(d, e)
1403
Raymond Hettinger5548be22004-07-05 18:49:38 +00001404 def test_int(self):
Raymond Hettinger605ed022004-11-24 07:28:48 +00001405 for x in range(-250, 250):
1406 s = '%0.2f' % (x / 100.0)
Raymond Hettinger5548be22004-07-05 18:49:38 +00001407 # should work the same as for floats
1408 self.assertEqual(int(Decimal(s)), int(float(s)))
Raymond Hettinger605ed022004-11-24 07:28:48 +00001409 # should work the same as to_integral in the ROUND_DOWN mode
Raymond Hettinger5548be22004-07-05 18:49:38 +00001410 d = Decimal(s)
Raymond Hettinger605ed022004-11-24 07:28:48 +00001411 r = d.to_integral(ROUND_DOWN)
Raymond Hettinger5548be22004-07-05 18:49:38 +00001412 self.assertEqual(Decimal(int(d)), r)
1413
Christian Heimes969fe572008-01-25 11:23:10 +00001414 def test_trunc(self):
1415 for x in range(-250, 250):
1416 s = '%0.2f' % (x / 100.0)
1417 # should work the same as for floats
1418 self.assertEqual(int(Decimal(s)), int(float(s)))
1419 # should work the same as to_integral in the ROUND_DOWN mode
1420 d = Decimal(s)
1421 r = d.to_integral(ROUND_DOWN)
Christian Heimes400adb02008-02-01 08:12:03 +00001422 self.assertEqual(Decimal(math.trunc(d)), r)
Christian Heimes969fe572008-01-25 11:23:10 +00001423
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00001424class ContextAPItests(unittest.TestCase):
1425
1426 def test_pickle(self):
1427 c = Context()
1428 e = pickle.loads(pickle.dumps(c))
1429 for k in vars(c):
1430 v1 = vars(c)[k]
1431 v2 = vars(e)[k]
1432 self.assertEqual(v1, v2)
1433
Raymond Hettinger0aeac102004-07-05 22:53:03 +00001434 def test_equality_with_other_types(self):
1435 self.assert_(Decimal(10) in ['a', 1.0, Decimal(10), (1,2), {}])
1436 self.assert_(Decimal(10) not in ['a', 1.0, (1,2), {}])
1437
Raymond Hettinger955d2b22004-08-08 20:17:45 +00001438 def test_copy(self):
1439 # All copies should be deep
1440 c = Context()
1441 d = c.copy()
1442 self.assertNotEqual(id(c), id(d))
1443 self.assertNotEqual(id(c.flags), id(d.flags))
1444 self.assertNotEqual(id(c.traps), id(d.traps))
1445
Thomas Wouters89f507f2006-12-13 04:49:30 +00001446class WithStatementTest(unittest.TestCase):
1447 # Can't do these as docstrings until Python 2.6
1448 # as doctest can't handle __future__ statements
1449
1450 def test_localcontext(self):
1451 # Use a copy of the current context in the block
1452 orig_ctx = getcontext()
1453 with localcontext() as enter_ctx:
1454 set_ctx = getcontext()
1455 final_ctx = getcontext()
1456 self.assert_(orig_ctx is final_ctx, 'did not restore context correctly')
1457 self.assert_(orig_ctx is not set_ctx, 'did not copy the context')
1458 self.assert_(set_ctx is enter_ctx, '__enter__ returned wrong context')
1459
1460 def test_localcontextarg(self):
1461 # Use a copy of the supplied context in the block
1462 orig_ctx = getcontext()
1463 new_ctx = Context(prec=42)
1464 with localcontext(new_ctx) as enter_ctx:
1465 set_ctx = getcontext()
1466 final_ctx = getcontext()
1467 self.assert_(orig_ctx is final_ctx, 'did not restore context correctly')
1468 self.assert_(set_ctx.prec == new_ctx.prec, 'did not set correct context')
1469 self.assert_(new_ctx is not set_ctx, 'did not copy the context')
1470 self.assert_(set_ctx is enter_ctx, '__enter__ returned wrong context')
1471
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001472class ContextFlags(unittest.TestCase):
1473 def test_flags_irrelevant(self):
1474 # check that the result (numeric result + flags raised) of an
1475 # arithmetic operation doesn't depend on the current flags
1476
1477 context = Context(prec=9, Emin = -999999999, Emax = 999999999,
1478 rounding=ROUND_HALF_EVEN, traps=[], flags=[])
1479
1480 # operations that raise various flags, in the form (function, arglist)
1481 operations = [
1482 (context._apply, [Decimal("100E-1000000009")]),
1483 (context.sqrt, [Decimal(2)]),
1484 (context.add, [Decimal("1.23456789"), Decimal("9.87654321")]),
1485 (context.multiply, [Decimal("1.23456789"), Decimal("9.87654321")]),
1486 (context.subtract, [Decimal("1.23456789"), Decimal("9.87654321")]),
1487 ]
1488
1489 # try various flags individually, then a whole lot at once
1490 flagsets = [[Inexact], [Rounded], [Underflow], [Clamped], [Subnormal],
1491 [Inexact, Rounded, Underflow, Clamped, Subnormal]]
1492
1493 for fn, args in operations:
1494 # find answer and flags raised using a clean context
1495 context.clear_flags()
1496 ans = fn(*args)
1497 flags = [k for k, v in context.flags.items() if v]
1498
1499 for extra_flags in flagsets:
1500 # set flags, before calling operation
1501 context.clear_flags()
1502 for flag in extra_flags:
1503 context._raise_error(flag)
1504 new_ans = fn(*args)
1505
1506 # flags that we expect to be set after the operation
1507 expected_flags = list(flags)
1508 for flag in extra_flags:
1509 if flag not in expected_flags:
1510 expected_flags.append(flag)
1511 expected_flags.sort(key=id)
1512
1513 # flags we actually got
1514 new_flags = [k for k,v in context.flags.items() if v]
1515 new_flags.sort(key=id)
1516
1517 self.assertEqual(ans, new_ans,
1518 "operation produces different answers depending on flags set: " +
1519 "expected %s, got %s." % (ans, new_ans))
1520 self.assertEqual(new_flags, expected_flags,
1521 "operation raises different flags depending on flags set: " +
1522 "expected %s, got %s" % (expected_flags, new_flags))
1523
1524def test_main(arith=False, verbose=None, todo_tests=None, debug=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001525 """ Execute the tests.
1526
Raymond Hettingered20ad82004-09-04 20:09:13 +00001527 Runs all arithmetic tests if arith is True or if the "decimal" resource
1528 is enabled in regrtest.py
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001529 """
Raymond Hettingered20ad82004-09-04 20:09:13 +00001530
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001531 init()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001532 global TEST_ALL, DEBUG
Raymond Hettingered20ad82004-09-04 20:09:13 +00001533 TEST_ALL = arith or is_resource_enabled('decimal')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001534 DEBUG = debug
Raymond Hettingered20ad82004-09-04 20:09:13 +00001535
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001536 if todo_tests is None:
1537 test_classes = [
1538 DecimalExplicitConstructionTest,
1539 DecimalImplicitConstructionTest,
1540 DecimalArithmeticOperatorsTest,
Christian Heimesf16baeb2008-02-29 14:57:44 +00001541 DecimalFormatTest,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001542 DecimalUseOfContextTest,
1543 DecimalUsabilityTest,
1544 DecimalPythonAPItests,
1545 ContextAPItests,
1546 DecimalTest,
1547 WithStatementTest,
1548 ContextFlags
1549 ]
1550 else:
1551 test_classes = [DecimalTest]
1552
1553 # Dynamically build custom test definition for each file in the test
1554 # directory and add the definitions to the DecimalTest class. This
1555 # procedure insures that new files do not get skipped.
1556 for filename in os.listdir(directory):
1557 if '.decTest' not in filename or filename.startswith("."):
1558 continue
1559 head, tail = filename.split('.')
1560 if todo_tests is not None and head not in todo_tests:
1561 continue
1562 tester = lambda self, f=filename: self.eval_file(directory + f)
1563 setattr(DecimalTest, 'test_' + head, tester)
1564 del filename, head, tail, tester
1565
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001566
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001567 try:
1568 run_unittest(*test_classes)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001569 if todo_tests is None:
1570 import decimal as DecimalModule
1571 run_doctest(DecimalModule, verbose)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001572 finally:
1573 setcontext(ORIGINAL_CONTEXT)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001574
1575if __name__ == '__main__':
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001576 import optparse
1577 p = optparse.OptionParser("test_decimal.py [--debug] [{--skip | test1 [test2 [...]]}]")
1578 p.add_option('--debug', '-d', action='store_true', help='shows the test number and context before each test')
1579 p.add_option('--skip', '-s', action='store_true', help='skip over 90% of the arithmetic tests')
1580 (opt, args) = p.parse_args()
1581
1582 if opt.skip:
1583 test_main(arith=False, verbose=True)
1584 elif args:
1585 test_main(arith=True, verbose=True, todo_tests=args, debug=opt.debug)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001586 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001587 test_main(arith=True, verbose=True)