blob: 40313475fb999697f17452a91b2add69bef3f0e1 [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
Stefan Krah1919b7e2012-03-21 18:25:23 +010019 http://speleotrove.com/decimal/dectest.zip
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000020
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
Christian Heimes400adb02008-02-01 08:12:03 +000027import math
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000028import os, sys
Mark Dickinsonac256ab2010-04-03 11:08:14 +000029import operator
Mark Dickinsonb1d8e322010-05-22 18:35:36 +000030import warnings
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000031import pickle, copy
Christian Heimes400adb02008-02-01 08:12:03 +000032import unittest
Raymond Hettinger82417ca2009-02-03 03:54:28 +000033import numbers
Stefan Krah1919b7e2012-03-21 18:25:23 +010034import locale
Eric Smith3ab08ca2010-12-04 15:17:38 +000035from test.support import (run_unittest, run_doctest, is_resource_enabled,
36 requires_IEEE_754)
Stefan Krah6fb204a2012-09-28 16:18:54 +020037from test.support import (check_warnings, import_fresh_module, TestFailed,
Stefan Krah6e467042012-11-10 23:09:04 +010038 run_with_locale, cpython_only)
Raymond Hettinger0aeac102004-07-05 22:53:03 +000039import random
Stefan Krah1919b7e2012-03-21 18:25:23 +010040import time
41import warnings
Raymond Hettinger7e71fa52004-12-18 19:07:19 +000042try:
43 import threading
44except ImportError:
45 threading = None
Raymond Hettinger7c85fa42004-07-01 11:01:35 +000046
Raymond Hettingerfed52962004-07-14 15:41:57 +000047
Stefan Krah1919b7e2012-03-21 18:25:23 +010048C = import_fresh_module('decimal', fresh=['_decimal'])
49P = import_fresh_module('decimal', blocked=['_decimal'])
50orig_sys_decimal = sys.modules['decimal']
51
52# fractions module must import the correct decimal module.
53cfractions = import_fresh_module('fractions', fresh=['fractions'])
54sys.modules['decimal'] = P
55pfractions = import_fresh_module('fractions', fresh=['fractions'])
56sys.modules['decimal'] = C
57fractions = {C:cfractions, P:pfractions}
58sys.modules['decimal'] = orig_sys_decimal
59
60
61# Useful Test Constant
62Signals = {
63 C: tuple(C.getcontext().flags.keys()) if C else None,
64 P: tuple(P.getcontext().flags.keys())
65}
Mark Dickinsonc69160e2010-05-04 14:35:33 +000066# Signals ordered with respect to precedence: when an operation
67# produces multiple signals, signals occurring later in the list
68# should be handled before those occurring earlier in the list.
Stefan Krah1919b7e2012-03-21 18:25:23 +010069OrderedSignals = {
70 C: [C.Clamped, C.Rounded, C.Inexact, C.Subnormal, C.Underflow,
71 C.Overflow, C.DivisionByZero, C.InvalidOperation,
72 C.FloatOperation] if C else None,
73 P: [P.Clamped, P.Rounded, P.Inexact, P.Subnormal, P.Underflow,
74 P.Overflow, P.DivisionByZero, P.InvalidOperation,
75 P.FloatOperation]
76}
77def assert_signals(cls, context, attr, expected):
78 d = getattr(context, attr)
79 cls.assertTrue(all(d[s] if s in expected else not d[s] for s in d))
80
Stefan Krah59a4a932013-01-16 12:58:59 +010081ROUND_UP = P.ROUND_UP
82ROUND_DOWN = P.ROUND_DOWN
83ROUND_CEILING = P.ROUND_CEILING
84ROUND_FLOOR = P.ROUND_FLOOR
85ROUND_HALF_UP = P.ROUND_HALF_UP
86ROUND_HALF_DOWN = P.ROUND_HALF_DOWN
87ROUND_HALF_EVEN = P.ROUND_HALF_EVEN
88ROUND_05UP = P.ROUND_05UP
89
90RoundingModes = [
91 ROUND_UP, ROUND_DOWN, ROUND_CEILING, ROUND_FLOOR,
92 ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,
93 ROUND_05UP
94]
Mark Dickinsonc69160e2010-05-04 14:35:33 +000095
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000096# Tests are built around these assumed context defaults.
97# test_main() restores the original context.
Stefan Krah1919b7e2012-03-21 18:25:23 +010098ORIGINAL_CONTEXT = {
99 C: C.getcontext().copy() if C else None,
100 P: P.getcontext().copy()
101}
102def init(m):
103 if not m: return
104 DefaultTestContext = m.Context(
Stefan Krah59a4a932013-01-16 12:58:59 +0100105 prec=9, rounding=ROUND_HALF_EVEN, traps=dict.fromkeys(Signals[m], 0)
Stefan Krah1919b7e2012-03-21 18:25:23 +0100106 )
107 m.setcontext(DefaultTestContext)
Raymond Hettinger6ea48452004-07-03 12:26:21 +0000108
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000109TESTDATADIR = 'decimaltestdata'
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +0000110if __name__ == '__main__':
111 file = sys.argv[0]
112else:
113 file = __file__
114testdir = os.path.dirname(file) or os.curdir
Raymond Hettinger267b8682005-03-27 10:47:39 +0000115directory = testdir + os.sep + TESTDATADIR + os.sep
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000116
Raymond Hettinger267b8682005-03-27 10:47:39 +0000117skip_expected = not os.path.isdir(directory)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000118
119# Make sure it actually raises errors when not expected and caught in flags
120# Slower, since it runs some things several times.
121EXTENDEDERRORTEST = False
122
Stefan Krah1919b7e2012-03-21 18:25:23 +0100123# Test extra functionality in the C version (-DEXTRA_FUNCTIONALITY).
124EXTRA_FUNCTIONALITY = True if hasattr(C, 'DecClamped') else False
125requires_extra_functionality = unittest.skipUnless(
126 EXTRA_FUNCTIONALITY, "test requires build with -DEXTRA_FUNCTIONALITY")
127skip_if_extra_functionality = unittest.skipIf(
128 EXTRA_FUNCTIONALITY, "test requires regular build")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000129
130
Stefan Krah1919b7e2012-03-21 18:25:23 +0100131class IBMTestCases(unittest.TestCase):
132 """Class which tests the Decimal class against the IBM test cases."""
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000133
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000134 def setUp(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100135 self.context = self.decimal.Context()
136 self.readcontext = self.decimal.Context()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000137 self.ignore_list = ['#']
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000138
Stefan Krah1919b7e2012-03-21 18:25:23 +0100139 # List of individual .decTest test ids that correspond to tests that
140 # we're skipping for one reason or another.
141 self.skipped_test_ids = set([
142 # Skip implementation-specific scaleb tests.
143 'scbx164',
144 'scbx165',
145
146 # For some operations (currently exp, ln, log10, power), the decNumber
147 # reference implementation imposes additional restrictions on the context
148 # and operands. These restrictions are not part of the specification;
149 # however, the effect of these restrictions does show up in some of the
150 # testcases. We skip testcases that violate these restrictions, since
151 # Decimal behaves differently from decNumber for these testcases so these
152 # testcases would otherwise fail.
153 'expx901',
154 'expx902',
155 'expx903',
156 'expx905',
157 'lnx901',
158 'lnx902',
159 'lnx903',
160 'lnx905',
161 'logx901',
162 'logx902',
163 'logx903',
164 'logx905',
165 'powx1183',
166 'powx1184',
167 'powx4001',
168 'powx4002',
169 'powx4003',
170 'powx4005',
171 'powx4008',
172 'powx4010',
173 'powx4012',
174 'powx4014',
175 ])
176
177 if self.decimal == C:
178 # status has additional Subnormal, Underflow
179 self.skipped_test_ids.add('pwsx803')
180 self.skipped_test_ids.add('pwsx805')
181 # Correct rounding (skipped for decNumber, too)
182 self.skipped_test_ids.add('powx4302')
183 self.skipped_test_ids.add('powx4303')
184 self.skipped_test_ids.add('powx4342')
185 self.skipped_test_ids.add('powx4343')
186 # http://bugs.python.org/issue7049
187 self.skipped_test_ids.add('pwmx325')
188 self.skipped_test_ids.add('pwmx326')
189
190 # Map test directives to setter functions.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000191 self.ChangeDict = {'precision' : self.change_precision,
Stefan Krah1919b7e2012-03-21 18:25:23 +0100192 'rounding' : self.change_rounding_method,
193 'maxexponent' : self.change_max_exponent,
194 'minexponent' : self.change_min_exponent,
195 'clamp' : self.change_clamp}
196
197 # Name adapter to be able to change the Decimal and Context
198 # interface without changing the test files from Cowlishaw.
199 self.NameAdapter = {'and':'logical_and',
200 'apply':'_apply',
201 'class':'number_class',
202 'comparesig':'compare_signal',
203 'comparetotal':'compare_total',
204 'comparetotmag':'compare_total_mag',
205 'copy':'copy_decimal',
206 'copyabs':'copy_abs',
207 'copynegate':'copy_negate',
208 'copysign':'copy_sign',
209 'divideint':'divide_int',
210 'invert':'logical_invert',
211 'iscanonical':'is_canonical',
212 'isfinite':'is_finite',
213 'isinfinite':'is_infinite',
214 'isnan':'is_nan',
215 'isnormal':'is_normal',
216 'isqnan':'is_qnan',
217 'issigned':'is_signed',
218 'issnan':'is_snan',
219 'issubnormal':'is_subnormal',
220 'iszero':'is_zero',
221 'maxmag':'max_mag',
222 'minmag':'min_mag',
223 'nextminus':'next_minus',
224 'nextplus':'next_plus',
225 'nexttoward':'next_toward',
226 'or':'logical_or',
227 'reduce':'normalize',
228 'remaindernear':'remainder_near',
229 'samequantum':'same_quantum',
230 'squareroot':'sqrt',
231 'toeng':'to_eng_string',
232 'tointegral':'to_integral_value',
233 'tointegralx':'to_integral_exact',
234 'tosci':'to_sci_string',
235 'xor':'logical_xor'}
236
237 # Map test-case names to roundings.
Stefan Krah59a4a932013-01-16 12:58:59 +0100238 self.RoundingDict = {'ceiling' : ROUND_CEILING,
239 'down' : ROUND_DOWN,
240 'floor' : ROUND_FLOOR,
241 'half_down' : ROUND_HALF_DOWN,
242 'half_even' : ROUND_HALF_EVEN,
243 'half_up' : ROUND_HALF_UP,
244 'up' : ROUND_UP,
245 '05up' : ROUND_05UP}
Stefan Krah1919b7e2012-03-21 18:25:23 +0100246
247 # Map the test cases' error names to the actual errors.
248 self.ErrorNames = {'clamped' : self.decimal.Clamped,
249 'conversion_syntax' : self.decimal.InvalidOperation,
250 'division_by_zero' : self.decimal.DivisionByZero,
251 'division_impossible' : self.decimal.InvalidOperation,
252 'division_undefined' : self.decimal.InvalidOperation,
253 'inexact' : self.decimal.Inexact,
254 'invalid_context' : self.decimal.InvalidOperation,
255 'invalid_operation' : self.decimal.InvalidOperation,
256 'overflow' : self.decimal.Overflow,
257 'rounded' : self.decimal.Rounded,
258 'subnormal' : self.decimal.Subnormal,
259 'underflow' : self.decimal.Underflow}
260
261 # The following functions return True/False rather than a
262 # Decimal instance.
263 self.LogicalFunctions = ('is_canonical',
264 'is_finite',
265 'is_infinite',
266 'is_nan',
267 'is_normal',
268 'is_qnan',
269 'is_signed',
270 'is_snan',
271 'is_subnormal',
272 'is_zero',
273 'same_quantum')
274
275 def read_unlimited(self, v, context):
276 """Work around the limitations of the 32-bit _decimal version. The
277 guaranteed maximum values for prec, Emax etc. are 425000000,
278 but higher values usually work, except for rare corner cases.
279 In particular, all of the IBM tests pass with maximum values
280 of 1070000000."""
281 if self.decimal == C and self.decimal.MAX_EMAX == 425000000:
282 self.readcontext._unsafe_setprec(1070000000)
283 self.readcontext._unsafe_setemax(1070000000)
284 self.readcontext._unsafe_setemin(-1070000000)
285 return self.readcontext.create_decimal(v)
286 else:
287 return self.decimal.Decimal(v, context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000288
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000289 def eval_file(self, file):
290 global skip_expected
291 if skip_expected:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000292 raise unittest.SkipTest
Antoine Pitrou92f60ed2010-10-14 22:11:44 +0000293 with open(file) as f:
294 for line in f:
295 line = line.replace('\r\n', '').replace('\n', '')
296 #print line
297 try:
298 t = self.eval_line(line)
Stefan Krah1919b7e2012-03-21 18:25:23 +0100299 except self.decimal.DecimalException as exception:
Ezio Melotti13925002011-03-16 11:05:33 +0200300 #Exception raised where there shouldn't have been one.
Antoine Pitrou92f60ed2010-10-14 22:11:44 +0000301 self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000302
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000303
304 def eval_line(self, s):
305 if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith(' --'):
306 s = (s.split('->')[0] + '->' +
307 s.split('->')[1].split('--')[0]).strip()
308 else:
309 s = s.split('--')[0].strip()
310
311 for ignore in self.ignore_list:
312 if s.find(ignore) >= 0:
313 #print s.split()[0], 'NotImplemented--', ignore
314 return
315 if not s:
316 return
317 elif ':' in s:
318 return self.eval_directive(s)
319 else:
320 return self.eval_equation(s)
321
322 def eval_directive(self, s):
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000323 funct, value = (x.strip().lower() for x in s.split(':'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000324 if funct == 'rounding':
Stefan Krah1919b7e2012-03-21 18:25:23 +0100325 value = self.RoundingDict[value]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000326 else:
327 try:
328 value = int(value)
329 except ValueError:
330 pass
331
Stefan Krah1919b7e2012-03-21 18:25:23 +0100332 funct = self.ChangeDict.get(funct, (lambda *args: None))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000333 funct(value)
334
335 def eval_equation(self, s):
Raymond Hettingered20ad82004-09-04 20:09:13 +0000336
337 if not TEST_ALL and random.random() < 0.90:
338 return
339
Stefan Krah1919b7e2012-03-21 18:25:23 +0100340 self.context.clear_flags()
341
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000342 try:
343 Sides = s.split('->')
344 L = Sides[0].strip().split()
345 id = L[0]
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000346 if DEBUG:
347 print("Test ", id, end=" ")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000348 funct = L[1].lower()
349 valstemp = L[2:]
350 L = Sides[1].strip().split()
351 ans = L[0]
352 exceptions = L[1:]
353 except (TypeError, AttributeError, IndexError):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100354 raise self.decimal.InvalidOperation
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000355 def FixQuotes(val):
356 val = val.replace("''", 'SingleQuote').replace('""', 'DoubleQuote')
357 val = val.replace("'", '').replace('"', '')
358 val = val.replace('SingleQuote', "'").replace('DoubleQuote', '"')
359 return val
Mark Dickinson8a546532009-10-08 16:30:38 +0000360
Stefan Krah1919b7e2012-03-21 18:25:23 +0100361 if id in self.skipped_test_ids:
Mark Dickinson8a546532009-10-08 16:30:38 +0000362 return
363
Stefan Krah1919b7e2012-03-21 18:25:23 +0100364 fname = self.NameAdapter.get(funct, funct)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000365 if fname == 'rescale':
366 return
367 funct = getattr(self.context, fname)
368 vals = []
369 conglomerate = ''
370 quote = 0
Stefan Krah1919b7e2012-03-21 18:25:23 +0100371 theirexceptions = [self.ErrorNames[x.lower()] for x in exceptions]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000372
Stefan Krah1919b7e2012-03-21 18:25:23 +0100373 for exception in Signals[self.decimal]:
Raymond Hettingerbf440692004-07-10 14:14:37 +0000374 self.context.traps[exception] = 1 #Catch these bugs...
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000375 for exception in theirexceptions:
Raymond Hettingerbf440692004-07-10 14:14:37 +0000376 self.context.traps[exception] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000377 for i, val in enumerate(valstemp):
378 if val.count("'") % 2 == 1:
379 quote = 1 - quote
380 if quote:
381 conglomerate = conglomerate + ' ' + val
382 continue
383 else:
384 val = conglomerate + val
385 conglomerate = ''
386 v = FixQuotes(val)
387 if fname in ('to_sci_string', 'to_eng_string'):
388 if EXTENDEDERRORTEST:
389 for error in theirexceptions:
Raymond Hettingerbf440692004-07-10 14:14:37 +0000390 self.context.traps[error] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000391 try:
392 funct(self.context.create_decimal(v))
393 except error:
394 pass
Stefan Krah1919b7e2012-03-21 18:25:23 +0100395 except Signals[self.decimal] as e:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000396 self.fail("Raised %s in %s when %s disabled" % \
397 (e, s, error))
398 else:
399 self.fail("Did not raise %s in %s" % (error, s))
Raymond Hettingerbf440692004-07-10 14:14:37 +0000400 self.context.traps[error] = 0
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000401 v = self.context.create_decimal(v)
402 else:
Stefan Krah1919b7e2012-03-21 18:25:23 +0100403 v = self.read_unlimited(v, self.context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000404 vals.append(v)
405
406 ans = FixQuotes(ans)
407
408 if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'):
409 for error in theirexceptions:
Raymond Hettingerbf440692004-07-10 14:14:37 +0000410 self.context.traps[error] = 1
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000411 try:
412 funct(*vals)
413 except error:
414 pass
Stefan Krah1919b7e2012-03-21 18:25:23 +0100415 except Signals[self.decimal] as e:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000416 self.fail("Raised %s in %s when %s disabled" % \
417 (e, s, error))
418 else:
419 self.fail("Did not raise %s in %s" % (error, s))
Raymond Hettingerbf440692004-07-10 14:14:37 +0000420 self.context.traps[error] = 0
Mark Dickinsonc69160e2010-05-04 14:35:33 +0000421
422 # as above, but add traps cumulatively, to check precedence
Stefan Krah1919b7e2012-03-21 18:25:23 +0100423 ordered_errors = [e for e in OrderedSignals[self.decimal] if e in theirexceptions]
Mark Dickinsonc69160e2010-05-04 14:35:33 +0000424 for error in ordered_errors:
425 self.context.traps[error] = 1
426 try:
427 funct(*vals)
428 except error:
429 pass
Stefan Krah1919b7e2012-03-21 18:25:23 +0100430 except Signals[self.decimal] as e:
Mark Dickinsonc69160e2010-05-04 14:35:33 +0000431 self.fail("Raised %s in %s; expected %s" %
432 (type(e), s, error))
433 else:
434 self.fail("Did not raise %s in %s" % (error, s))
435 # reset traps
436 for error in ordered_errors:
437 self.context.traps[error] = 0
438
439
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000440 if DEBUG:
441 print("--", self.context)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000442 try:
443 result = str(funct(*vals))
Stefan Krah1919b7e2012-03-21 18:25:23 +0100444 if fname in self.LogicalFunctions:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000445 result = str(int(eval(result))) # 'True', 'False' -> '1', '0'
Stefan Krah1919b7e2012-03-21 18:25:23 +0100446 except Signals[self.decimal] as error:
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000447 self.fail("Raised %s in %s" % (error, s))
448 except: #Catch any error long enough to state the test case.
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000449 print("ERROR:", s)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000450 raise
451
452 myexceptions = self.getexceptions()
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000453
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000454 myexceptions.sort(key=repr)
455 theirexceptions.sort(key=repr)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000456
457 self.assertEqual(result, ans,
458 'Incorrect answer for ' + s + ' -- got ' + result)
Stefan Krah1919b7e2012-03-21 18:25:23 +0100459
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000460 self.assertEqual(myexceptions, theirexceptions,
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000461 'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000462
463 def getexceptions(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100464 return [e for e in Signals[self.decimal] if self.context.flags[e]]
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000465
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000466 def change_precision(self, prec):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100467 if self.decimal == C and self.decimal.MAX_PREC == 425000000:
468 self.context._unsafe_setprec(prec)
469 else:
470 self.context.prec = prec
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000471 def change_rounding_method(self, rounding):
472 self.context.rounding = rounding
473 def change_min_exponent(self, exp):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100474 if self.decimal == C and self.decimal.MAX_PREC == 425000000:
475 self.context._unsafe_setemin(exp)
476 else:
477 self.context.Emin = exp
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000478 def change_max_exponent(self, exp):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100479 if self.decimal == C and self.decimal.MAX_PREC == 425000000:
480 self.context._unsafe_setemax(exp)
481 else:
482 self.context.Emax = exp
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000483 def change_clamp(self, clamp):
Mark Dickinsonb1d8e322010-05-22 18:35:36 +0000484 self.context.clamp = clamp
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000485
Stefan Krah1919b7e2012-03-21 18:25:23 +0100486class CIBMTestCases(IBMTestCases):
487 decimal = C
488class PyIBMTestCases(IBMTestCases):
489 decimal = P
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000490
491# The following classes test the behaviour of Decimal according to PEP 327
492
Stefan Krah1919b7e2012-03-21 18:25:23 +0100493class ExplicitConstructionTest(unittest.TestCase):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000494 '''Unit tests for Explicit Construction cases of Decimal.'''
495
496 def test_explicit_empty(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100497 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000498 self.assertEqual(Decimal(), Decimal("0"))
499
500 def test_explicit_from_None(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100501 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000502 self.assertRaises(TypeError, Decimal, None)
503
504 def test_explicit_from_int(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100505 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000506
507 #positive
508 d = Decimal(45)
509 self.assertEqual(str(d), '45')
510
511 #very large positive
512 d = Decimal(500000123)
513 self.assertEqual(str(d), '500000123')
514
515 #negative
516 d = Decimal(-45)
517 self.assertEqual(str(d), '-45')
518
519 #zero
520 d = Decimal(0)
521 self.assertEqual(str(d), '0')
522
Stefan Krah1919b7e2012-03-21 18:25:23 +0100523 # single word longs
524 for n in range(0, 32):
525 for sign in (-1, 1):
526 for x in range(-5, 5):
527 i = sign * (2**n + x)
528 d = Decimal(i)
529 self.assertEqual(str(d), str(i))
530
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000531 def test_explicit_from_string(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100532 Decimal = self.decimal.Decimal
533 InvalidOperation = self.decimal.InvalidOperation
534 localcontext = self.decimal.localcontext
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000535
536 #empty
537 self.assertEqual(str(Decimal('')), 'NaN')
538
539 #int
540 self.assertEqual(str(Decimal('45')), '45')
541
542 #float
543 self.assertEqual(str(Decimal('45.34')), '45.34')
544
545 #engineer notation
546 self.assertEqual(str(Decimal('45e2')), '4.5E+3')
547
548 #just not a number
549 self.assertEqual(str(Decimal('ugly')), 'NaN')
550
Christian Heimesa62da1d2008-01-12 19:39:10 +0000551 #leading and trailing whitespace permitted
552 self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
553 self.assertEqual(str(Decimal(' -7.89')), '-7.89')
Stefan Krah1919b7e2012-03-21 18:25:23 +0100554 self.assertEqual(str(Decimal(" 3.45679 ")), '3.45679')
555
556 # unicode whitespace
557 for lead in ["", ' ', '\u00a0', '\u205f']:
558 for trail in ["", ' ', '\u00a0', '\u205f']:
559 self.assertEqual(str(Decimal(lead + '9.311E+28' + trail)),
560 '9.311E+28')
561
562 with localcontext() as c:
563 c.traps[InvalidOperation] = True
564 # Invalid string
565 self.assertRaises(InvalidOperation, Decimal, "xyz")
566 # Two arguments max
567 self.assertRaises(TypeError, Decimal, "1234", "x", "y")
568
569 # space within the numeric part
570 self.assertRaises(InvalidOperation, Decimal, "1\u00a02\u00a03")
571 self.assertRaises(InvalidOperation, Decimal, "\u00a01\u00a02\u00a0")
572
573 # unicode whitespace
574 self.assertRaises(InvalidOperation, Decimal, "\u00a0")
575 self.assertRaises(InvalidOperation, Decimal, "\u00a0\u00a0")
576
577 # embedded NUL
578 self.assertRaises(InvalidOperation, Decimal, "12\u00003")
579
Stefan Krah6e467042012-11-10 23:09:04 +0100580 @cpython_only
581 def test_from_legacy_strings(self):
582 import _testcapi
583 Decimal = self.decimal.Decimal
584 context = self.decimal.Context()
585
586 s = _testcapi.unicode_legacy_string('9.999999')
587 self.assertEqual(str(Decimal(s)), '9.999999')
588 self.assertEqual(str(context.create_decimal(s)), '9.999999')
Christian Heimesa62da1d2008-01-12 19:39:10 +0000589
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000590 def test_explicit_from_tuples(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100591 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000592
593 #zero
594 d = Decimal( (0, (0,), 0) )
595 self.assertEqual(str(d), '0')
596
597 #int
598 d = Decimal( (1, (4, 5), 0) )
599 self.assertEqual(str(d), '-45')
600
601 #float
602 d = Decimal( (0, (4, 5, 3, 4), -2) )
603 self.assertEqual(str(d), '45.34')
604
605 #weird
606 d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
607 self.assertEqual(str(d), '-4.34913534E-17')
608
Stefan Krah1919b7e2012-03-21 18:25:23 +0100609 #inf
610 d = Decimal( (0, (), "F") )
611 self.assertEqual(str(d), 'Infinity')
612
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000613 #wrong number of items
614 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1)) )
615
616 #bad sign
617 self.assertRaises(ValueError, Decimal, (8, (4, 3, 4, 9, 1), 2) )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000618 self.assertRaises(ValueError, Decimal, (0., (4, 3, 4, 9, 1), 2) )
619 self.assertRaises(ValueError, Decimal, (Decimal(1), (4, 3, 4, 9, 1), 2))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000620
621 #bad exp
622 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 'wrong!') )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000623 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 0.) )
624 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), '1') )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000625
626 #bad coefficients
Stefan Krah1919b7e2012-03-21 18:25:23 +0100627 self.assertRaises(ValueError, Decimal, (1, "xyz", 2) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000628 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, None, 1), 2) )
629 self.assertRaises(ValueError, Decimal, (1, (4, -3, 4, 9, 1), 2) )
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000630 self.assertRaises(ValueError, Decimal, (1, (4, 10, 4, 9, 1), 2) )
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +0000631 self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 'a', 1), 2) )
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000632
Stefan Krah1919b7e2012-03-21 18:25:23 +0100633 def test_explicit_from_list(self):
634 Decimal = self.decimal.Decimal
635
636 d = Decimal([0, [0], 0])
637 self.assertEqual(str(d), '0')
638
639 d = Decimal([1, [4, 3, 4, 9, 1, 3, 5, 3, 4], -25])
640 self.assertEqual(str(d), '-4.34913534E-17')
641
642 d = Decimal([1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25])
643 self.assertEqual(str(d), '-4.34913534E-17')
644
645 d = Decimal((1, [4, 3, 4, 9, 1, 3, 5, 3, 4], -25))
646 self.assertEqual(str(d), '-4.34913534E-17')
647
Antoine Pitrou503ab332010-03-30 18:56:19 +0000648 def test_explicit_from_bool(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100649 Decimal = self.decimal.Decimal
650
Antoine Pitrou503ab332010-03-30 18:56:19 +0000651 self.assertIs(bool(Decimal(0)), False)
652 self.assertIs(bool(Decimal(1)), True)
653 self.assertEqual(Decimal(False), Decimal(0))
654 self.assertEqual(Decimal(True), Decimal(1))
655
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000656 def test_explicit_from_Decimal(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100657 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000658
659 #positive
660 d = Decimal(45)
661 e = Decimal(d)
662 self.assertEqual(str(e), '45')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000663
664 #very large positive
665 d = Decimal(500000123)
666 e = Decimal(d)
667 self.assertEqual(str(e), '500000123')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000668
669 #negative
670 d = Decimal(-45)
671 e = Decimal(d)
672 self.assertEqual(str(e), '-45')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000673
674 #zero
675 d = Decimal(0)
676 e = Decimal(d)
677 self.assertEqual(str(e), '0')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000678
Raymond Hettinger96798592010-04-02 16:58:27 +0000679 @requires_IEEE_754
680 def test_explicit_from_float(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100681
682 Decimal = self.decimal.Decimal
683
Raymond Hettinger96798592010-04-02 16:58:27 +0000684 r = Decimal(0.1)
685 self.assertEqual(type(r), Decimal)
686 self.assertEqual(str(r),
687 '0.1000000000000000055511151231257827021181583404541015625')
688 self.assertTrue(Decimal(float('nan')).is_qnan())
689 self.assertTrue(Decimal(float('inf')).is_infinite())
690 self.assertTrue(Decimal(float('-inf')).is_infinite())
691 self.assertEqual(str(Decimal(float('nan'))),
692 str(Decimal('NaN')))
693 self.assertEqual(str(Decimal(float('inf'))),
694 str(Decimal('Infinity')))
695 self.assertEqual(str(Decimal(float('-inf'))),
696 str(Decimal('-Infinity')))
697 self.assertEqual(str(Decimal(float('-0.0'))),
698 str(Decimal('-0')))
699 for i in range(200):
700 x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
701 self.assertEqual(x, float(Decimal(x))) # roundtrip
702
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000703 def test_explicit_context_create_decimal(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100704 Decimal = self.decimal.Decimal
705 InvalidOperation = self.decimal.InvalidOperation
706 Rounded = self.decimal.Rounded
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000707
Stefan Krah1919b7e2012-03-21 18:25:23 +0100708 nc = copy.copy(self.decimal.getcontext())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000709 nc.prec = 3
710
711 # empty
Raymond Hettingerfed52962004-07-14 15:41:57 +0000712 d = Decimal()
713 self.assertEqual(str(d), '0')
714 d = nc.create_decimal()
715 self.assertEqual(str(d), '0')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000716
717 # from None
718 self.assertRaises(TypeError, nc.create_decimal, None)
719
720 # from int
721 d = nc.create_decimal(456)
Ezio Melottie9615932010-01-24 19:26:24 +0000722 self.assertIsInstance(d, Decimal)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000723 self.assertEqual(nc.create_decimal(45678),
724 nc.create_decimal('457E+2'))
725
726 # from string
727 d = Decimal('456789')
728 self.assertEqual(str(d), '456789')
729 d = nc.create_decimal('456789')
730 self.assertEqual(str(d), '4.57E+5')
Christian Heimesa62da1d2008-01-12 19:39:10 +0000731 # leading and trailing whitespace should result in a NaN;
732 # spaces are already checked in Cowlishaw's test-suite, so
733 # here we just check that a trailing newline results in a NaN
734 self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000735
736 # from tuples
737 d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
738 self.assertEqual(str(d), '-4.34913534E-17')
739 d = nc.create_decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
740 self.assertEqual(str(d), '-4.35E-17')
741
742 # from Decimal
743 prevdec = Decimal(500000123)
744 d = Decimal(prevdec)
745 self.assertEqual(str(d), '500000123')
746 d = nc.create_decimal(prevdec)
747 self.assertEqual(str(d), '5.00E+8')
748
Stefan Krah1919b7e2012-03-21 18:25:23 +0100749 # more integers
750 nc.prec = 28
751 nc.traps[InvalidOperation] = True
752
753 for v in [-2**63-1, -2**63, -2**31-1, -2**31, 0,
754 2**31-1, 2**31, 2**63-1, 2**63]:
755 d = nc.create_decimal(v)
756 self.assertTrue(isinstance(d, Decimal))
757 self.assertEqual(int(d), v)
758
759 nc.prec = 3
760 nc.traps[Rounded] = True
761 self.assertRaises(Rounded, nc.create_decimal, 1234)
762
763 # from string
764 nc.prec = 28
765 self.assertEqual(str(nc.create_decimal('0E-017')), '0E-17')
766 self.assertEqual(str(nc.create_decimal('45')), '45')
767 self.assertEqual(str(nc.create_decimal('-Inf')), '-Infinity')
768 self.assertEqual(str(nc.create_decimal('NaN123')), 'NaN123')
769
770 # invalid arguments
771 self.assertRaises(InvalidOperation, nc.create_decimal, "xyz")
772 self.assertRaises(ValueError, nc.create_decimal, (1, "xyz", -25))
773 self.assertRaises(TypeError, nc.create_decimal, "1234", "5678")
774
775 # too many NaN payload digits
776 nc.prec = 3
777 self.assertRaises(InvalidOperation, nc.create_decimal, 'NaN12345')
778 self.assertRaises(InvalidOperation, nc.create_decimal,
779 Decimal('NaN12345'))
780
781 nc.traps[InvalidOperation] = False
782 self.assertEqual(str(nc.create_decimal('NaN12345')), 'NaN')
783 self.assertTrue(nc.flags[InvalidOperation])
784
785 nc.flags[InvalidOperation] = False
786 self.assertEqual(str(nc.create_decimal(Decimal('NaN12345'))), 'NaN')
787 self.assertTrue(nc.flags[InvalidOperation])
788
789 def test_explicit_context_create_from_float(self):
790
791 Decimal = self.decimal.Decimal
792
793 nc = self.decimal.Context()
794 r = nc.create_decimal(0.1)
795 self.assertEqual(type(r), Decimal)
796 self.assertEqual(str(r), '0.1000000000000000055511151231')
797 self.assertTrue(nc.create_decimal(float('nan')).is_qnan())
798 self.assertTrue(nc.create_decimal(float('inf')).is_infinite())
799 self.assertTrue(nc.create_decimal(float('-inf')).is_infinite())
800 self.assertEqual(str(nc.create_decimal(float('nan'))),
801 str(nc.create_decimal('NaN')))
802 self.assertEqual(str(nc.create_decimal(float('inf'))),
803 str(nc.create_decimal('Infinity')))
804 self.assertEqual(str(nc.create_decimal(float('-inf'))),
805 str(nc.create_decimal('-Infinity')))
806 self.assertEqual(str(nc.create_decimal(float('-0.0'))),
807 str(nc.create_decimal('-0')))
808 nc.prec = 100
809 for i in range(200):
810 x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
811 self.assertEqual(x, float(nc.create_decimal(x))) # roundtrip
812
Mark Dickinson345adc42009-08-02 10:14:23 +0000813 def test_unicode_digits(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100814 Decimal = self.decimal.Decimal
815
Mark Dickinson345adc42009-08-02 10:14:23 +0000816 test_values = {
817 '\uff11': '1',
818 '\u0660.\u0660\u0663\u0667\u0662e-\u0663' : '0.0000372',
819 '-nan\u0c68\u0c6a\u0c66\u0c66' : '-NaN2400',
820 }
821 for input, expected in test_values.items():
822 self.assertEqual(str(Decimal(input)), expected)
823
Stefan Krah1919b7e2012-03-21 18:25:23 +0100824class CExplicitConstructionTest(ExplicitConstructionTest):
825 decimal = C
826class PyExplicitConstructionTest(ExplicitConstructionTest):
827 decimal = P
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000828
Stefan Krah1919b7e2012-03-21 18:25:23 +0100829class ImplicitConstructionTest(unittest.TestCase):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000830 '''Unit tests for Implicit Construction cases of Decimal.'''
831
832 def test_implicit_from_None(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100833 Decimal = self.decimal.Decimal
834 self.assertRaises(TypeError, eval, 'Decimal(5) + None', locals())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000835
836 def test_implicit_from_int(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100837 Decimal = self.decimal.Decimal
838
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000839 #normal
840 self.assertEqual(str(Decimal(5) + 45), '50')
841 #exceeding precision
842 self.assertEqual(Decimal(5) + 123456789000, Decimal(123456789000))
843
844 def test_implicit_from_string(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100845 Decimal = self.decimal.Decimal
846 self.assertRaises(TypeError, eval, 'Decimal(5) + "3"', locals())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000847
848 def test_implicit_from_float(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100849 Decimal = self.decimal.Decimal
850 self.assertRaises(TypeError, eval, 'Decimal(5) + 2.2', locals())
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000851
852 def test_implicit_from_Decimal(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100853 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000854 self.assertEqual(Decimal(5) + Decimal(45), Decimal(50))
855
Raymond Hettinger267b8682005-03-27 10:47:39 +0000856 def test_rop(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100857 Decimal = self.decimal.Decimal
858
Raymond Hettinger267b8682005-03-27 10:47:39 +0000859 # Allow other classes to be trained to interact with Decimals
860 class E:
861 def __divmod__(self, other):
862 return 'divmod ' + str(other)
863 def __rdivmod__(self, other):
864 return str(other) + ' rdivmod'
865 def __lt__(self, other):
866 return 'lt ' + str(other)
867 def __gt__(self, other):
868 return 'gt ' + str(other)
869 def __le__(self, other):
870 return 'le ' + str(other)
871 def __ge__(self, other):
872 return 'ge ' + str(other)
873 def __eq__(self, other):
874 return 'eq ' + str(other)
875 def __ne__(self, other):
876 return 'ne ' + str(other)
877
878 self.assertEqual(divmod(E(), Decimal(10)), 'divmod 10')
879 self.assertEqual(divmod(Decimal(10), E()), '10 rdivmod')
880 self.assertEqual(eval('Decimal(10) < E()'), 'gt 10')
881 self.assertEqual(eval('Decimal(10) > E()'), 'lt 10')
882 self.assertEqual(eval('Decimal(10) <= E()'), 'ge 10')
883 self.assertEqual(eval('Decimal(10) >= E()'), 'le 10')
884 self.assertEqual(eval('Decimal(10) == E()'), 'eq 10')
885 self.assertEqual(eval('Decimal(10) != E()'), 'ne 10')
886
887 # insert operator methods and then exercise them
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000888 oplist = [
889 ('+', '__add__', '__radd__'),
890 ('-', '__sub__', '__rsub__'),
891 ('*', '__mul__', '__rmul__'),
Thomas Woutersdcc6d322006-04-21 11:30:52 +0000892 ('/', '__truediv__', '__rtruediv__'),
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000893 ('%', '__mod__', '__rmod__'),
894 ('//', '__floordiv__', '__rfloordiv__'),
895 ('**', '__pow__', '__rpow__')
896 ]
Raymond Hettinger267b8682005-03-27 10:47:39 +0000897
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000898 for sym, lop, rop in oplist:
Raymond Hettinger267b8682005-03-27 10:47:39 +0000899 setattr(E, lop, lambda self, other: 'str' + lop + str(other))
900 setattr(E, rop, lambda self, other: str(other) + rop + 'str')
901 self.assertEqual(eval('E()' + sym + 'Decimal(10)'),
902 'str' + lop + '10')
903 self.assertEqual(eval('Decimal(10)' + sym + 'E()'),
904 '10' + rop + 'str')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +0000905
Stefan Krah1919b7e2012-03-21 18:25:23 +0100906class CImplicitConstructionTest(ImplicitConstructionTest):
907 decimal = C
908class PyImplicitConstructionTest(ImplicitConstructionTest):
909 decimal = P
Mark Dickinson79f52032009-03-17 23:12:51 +0000910
Stefan Krah1919b7e2012-03-21 18:25:23 +0100911class FormatTest(unittest.TestCase):
Christian Heimesf16baeb2008-02-29 14:57:44 +0000912 '''Unit tests for the format function.'''
913 def test_formatting(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +0100914 Decimal = self.decimal.Decimal
915
Christian Heimesf16baeb2008-02-29 14:57:44 +0000916 # triples giving a format, a Decimal, and the expected result
917 test_values = [
918 ('e', '0E-15', '0e-15'),
919 ('e', '2.3E-15', '2.3e-15'),
920 ('e', '2.30E+2', '2.30e+2'), # preserve significant zeros
921 ('e', '2.30000E-15', '2.30000e-15'),
922 ('e', '1.23456789123456789e40', '1.23456789123456789e+40'),
923 ('e', '1.5', '1.5e+0'),
924 ('e', '0.15', '1.5e-1'),
925 ('e', '0.015', '1.5e-2'),
926 ('e', '0.0000000000015', '1.5e-12'),
927 ('e', '15.0', '1.50e+1'),
928 ('e', '-15', '-1.5e+1'),
929 ('e', '0', '0e+0'),
930 ('e', '0E1', '0e+1'),
931 ('e', '0.0', '0e-1'),
932 ('e', '0.00', '0e-2'),
933 ('.6e', '0E-15', '0.000000e-9'),
934 ('.6e', '0', '0.000000e+6'),
935 ('.6e', '9.999999', '9.999999e+0'),
936 ('.6e', '9.9999999', '1.000000e+1'),
937 ('.6e', '-1.23e5', '-1.230000e+5'),
938 ('.6e', '1.23456789e-3', '1.234568e-3'),
939 ('f', '0', '0'),
940 ('f', '0.0', '0.0'),
941 ('f', '0E-2', '0.00'),
942 ('f', '0.00E-8', '0.0000000000'),
943 ('f', '0E1', '0'), # loses exponent information
944 ('f', '3.2E1', '32'),
945 ('f', '3.2E2', '320'),
946 ('f', '3.20E2', '320'),
947 ('f', '3.200E2', '320.0'),
948 ('f', '3.2E-6', '0.0000032'),
949 ('.6f', '0E-15', '0.000000'), # all zeros treated equally
950 ('.6f', '0E1', '0.000000'),
951 ('.6f', '0', '0.000000'),
952 ('.0f', '0', '0'), # no decimal point
953 ('.0f', '0e-2', '0'),
954 ('.0f', '3.14159265', '3'),
955 ('.1f', '3.14159265', '3.1'),
956 ('.4f', '3.14159265', '3.1416'),
957 ('.6f', '3.14159265', '3.141593'),
958 ('.7f', '3.14159265', '3.1415926'), # round-half-even!
959 ('.8f', '3.14159265', '3.14159265'),
960 ('.9f', '3.14159265', '3.141592650'),
961
962 ('g', '0', '0'),
963 ('g', '0.0', '0.0'),
964 ('g', '0E1', '0e+1'),
965 ('G', '0E1', '0E+1'),
966 ('g', '0E-5', '0.00000'),
967 ('g', '0E-6', '0.000000'),
968 ('g', '0E-7', '0e-7'),
969 ('g', '-0E2', '-0e+2'),
970 ('.0g', '3.14159265', '3'), # 0 sig fig -> 1 sig fig
Stefan Krah1919b7e2012-03-21 18:25:23 +0100971 ('.0n', '3.14159265', '3'), # same for 'n'
Christian Heimesf16baeb2008-02-29 14:57:44 +0000972 ('.1g', '3.14159265', '3'),
973 ('.2g', '3.14159265', '3.1'),
974 ('.5g', '3.14159265', '3.1416'),
975 ('.7g', '3.14159265', '3.141593'),
976 ('.8g', '3.14159265', '3.1415926'), # round-half-even!
977 ('.9g', '3.14159265', '3.14159265'),
978 ('.10g', '3.14159265', '3.14159265'), # don't pad
979
980 ('%', '0E1', '0%'),
981 ('%', '0E0', '0%'),
982 ('%', '0E-1', '0%'),
983 ('%', '0E-2', '0%'),
984 ('%', '0E-3', '0.0%'),
985 ('%', '0E-4', '0.00%'),
986
987 ('.3%', '0', '0.000%'), # all zeros treated equally
988 ('.3%', '0E10', '0.000%'),
989 ('.3%', '0E-10', '0.000%'),
990 ('.3%', '2.34', '234.000%'),
991 ('.3%', '1.234567', '123.457%'),
992 ('.0%', '1.23', '123%'),
993
994 ('e', 'NaN', 'NaN'),
995 ('f', '-NaN123', '-NaN123'),
996 ('+g', 'NaN456', '+NaN456'),
997 ('.3e', 'Inf', 'Infinity'),
998 ('.16f', '-Inf', '-Infinity'),
999 ('.0g', '-sNaN', '-sNaN'),
1000
1001 ('', '1.00', '1.00'),
Mark Dickinsonad416342009-03-17 18:10:15 +00001002
Mark Dickinson79f52032009-03-17 23:12:51 +00001003 # test alignment and padding
Mark Dickinson46ab5d02009-09-08 20:22:46 +00001004 ('6', '123', ' 123'),
Mark Dickinsonad416342009-03-17 18:10:15 +00001005 ('<6', '123', '123 '),
1006 ('>6', '123', ' 123'),
1007 ('^6', '123', ' 123 '),
1008 ('=+6', '123', '+ 123'),
Mark Dickinson79f52032009-03-17 23:12:51 +00001009 ('#<10', 'NaN', 'NaN#######'),
1010 ('#<10', '-4.3', '-4.3######'),
1011 ('#<+10', '0.0130', '+0.0130###'),
1012 ('#< 10', '0.0130', ' 0.0130###'),
1013 ('@>10', '-Inf', '@-Infinity'),
1014 ('#>5', '-Inf', '-Infinity'),
1015 ('?^5', '123', '?123?'),
1016 ('%^6', '123', '%123%%'),
1017 (' ^6', '-45.6', '-45.6 '),
1018 ('/=10', '-45.6', '-/////45.6'),
1019 ('/=+10', '45.6', '+/////45.6'),
1020 ('/= 10', '45.6', ' /////45.6'),
Stefan Krah6edda142013-05-29 15:45:38 +02001021 ('\x00=10', '-inf', '-\x00Infinity'),
1022 ('\x00^16', '-inf', '\x00\x00\x00-Infinity\x00\x00\x00\x00'),
1023 ('\x00>10', '1.2345', '\x00\x00\x00\x001.2345'),
1024 ('\x00<10', '1.2345', '1.2345\x00\x00\x00\x00'),
Mark Dickinson79f52032009-03-17 23:12:51 +00001025
1026 # thousands separator
1027 (',', '1234567', '1,234,567'),
1028 (',', '123456', '123,456'),
1029 (',', '12345', '12,345'),
1030 (',', '1234', '1,234'),
1031 (',', '123', '123'),
1032 (',', '12', '12'),
1033 (',', '1', '1'),
1034 (',', '0', '0'),
1035 (',', '-1234567', '-1,234,567'),
1036 (',', '-123456', '-123,456'),
1037 ('7,', '123456', '123,456'),
Mark Dickinson46ab5d02009-09-08 20:22:46 +00001038 ('8,', '123456', ' 123,456'),
Mark Dickinson79f52032009-03-17 23:12:51 +00001039 ('08,', '123456', '0,123,456'), # special case: extra 0 needed
1040 ('+08,', '123456', '+123,456'), # but not if there's a sign
1041 (' 08,', '123456', ' 123,456'),
1042 ('08,', '-123456', '-123,456'),
1043 ('+09,', '123456', '+0,123,456'),
1044 # ... with fractional part...
1045 ('07,', '1234.56', '1,234.56'),
1046 ('08,', '1234.56', '1,234.56'),
1047 ('09,', '1234.56', '01,234.56'),
1048 ('010,', '1234.56', '001,234.56'),
1049 ('011,', '1234.56', '0,001,234.56'),
1050 ('012,', '1234.56', '0,001,234.56'),
1051 ('08,.1f', '1234.5', '01,234.5'),
1052 # no thousands separators in fraction part
1053 (',', '1.23456789', '1.23456789'),
1054 (',%', '123.456789', '12,345.6789%'),
1055 (',e', '123456', '1.23456e+5'),
1056 (',E', '123456', '1.23456E+5'),
Mark Dickinson7718d2b2009-09-07 16:21:56 +00001057
1058 # issue 6850
1059 ('a=-7.0', '0.12345', 'aaaa0.1'),
Christian Heimesf16baeb2008-02-29 14:57:44 +00001060 ]
1061 for fmt, d, result in test_values:
1062 self.assertEqual(format(Decimal(d), fmt), result)
1063
Stefan Krah1919b7e2012-03-21 18:25:23 +01001064 # bytes format argument
1065 self.assertRaises(TypeError, Decimal(1).__format__, b'-020')
1066
Mark Dickinson79f52032009-03-17 23:12:51 +00001067 def test_n_format(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001068 Decimal = self.decimal.Decimal
1069
Mark Dickinson79f52032009-03-17 23:12:51 +00001070 try:
1071 from locale import CHAR_MAX
1072 except ImportError:
Zachary Ware9fe6d862013-12-08 00:20:35 -06001073 self.skipTest('locale.CHAR_MAX not available')
Mark Dickinson79f52032009-03-17 23:12:51 +00001074
Stefan Krah1919b7e2012-03-21 18:25:23 +01001075 def make_grouping(lst):
1076 return ''.join([chr(x) for x in lst]) if self.decimal == C else lst
1077
1078 def get_fmt(x, override=None, fmt='n'):
1079 if self.decimal == C:
1080 return Decimal(x).__format__(fmt, override)
1081 else:
1082 return Decimal(x).__format__(fmt, _localeconv=override)
1083
Mark Dickinson79f52032009-03-17 23:12:51 +00001084 # Set up some localeconv-like dictionaries
1085 en_US = {
1086 'decimal_point' : '.',
Stefan Krah1919b7e2012-03-21 18:25:23 +01001087 'grouping' : make_grouping([3, 3, 0]),
1088 'thousands_sep' : ','
Mark Dickinson79f52032009-03-17 23:12:51 +00001089 }
1090
1091 fr_FR = {
1092 'decimal_point' : ',',
Stefan Krah1919b7e2012-03-21 18:25:23 +01001093 'grouping' : make_grouping([CHAR_MAX]),
Mark Dickinson79f52032009-03-17 23:12:51 +00001094 'thousands_sep' : ''
1095 }
1096
1097 ru_RU = {
1098 'decimal_point' : ',',
Stefan Krah1919b7e2012-03-21 18:25:23 +01001099 'grouping': make_grouping([3, 3, 0]),
Mark Dickinson79f52032009-03-17 23:12:51 +00001100 'thousands_sep' : ' '
1101 }
1102
1103 crazy = {
1104 'decimal_point' : '&',
Stefan Krah1919b7e2012-03-21 18:25:23 +01001105 'grouping': make_grouping([1, 4, 2, CHAR_MAX]),
Mark Dickinson79f52032009-03-17 23:12:51 +00001106 'thousands_sep' : '-'
1107 }
1108
Stefan Krah1919b7e2012-03-21 18:25:23 +01001109 dotsep_wide = {
1110 'decimal_point' : b'\xc2\xbf'.decode('utf-8'),
1111 'grouping': make_grouping([3, 3, 0]),
1112 'thousands_sep' : b'\xc2\xb4'.decode('utf-8')
1113 }
Mark Dickinson79f52032009-03-17 23:12:51 +00001114
1115 self.assertEqual(get_fmt(Decimal('12.7'), en_US), '12.7')
1116 self.assertEqual(get_fmt(Decimal('12.7'), fr_FR), '12,7')
1117 self.assertEqual(get_fmt(Decimal('12.7'), ru_RU), '12,7')
1118 self.assertEqual(get_fmt(Decimal('12.7'), crazy), '1-2&7')
1119
1120 self.assertEqual(get_fmt(123456789, en_US), '123,456,789')
1121 self.assertEqual(get_fmt(123456789, fr_FR), '123456789')
1122 self.assertEqual(get_fmt(123456789, ru_RU), '123 456 789')
1123 self.assertEqual(get_fmt(1234567890123, crazy), '123456-78-9012-3')
1124
1125 self.assertEqual(get_fmt(123456789, en_US, '.6n'), '1.23457e+8')
1126 self.assertEqual(get_fmt(123456789, fr_FR, '.6n'), '1,23457e+8')
1127 self.assertEqual(get_fmt(123456789, ru_RU, '.6n'), '1,23457e+8')
1128 self.assertEqual(get_fmt(123456789, crazy, '.6n'), '1&23457e+8')
1129
Mark Dickinson7303b592009-03-18 08:25:36 +00001130 # zero padding
1131 self.assertEqual(get_fmt(1234, fr_FR, '03n'), '1234')
1132 self.assertEqual(get_fmt(1234, fr_FR, '04n'), '1234')
1133 self.assertEqual(get_fmt(1234, fr_FR, '05n'), '01234')
1134 self.assertEqual(get_fmt(1234, fr_FR, '06n'), '001234')
1135
1136 self.assertEqual(get_fmt(12345, en_US, '05n'), '12,345')
1137 self.assertEqual(get_fmt(12345, en_US, '06n'), '12,345')
1138 self.assertEqual(get_fmt(12345, en_US, '07n'), '012,345')
1139 self.assertEqual(get_fmt(12345, en_US, '08n'), '0,012,345')
1140 self.assertEqual(get_fmt(12345, en_US, '09n'), '0,012,345')
1141 self.assertEqual(get_fmt(12345, en_US, '010n'), '00,012,345')
1142
1143 self.assertEqual(get_fmt(123456, crazy, '06n'), '1-2345-6')
1144 self.assertEqual(get_fmt(123456, crazy, '07n'), '1-2345-6')
1145 self.assertEqual(get_fmt(123456, crazy, '08n'), '1-2345-6')
1146 self.assertEqual(get_fmt(123456, crazy, '09n'), '01-2345-6')
1147 self.assertEqual(get_fmt(123456, crazy, '010n'), '0-01-2345-6')
1148 self.assertEqual(get_fmt(123456, crazy, '011n'), '0-01-2345-6')
1149 self.assertEqual(get_fmt(123456, crazy, '012n'), '00-01-2345-6')
1150 self.assertEqual(get_fmt(123456, crazy, '013n'), '000-01-2345-6')
1151
Stefan Krah1919b7e2012-03-21 18:25:23 +01001152 # wide char separator and decimal point
1153 self.assertEqual(get_fmt(Decimal('-1.5'), dotsep_wide, '020n'),
1154 '-0\u00b4000\u00b4000\u00b4000\u00b4001\u00bf5')
Mark Dickinson79f52032009-03-17 23:12:51 +00001155
Stefan Krah6fb204a2012-09-28 16:18:54 +02001156 @run_with_locale('LC_ALL', 'ps_AF')
Stefan Krah1919b7e2012-03-21 18:25:23 +01001157 def test_wide_char_separator_decimal_point(self):
1158 # locale with wide char separator and decimal point
Stefan Krah8a491a82012-09-28 17:17:11 +02001159 import locale
Stefan Krah1919b7e2012-03-21 18:25:23 +01001160 Decimal = self.decimal.Decimal
1161
Stefan Krah8a491a82012-09-28 17:17:11 +02001162 decimal_point = locale.localeconv()['decimal_point']
1163 thousands_sep = locale.localeconv()['thousands_sep']
Zachary Ware9fe6d862013-12-08 00:20:35 -06001164 if decimal_point != '\u066b':
1165 self.skipTest('inappropriate decimal point separator'
Zachary Ware0f533ac2013-12-12 10:32:16 -06001166 '({!a} not {!a})'.format(decimal_point, '\u066b'))
Zachary Ware9fe6d862013-12-08 00:20:35 -06001167 if thousands_sep != '\u066c':
1168 self.skipTest('inappropriate thousands separator'
Zachary Ware0f533ac2013-12-12 10:32:16 -06001169 '({!a} not {!a})'.format(thousands_sep, '\u066c'))
Stefan Krah8a491a82012-09-28 17:17:11 +02001170
Stefan Krah1919b7e2012-03-21 18:25:23 +01001171 self.assertEqual(format(Decimal('100000000.123'), 'n'),
1172 '100\u066c000\u066c000\u066b123')
Stefan Krah1919b7e2012-03-21 18:25:23 +01001173
1174class CFormatTest(FormatTest):
1175 decimal = C
1176class PyFormatTest(FormatTest):
1177 decimal = P
1178
1179class ArithmeticOperatorsTest(unittest.TestCase):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001180 '''Unit tests for all arithmetic operators, binary and unary.'''
1181
1182 def test_addition(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001183 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001184
1185 d1 = Decimal('-11.1')
1186 d2 = Decimal('22.2')
1187
1188 #two Decimals
1189 self.assertEqual(d1+d2, Decimal('11.1'))
1190 self.assertEqual(d2+d1, Decimal('11.1'))
1191
1192 #with other type, left
1193 c = d1 + 5
1194 self.assertEqual(c, Decimal('-6.1'))
1195 self.assertEqual(type(c), type(d1))
1196
1197 #with other type, right
1198 c = 5 + d1
1199 self.assertEqual(c, Decimal('-6.1'))
1200 self.assertEqual(type(c), type(d1))
1201
1202 #inline with decimal
1203 d1 += d2
1204 self.assertEqual(d1, Decimal('11.1'))
1205
1206 #inline with other type
1207 d1 += 5
1208 self.assertEqual(d1, Decimal('16.1'))
1209
1210 def test_subtraction(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001211 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001212
1213 d1 = Decimal('-11.1')
1214 d2 = Decimal('22.2')
1215
1216 #two Decimals
1217 self.assertEqual(d1-d2, Decimal('-33.3'))
1218 self.assertEqual(d2-d1, Decimal('33.3'))
1219
1220 #with other type, left
1221 c = d1 - 5
1222 self.assertEqual(c, Decimal('-16.1'))
1223 self.assertEqual(type(c), type(d1))
1224
1225 #with other type, right
1226 c = 5 - d1
1227 self.assertEqual(c, Decimal('16.1'))
1228 self.assertEqual(type(c), type(d1))
1229
1230 #inline with decimal
1231 d1 -= d2
1232 self.assertEqual(d1, Decimal('-33.3'))
1233
1234 #inline with other type
1235 d1 -= 5
1236 self.assertEqual(d1, Decimal('-38.3'))
1237
1238 def test_multiplication(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001239 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001240
1241 d1 = Decimal('-5')
1242 d2 = Decimal('3')
1243
1244 #two Decimals
1245 self.assertEqual(d1*d2, Decimal('-15'))
1246 self.assertEqual(d2*d1, Decimal('-15'))
1247
1248 #with other type, left
1249 c = d1 * 5
1250 self.assertEqual(c, Decimal('-25'))
1251 self.assertEqual(type(c), type(d1))
1252
1253 #with other type, right
1254 c = 5 * d1
1255 self.assertEqual(c, Decimal('-25'))
1256 self.assertEqual(type(c), type(d1))
1257
1258 #inline with decimal
1259 d1 *= d2
1260 self.assertEqual(d1, Decimal('-15'))
1261
1262 #inline with other type
1263 d1 *= 5
1264 self.assertEqual(d1, Decimal('-75'))
1265
1266 def test_division(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001267 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001268
1269 d1 = Decimal('-5')
1270 d2 = Decimal('2')
1271
1272 #two Decimals
1273 self.assertEqual(d1/d2, Decimal('-2.5'))
1274 self.assertEqual(d2/d1, Decimal('-0.4'))
1275
1276 #with other type, left
1277 c = d1 / 4
1278 self.assertEqual(c, Decimal('-1.25'))
1279 self.assertEqual(type(c), type(d1))
1280
1281 #with other type, right
1282 c = 4 / d1
1283 self.assertEqual(c, Decimal('-0.8'))
1284 self.assertEqual(type(c), type(d1))
1285
1286 #inline with decimal
1287 d1 /= d2
1288 self.assertEqual(d1, Decimal('-2.5'))
1289
1290 #inline with other type
1291 d1 /= 4
1292 self.assertEqual(d1, Decimal('-0.625'))
1293
1294 def test_floor_division(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001295 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001296
1297 d1 = Decimal('5')
1298 d2 = Decimal('2')
1299
1300 #two Decimals
1301 self.assertEqual(d1//d2, Decimal('2'))
1302 self.assertEqual(d2//d1, Decimal('0'))
1303
1304 #with other type, left
1305 c = d1 // 4
1306 self.assertEqual(c, Decimal('1'))
1307 self.assertEqual(type(c), type(d1))
1308
1309 #with other type, right
1310 c = 7 // d1
1311 self.assertEqual(c, Decimal('1'))
1312 self.assertEqual(type(c), type(d1))
1313
1314 #inline with decimal
1315 d1 //= d2
1316 self.assertEqual(d1, Decimal('2'))
1317
1318 #inline with other type
1319 d1 //= 2
1320 self.assertEqual(d1, Decimal('1'))
1321
1322 def test_powering(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001323 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001324
1325 d1 = Decimal('5')
1326 d2 = Decimal('2')
1327
1328 #two Decimals
1329 self.assertEqual(d1**d2, Decimal('25'))
1330 self.assertEqual(d2**d1, Decimal('32'))
1331
1332 #with other type, left
1333 c = d1 ** 4
1334 self.assertEqual(c, Decimal('625'))
1335 self.assertEqual(type(c), type(d1))
1336
1337 #with other type, right
1338 c = 7 ** d1
1339 self.assertEqual(c, Decimal('16807'))
1340 self.assertEqual(type(c), type(d1))
1341
1342 #inline with decimal
1343 d1 **= d2
1344 self.assertEqual(d1, Decimal('25'))
1345
1346 #inline with other type
1347 d1 **= 4
1348 self.assertEqual(d1, Decimal('390625'))
1349
1350 def test_module(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001351 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001352
1353 d1 = Decimal('5')
1354 d2 = Decimal('2')
1355
1356 #two Decimals
1357 self.assertEqual(d1%d2, Decimal('1'))
1358 self.assertEqual(d2%d1, Decimal('2'))
1359
1360 #with other type, left
1361 c = d1 % 4
1362 self.assertEqual(c, Decimal('1'))
1363 self.assertEqual(type(c), type(d1))
1364
1365 #with other type, right
1366 c = 7 % d1
1367 self.assertEqual(c, Decimal('2'))
1368 self.assertEqual(type(c), type(d1))
1369
1370 #inline with decimal
1371 d1 %= d2
1372 self.assertEqual(d1, Decimal('1'))
1373
1374 #inline with other type
1375 d1 %= 4
1376 self.assertEqual(d1, Decimal('1'))
1377
1378 def test_floor_div_module(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001379 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001380
1381 d1 = Decimal('5')
1382 d2 = Decimal('2')
1383
1384 #two Decimals
1385 (p, q) = divmod(d1, d2)
1386 self.assertEqual(p, Decimal('2'))
1387 self.assertEqual(q, Decimal('1'))
1388 self.assertEqual(type(p), type(d1))
1389 self.assertEqual(type(q), type(d1))
1390
1391 #with other type, left
1392 (p, q) = divmod(d1, 4)
1393 self.assertEqual(p, Decimal('1'))
1394 self.assertEqual(q, Decimal('1'))
1395 self.assertEqual(type(p), type(d1))
1396 self.assertEqual(type(q), type(d1))
1397
1398 #with other type, right
1399 (p, q) = divmod(7, d1)
1400 self.assertEqual(p, Decimal('1'))
1401 self.assertEqual(q, Decimal('2'))
1402 self.assertEqual(type(p), type(d1))
1403 self.assertEqual(type(q), type(d1))
1404
1405 def test_unary_operators(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001406 Decimal = self.decimal.Decimal
1407
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001408 self.assertEqual(+Decimal(45), Decimal(+45)) # +
1409 self.assertEqual(-Decimal(45), Decimal(-45)) # -
1410 self.assertEqual(abs(Decimal(45)), abs(Decimal(-45))) # abs
1411
Christian Heimes77c02eb2008-02-09 02:18:51 +00001412 def test_nan_comparisons(self):
Mark Dickinsonac256ab2010-04-03 11:08:14 +00001413 # comparisons involving signaling nans signal InvalidOperation
1414
1415 # order comparisons (<, <=, >, >=) involving only quiet nans
1416 # also signal InvalidOperation
1417
1418 # equality comparisons (==, !=) involving only quiet nans
1419 # don't signal, but return False or True respectively.
Stefan Krah1919b7e2012-03-21 18:25:23 +01001420 Decimal = self.decimal.Decimal
1421 InvalidOperation = self.decimal.InvalidOperation
1422 localcontext = self.decimal.localcontext
Mark Dickinsonac256ab2010-04-03 11:08:14 +00001423
Christian Heimes77c02eb2008-02-09 02:18:51 +00001424 n = Decimal('NaN')
1425 s = Decimal('sNaN')
1426 i = Decimal('Inf')
1427 f = Decimal('2')
Mark Dickinsonac256ab2010-04-03 11:08:14 +00001428
1429 qnan_pairs = (n, n), (n, i), (i, n), (n, f), (f, n)
1430 snan_pairs = (s, n), (n, s), (s, i), (i, s), (s, f), (f, s), (s, s)
1431 order_ops = operator.lt, operator.le, operator.gt, operator.ge
1432 equality_ops = operator.eq, operator.ne
1433
1434 # results when InvalidOperation is not trapped
1435 for x, y in qnan_pairs + snan_pairs:
1436 for op in order_ops + equality_ops:
1437 got = op(x, y)
1438 expected = True if op is operator.ne else False
1439 self.assertIs(expected, got,
1440 "expected {0!r} for operator.{1}({2!r}, {3!r}); "
1441 "got {4!r}".format(
1442 expected, op.__name__, x, y, got))
1443
1444 # repeat the above, but this time trap the InvalidOperation
1445 with localcontext() as ctx:
1446 ctx.traps[InvalidOperation] = 1
1447
1448 for x, y in qnan_pairs:
1449 for op in equality_ops:
1450 got = op(x, y)
1451 expected = True if op is operator.ne else False
1452 self.assertIs(expected, got,
1453 "expected {0!r} for "
1454 "operator.{1}({2!r}, {3!r}); "
1455 "got {4!r}".format(
1456 expected, op.__name__, x, y, got))
1457
1458 for x, y in snan_pairs:
1459 for op in equality_ops:
1460 self.assertRaises(InvalidOperation, operator.eq, x, y)
1461 self.assertRaises(InvalidOperation, operator.ne, x, y)
1462
1463 for x, y in qnan_pairs + snan_pairs:
1464 for op in order_ops:
1465 self.assertRaises(InvalidOperation, op, x, y)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001466
Mark Dickinson84230a12010-02-18 14:49:50 +00001467 def test_copy_sign(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001468 Decimal = self.decimal.Decimal
Mark Dickinson84230a12010-02-18 14:49:50 +00001469
Stefan Krah1919b7e2012-03-21 18:25:23 +01001470 d = Decimal(1).copy_sign(Decimal(-2))
Mark Dickinson84230a12010-02-18 14:49:50 +00001471 self.assertEqual(Decimal(1).copy_sign(-2), d)
1472 self.assertRaises(TypeError, Decimal(1).copy_sign, '-2')
1473
Stefan Krah1919b7e2012-03-21 18:25:23 +01001474class CArithmeticOperatorsTest(ArithmeticOperatorsTest):
1475 decimal = C
1476class PyArithmeticOperatorsTest(ArithmeticOperatorsTest):
1477 decimal = P
1478
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001479# The following are two functions used to test threading in the next class
1480
1481def thfunc1(cls):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001482 Decimal = cls.decimal.Decimal
1483 InvalidOperation = cls.decimal.InvalidOperation
1484 DivisionByZero = cls.decimal.DivisionByZero
1485 Overflow = cls.decimal.Overflow
1486 Underflow = cls.decimal.Underflow
1487 Inexact = cls.decimal.Inexact
1488 getcontext = cls.decimal.getcontext
1489 localcontext = cls.decimal.localcontext
1490
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001491 d1 = Decimal(1)
1492 d3 = Decimal(3)
Christian Heimesfe337bf2008-03-23 21:54:12 +00001493 test1 = d1/d3
Christian Heimesfe337bf2008-03-23 21:54:12 +00001494
Stefan Krah1919b7e2012-03-21 18:25:23 +01001495 cls.finish1.set()
1496 cls.synchro.wait()
1497
1498 test2 = d1/d3
1499 with localcontext() as c2:
1500 cls.assertTrue(c2.flags[Inexact])
1501 cls.assertRaises(DivisionByZero, c2.divide, d1, 0)
1502 cls.assertTrue(c2.flags[DivisionByZero])
1503 with localcontext() as c3:
1504 cls.assertTrue(c3.flags[Inexact])
1505 cls.assertTrue(c3.flags[DivisionByZero])
1506 cls.assertRaises(InvalidOperation, c3.compare, d1, Decimal('sNaN'))
1507 cls.assertTrue(c3.flags[InvalidOperation])
1508 del c3
1509 cls.assertFalse(c2.flags[InvalidOperation])
1510 del c2
1511
1512 cls.assertEqual(test1, Decimal('0.333333333333333333333333'))
1513 cls.assertEqual(test2, Decimal('0.333333333333333333333333'))
1514
1515 c1 = getcontext()
1516 cls.assertTrue(c1.flags[Inexact])
1517 for sig in Overflow, Underflow, DivisionByZero, InvalidOperation:
1518 cls.assertFalse(c1.flags[sig])
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001519
1520def thfunc2(cls):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001521 Decimal = cls.decimal.Decimal
1522 InvalidOperation = cls.decimal.InvalidOperation
1523 DivisionByZero = cls.decimal.DivisionByZero
1524 Overflow = cls.decimal.Overflow
1525 Underflow = cls.decimal.Underflow
1526 Inexact = cls.decimal.Inexact
1527 getcontext = cls.decimal.getcontext
1528 localcontext = cls.decimal.localcontext
1529
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001530 d1 = Decimal(1)
1531 d3 = Decimal(3)
Christian Heimesfe337bf2008-03-23 21:54:12 +00001532 test1 = d1/d3
Stefan Krah1919b7e2012-03-21 18:25:23 +01001533
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001534 thiscontext = getcontext()
1535 thiscontext.prec = 18
Christian Heimesfe337bf2008-03-23 21:54:12 +00001536 test2 = d1/d3
Stefan Krah1919b7e2012-03-21 18:25:23 +01001537
1538 with localcontext() as c2:
1539 cls.assertTrue(c2.flags[Inexact])
1540 cls.assertRaises(Overflow, c2.multiply, Decimal('1e425000000'), 999)
1541 cls.assertTrue(c2.flags[Overflow])
1542 with localcontext(thiscontext) as c3:
1543 cls.assertTrue(c3.flags[Inexact])
1544 cls.assertFalse(c3.flags[Overflow])
1545 c3.traps[Underflow] = True
1546 cls.assertRaises(Underflow, c3.divide, Decimal('1e-425000000'), 999)
1547 cls.assertTrue(c3.flags[Underflow])
1548 del c3
1549 cls.assertFalse(c2.flags[Underflow])
1550 cls.assertFalse(c2.traps[Underflow])
1551 del c2
1552
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001553 cls.synchro.set()
1554 cls.finish2.set()
Christian Heimesfe337bf2008-03-23 21:54:12 +00001555
Stefan Krah1919b7e2012-03-21 18:25:23 +01001556 cls.assertEqual(test1, Decimal('0.333333333333333333333333'))
Christian Heimesfe337bf2008-03-23 21:54:12 +00001557 cls.assertEqual(test2, Decimal('0.333333333333333333'))
Stefan Krah1919b7e2012-03-21 18:25:23 +01001558
1559 cls.assertFalse(thiscontext.traps[Underflow])
1560 cls.assertTrue(thiscontext.flags[Inexact])
1561 for sig in Overflow, Underflow, DivisionByZero, InvalidOperation:
1562 cls.assertFalse(thiscontext.flags[sig])
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001563
Stefan Krah1919b7e2012-03-21 18:25:23 +01001564class ThreadingTest(unittest.TestCase):
1565 '''Unit tests for thread local contexts in Decimal.'''
Raymond Hettinger7e71fa52004-12-18 19:07:19 +00001566
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001567 # Take care executing this test from IDLE, there's an issue in threading
1568 # that hangs IDLE and I couldn't find it
1569
1570 def test_threading(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001571 DefaultContext = self.decimal.DefaultContext
1572
1573 if self.decimal == C and not self.decimal.HAVE_THREADS:
1574 self.skipTest("compiled without threading")
1575 # Test the "threading isolation" of a Context. Also test changing
1576 # the DefaultContext, which acts as a template for the thread-local
1577 # contexts.
1578 save_prec = DefaultContext.prec
1579 save_emax = DefaultContext.Emax
1580 save_emin = DefaultContext.Emin
1581 DefaultContext.prec = 24
1582 DefaultContext.Emax = 425000000
1583 DefaultContext.Emin = -425000000
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001584
1585 self.synchro = threading.Event()
1586 self.finish1 = threading.Event()
1587 self.finish2 = threading.Event()
1588
1589 th1 = threading.Thread(target=thfunc1, args=(self,))
1590 th2 = threading.Thread(target=thfunc2, args=(self,))
1591
1592 th1.start()
1593 th2.start()
1594
1595 self.finish1.wait()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001596 self.finish2.wait()
Stefan Krah1919b7e2012-03-21 18:25:23 +01001597
1598 for sig in Signals[self.decimal]:
1599 self.assertFalse(DefaultContext.flags[sig])
1600
1601 DefaultContext.prec = save_prec
1602 DefaultContext.Emax = save_emax
1603 DefaultContext.Emin = save_emin
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001604
Stefan Krah1919b7e2012-03-21 18:25:23 +01001605@unittest.skipUnless(threading, 'threading required')
1606class CThreadingTest(ThreadingTest):
1607 decimal = C
1608@unittest.skipUnless(threading, 'threading required')
1609class PyThreadingTest(ThreadingTest):
1610 decimal = P
Raymond Hettinger7e71fa52004-12-18 19:07:19 +00001611
Stefan Krah1919b7e2012-03-21 18:25:23 +01001612class UsabilityTest(unittest.TestCase):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001613 '''Unit tests for Usability cases of Decimal.'''
1614
1615 def test_comparison_operators(self):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001616
Stefan Krah1919b7e2012-03-21 18:25:23 +01001617 Decimal = self.decimal.Decimal
1618
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001619 da = Decimal('23.42')
1620 db = Decimal('23.42')
1621 dc = Decimal('45')
1622
1623 #two Decimals
Ezio Melotti6607d512010-04-03 14:59:49 +00001624 self.assertGreater(dc, da)
1625 self.assertGreaterEqual(dc, da)
1626 self.assertLess(da, dc)
1627 self.assertLessEqual(da, dc)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001628 self.assertEqual(da, db)
Ezio Melotti6607d512010-04-03 14:59:49 +00001629 self.assertNotEqual(da, dc)
1630 self.assertLessEqual(da, db)
1631 self.assertGreaterEqual(da, db)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001632
1633 #a Decimal and an int
Ezio Melotti6607d512010-04-03 14:59:49 +00001634 self.assertGreater(dc, 23)
1635 self.assertLess(23, dc)
Guido van Rossume61fd5b2007-07-11 12:20:59 +00001636 self.assertEqual(dc, 45)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001637
1638 #a Decimal and uncomparable
Raymond Hettinger0aeac102004-07-05 22:53:03 +00001639 self.assertNotEqual(da, 'ugly')
1640 self.assertNotEqual(da, 32.7)
1641 self.assertNotEqual(da, object())
1642 self.assertNotEqual(da, object)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001643
Raymond Hettinger0aeac102004-07-05 22:53:03 +00001644 # sortable
Guido van Rossumc1f779c2007-07-03 08:25:58 +00001645 a = list(map(Decimal, range(100)))
Raymond Hettinger0aeac102004-07-05 22:53:03 +00001646 b = a[:]
1647 random.shuffle(a)
1648 a.sort()
1649 self.assertEqual(a, b)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001650
Mark Dickinsonac256ab2010-04-03 11:08:14 +00001651 def test_decimal_float_comparison(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001652 Decimal = self.decimal.Decimal
1653
Mark Dickinsonac256ab2010-04-03 11:08:14 +00001654 da = Decimal('0.25')
1655 db = Decimal('3.0')
Ezio Melotti6607d512010-04-03 14:59:49 +00001656 self.assertLess(da, 3.0)
1657 self.assertLessEqual(da, 3.0)
1658 self.assertGreater(db, 0.25)
1659 self.assertGreaterEqual(db, 0.25)
1660 self.assertNotEqual(da, 1.5)
1661 self.assertEqual(da, 0.25)
1662 self.assertGreater(3.0, da)
1663 self.assertGreaterEqual(3.0, da)
1664 self.assertLess(0.25, db)
1665 self.assertLessEqual(0.25, db)
1666 self.assertNotEqual(0.25, db)
1667 self.assertEqual(3.0, db)
1668 self.assertNotEqual(0.1, Decimal('0.1'))
Mark Dickinsonac256ab2010-04-03 11:08:14 +00001669
Stefan Krah1919b7e2012-03-21 18:25:23 +01001670 def test_decimal_complex_comparison(self):
1671 Decimal = self.decimal.Decimal
1672
1673 da = Decimal('0.25')
1674 db = Decimal('3.0')
1675 self.assertNotEqual(da, (1.5+0j))
1676 self.assertNotEqual((1.5+0j), da)
1677 self.assertEqual(da, (0.25+0j))
1678 self.assertEqual((0.25+0j), da)
1679 self.assertEqual((3.0+0j), db)
1680 self.assertEqual(db, (3.0+0j))
1681
1682 self.assertNotEqual(db, (3.0+1j))
1683 self.assertNotEqual((3.0+1j), db)
1684
1685 self.assertIs(db.__lt__(3.0+0j), NotImplemented)
1686 self.assertIs(db.__le__(3.0+0j), NotImplemented)
1687 self.assertIs(db.__gt__(3.0+0j), NotImplemented)
1688 self.assertIs(db.__le__(3.0+0j), NotImplemented)
1689
1690 def test_decimal_fraction_comparison(self):
1691 D = self.decimal.Decimal
1692 F = fractions[self.decimal].Fraction
1693 Context = self.decimal.Context
1694 localcontext = self.decimal.localcontext
1695 InvalidOperation = self.decimal.InvalidOperation
1696
1697
1698 emax = C.MAX_EMAX if C else 999999999
1699 emin = C.MIN_EMIN if C else -999999999
1700 etiny = C.MIN_ETINY if C else -1999999997
1701 c = Context(Emax=emax, Emin=emin)
1702
1703 with localcontext(c):
1704 c.prec = emax
1705 self.assertLess(D(0), F(1,9999999999999999999999999999999999999))
1706 self.assertLess(F(-1,9999999999999999999999999999999999999), D(0))
1707 self.assertLess(F(0,1), D("1e" + str(etiny)))
1708 self.assertLess(D("-1e" + str(etiny)), F(0,1))
1709 self.assertLess(F(0,9999999999999999999999999), D("1e" + str(etiny)))
1710 self.assertLess(D("-1e" + str(etiny)), F(0,9999999999999999999999999))
1711
1712 self.assertEqual(D("0.1"), F(1,10))
1713 self.assertEqual(F(1,10), D("0.1"))
1714
1715 c.prec = 300
1716 self.assertNotEqual(D(1)/3, F(1,3))
1717 self.assertNotEqual(F(1,3), D(1)/3)
1718
1719 self.assertLessEqual(F(120984237, 9999999999), D("9e" + str(emax)))
1720 self.assertGreaterEqual(D("9e" + str(emax)), F(120984237, 9999999999))
1721
1722 self.assertGreater(D('inf'), F(99999999999,123))
1723 self.assertGreater(D('inf'), F(-99999999999,123))
1724 self.assertLess(D('-inf'), F(99999999999,123))
1725 self.assertLess(D('-inf'), F(-99999999999,123))
1726
1727 self.assertRaises(InvalidOperation, D('nan').__gt__, F(-9,123))
1728 self.assertIs(NotImplemented, F(-9,123).__lt__(D('nan')))
1729 self.assertNotEqual(D('nan'), F(-9,123))
1730 self.assertNotEqual(F(-9,123), D('nan'))
1731
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001732 def test_copy_and_deepcopy_methods(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001733 Decimal = self.decimal.Decimal
1734
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001735 d = Decimal('43.24')
1736 c = copy.copy(d)
1737 self.assertEqual(id(c), id(d))
1738 dc = copy.deepcopy(d)
1739 self.assertEqual(id(dc), id(d))
1740
1741 def test_hash_method(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001742
1743 Decimal = self.decimal.Decimal
1744 localcontext = self.decimal.localcontext
1745
Stefan Krahdc817b22010-11-17 11:16:34 +00001746 def hashit(d):
1747 a = hash(d)
1748 b = d.__hash__()
1749 self.assertEqual(a, b)
1750 return a
1751
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001752 #just that it's hashable
Stefan Krahdc817b22010-11-17 11:16:34 +00001753 hashit(Decimal(23))
1754 hashit(Decimal('Infinity'))
1755 hashit(Decimal('-Infinity'))
1756 hashit(Decimal('nan123'))
1757 hashit(Decimal('-NaN'))
Thomas Wouters8ce81f72007-09-20 18:22:40 +00001758
1759 test_values = [Decimal(sign*(2**m + n))
1760 for m in [0, 14, 15, 16, 17, 30, 31,
Stefan Krahdc817b22010-11-17 11:16:34 +00001761 32, 33, 61, 62, 63, 64, 65, 66]
Thomas Wouters8ce81f72007-09-20 18:22:40 +00001762 for n in range(-10, 10)
1763 for sign in [-1, 1]]
1764 test_values.extend([
Stefan Krahdc817b22010-11-17 11:16:34 +00001765 Decimal("-1"), # ==> -2
Thomas Wouters8ce81f72007-09-20 18:22:40 +00001766 Decimal("-0"), # zeros
1767 Decimal("0.00"),
1768 Decimal("-0.000"),
1769 Decimal("0E10"),
1770 Decimal("-0E12"),
1771 Decimal("10.0"), # negative exponent
1772 Decimal("-23.00000"),
1773 Decimal("1230E100"), # positive exponent
1774 Decimal("-4.5678E50"),
1775 # a value for which hash(n) != hash(n % (2**64-1))
1776 # in Python pre-2.6
1777 Decimal(2**64 + 2**32 - 1),
1778 # selection of values which fail with the old (before
1779 # version 2.6) long.__hash__
1780 Decimal("1.634E100"),
1781 Decimal("90.697E100"),
1782 Decimal("188.83E100"),
1783 Decimal("1652.9E100"),
1784 Decimal("56531E100"),
1785 ])
1786
1787 # check that hash(d) == hash(int(d)) for integral values
1788 for value in test_values:
Stefan Krahdc817b22010-11-17 11:16:34 +00001789 self.assertEqual(hashit(value), hashit(int(value)))
Thomas Wouters8ce81f72007-09-20 18:22:40 +00001790
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001791 #the same hash that to an int
Stefan Krahdc817b22010-11-17 11:16:34 +00001792 self.assertEqual(hashit(Decimal(23)), hashit(23))
Raymond Hettingerd325c4b2010-11-21 04:08:28 +00001793 self.assertRaises(TypeError, hash, Decimal('sNaN'))
Stefan Krahdc817b22010-11-17 11:16:34 +00001794 self.assertTrue(hashit(Decimal('Inf')))
1795 self.assertTrue(hashit(Decimal('-Inf')))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001796
Mark Dickinsonac256ab2010-04-03 11:08:14 +00001797 # check that the hashes of a Decimal float match when they
1798 # represent exactly the same values
1799 test_strings = ['inf', '-Inf', '0.0', '-.0e1',
1800 '34.0', '2.5', '112390.625', '-0.515625']
1801 for s in test_strings:
1802 f = float(s)
1803 d = Decimal(s)
Stefan Krahdc817b22010-11-17 11:16:34 +00001804 self.assertEqual(hashit(f), hashit(d))
Mark Dickinsonac256ab2010-04-03 11:08:14 +00001805
Stefan Krah1919b7e2012-03-21 18:25:23 +01001806 with localcontext() as c:
1807 # check that the value of the hash doesn't depend on the
1808 # current context (issue #1757)
1809 x = Decimal("123456789.1")
Christian Heimes2380ac72008-01-09 00:17:24 +00001810
Stefan Krah1919b7e2012-03-21 18:25:23 +01001811 c.prec = 6
1812 h1 = hashit(x)
1813 c.prec = 10
1814 h2 = hashit(x)
1815 c.prec = 16
1816 h3 = hashit(x)
Christian Heimes2380ac72008-01-09 00:17:24 +00001817
Stefan Krah1919b7e2012-03-21 18:25:23 +01001818 self.assertEqual(h1, h2)
1819 self.assertEqual(h1, h3)
1820
1821 c.prec = 10000
1822 x = 1100 ** 1248
1823 self.assertEqual(hashit(Decimal(x)), hashit(x))
Christian Heimes2380ac72008-01-09 00:17:24 +00001824
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001825 def test_min_and_max_methods(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001826 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001827
1828 d1 = Decimal('15.32')
1829 d2 = Decimal('28.5')
1830 l1 = 15
1831 l2 = 28
1832
1833 #between Decimals
Ezio Melotti6607d512010-04-03 14:59:49 +00001834 self.assertIs(min(d1,d2), d1)
1835 self.assertIs(min(d2,d1), d1)
1836 self.assertIs(max(d1,d2), d2)
1837 self.assertIs(max(d2,d1), d2)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001838
Serhiy Storchaka95949422013-08-27 19:40:23 +03001839 #between Decimal and int
Ezio Melotti6607d512010-04-03 14:59:49 +00001840 self.assertIs(min(d1,l2), d1)
1841 self.assertIs(min(l2,d1), d1)
1842 self.assertIs(max(l1,d2), d2)
1843 self.assertIs(max(d2,l1), d2)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001844
1845 def test_as_nonzero(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001846 Decimal = self.decimal.Decimal
1847
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001848 #as false
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001849 self.assertFalse(Decimal(0))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001850 #as true
Benjamin Petersonc9c0f202009-06-30 23:06:06 +00001851 self.assertTrue(Decimal('0.372'))
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001852
1853 def test_tostring_methods(self):
1854 #Test str and repr methods.
Stefan Krah1919b7e2012-03-21 18:25:23 +01001855 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001856
1857 d = Decimal('15.32')
1858 self.assertEqual(str(d), '15.32') # str
Christian Heimes68f5fbe2008-02-14 08:27:37 +00001859 self.assertEqual(repr(d), "Decimal('15.32')") # repr
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001860
1861 def test_tonum_methods(self):
Mark Dickinson5c2db372009-12-05 20:28:34 +00001862 #Test float and int methods.
Stefan Krah1919b7e2012-03-21 18:25:23 +01001863 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001864
1865 d1 = Decimal('66')
1866 d2 = Decimal('15.32')
1867
1868 #int
1869 self.assertEqual(int(d1), 66)
1870 self.assertEqual(int(d2), 15)
1871
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001872 #float
1873 self.assertEqual(float(d1), 66)
1874 self.assertEqual(float(d2), 15.32)
1875
Mark Dickinsonb27406c2008-05-09 13:42:33 +00001876 #floor
1877 test_pairs = [
1878 ('123.00', 123),
1879 ('3.2', 3),
1880 ('3.54', 3),
1881 ('3.899', 3),
1882 ('-2.3', -3),
1883 ('-11.0', -11),
1884 ('0.0', 0),
1885 ('-0E3', 0),
Stefan Krah1919b7e2012-03-21 18:25:23 +01001886 ('89891211712379812736.1', 89891211712379812736),
Mark Dickinsonb27406c2008-05-09 13:42:33 +00001887 ]
1888 for d, i in test_pairs:
1889 self.assertEqual(math.floor(Decimal(d)), i)
1890 self.assertRaises(ValueError, math.floor, Decimal('-NaN'))
1891 self.assertRaises(ValueError, math.floor, Decimal('sNaN'))
1892 self.assertRaises(ValueError, math.floor, Decimal('NaN123'))
1893 self.assertRaises(OverflowError, math.floor, Decimal('Inf'))
1894 self.assertRaises(OverflowError, math.floor, Decimal('-Inf'))
1895
1896 #ceiling
1897 test_pairs = [
1898 ('123.00', 123),
1899 ('3.2', 4),
1900 ('3.54', 4),
1901 ('3.899', 4),
1902 ('-2.3', -2),
1903 ('-11.0', -11),
1904 ('0.0', 0),
1905 ('-0E3', 0),
Stefan Krah1919b7e2012-03-21 18:25:23 +01001906 ('89891211712379812736.1', 89891211712379812737),
Mark Dickinsonb27406c2008-05-09 13:42:33 +00001907 ]
1908 for d, i in test_pairs:
1909 self.assertEqual(math.ceil(Decimal(d)), i)
1910 self.assertRaises(ValueError, math.ceil, Decimal('-NaN'))
1911 self.assertRaises(ValueError, math.ceil, Decimal('sNaN'))
1912 self.assertRaises(ValueError, math.ceil, Decimal('NaN123'))
1913 self.assertRaises(OverflowError, math.ceil, Decimal('Inf'))
1914 self.assertRaises(OverflowError, math.ceil, Decimal('-Inf'))
1915
1916 #round, single argument
1917 test_pairs = [
1918 ('123.00', 123),
1919 ('3.2', 3),
1920 ('3.54', 4),
1921 ('3.899', 4),
1922 ('-2.3', -2),
1923 ('-11.0', -11),
1924 ('0.0', 0),
1925 ('-0E3', 0),
1926 ('-3.5', -4),
1927 ('-2.5', -2),
1928 ('-1.5', -2),
1929 ('-0.5', 0),
1930 ('0.5', 0),
1931 ('1.5', 2),
1932 ('2.5', 2),
1933 ('3.5', 4),
1934 ]
1935 for d, i in test_pairs:
1936 self.assertEqual(round(Decimal(d)), i)
1937 self.assertRaises(ValueError, round, Decimal('-NaN'))
1938 self.assertRaises(ValueError, round, Decimal('sNaN'))
1939 self.assertRaises(ValueError, round, Decimal('NaN123'))
1940 self.assertRaises(OverflowError, round, Decimal('Inf'))
1941 self.assertRaises(OverflowError, round, Decimal('-Inf'))
1942
1943 #round, two arguments; this is essentially equivalent
1944 #to quantize, which is already extensively tested
1945 test_triples = [
1946 ('123.456', -4, '0E+4'),
1947 ('123.456', -3, '0E+3'),
1948 ('123.456', -2, '1E+2'),
1949 ('123.456', -1, '1.2E+2'),
1950 ('123.456', 0, '123'),
1951 ('123.456', 1, '123.5'),
1952 ('123.456', 2, '123.46'),
1953 ('123.456', 3, '123.456'),
1954 ('123.456', 4, '123.4560'),
1955 ('123.455', 2, '123.46'),
1956 ('123.445', 2, '123.44'),
1957 ('Inf', 4, 'NaN'),
1958 ('-Inf', -23, 'NaN'),
1959 ('sNaN314', 3, 'NaN314'),
1960 ]
1961 for d, n, r in test_triples:
1962 self.assertEqual(str(round(Decimal(d), n)), r)
1963
Mark Dickinsonfc33d4c2012-08-24 18:53:10 +01001964 def test_nan_to_float(self):
1965 # Test conversions of decimal NANs to float.
1966 # See http://bugs.python.org/issue15544
1967 Decimal = self.decimal.Decimal
1968 for s in ('nan', 'nan1234', '-nan', '-nan2468'):
1969 f = float(Decimal(s))
1970 self.assertTrue(math.isnan(f))
1971 sign = math.copysign(1.0, f)
1972 self.assertEqual(sign, -1.0 if s.startswith('-') else 1.0)
1973
1974 def test_snan_to_float(self):
1975 Decimal = self.decimal.Decimal
1976 for s in ('snan', '-snan', 'snan1357', '-snan1234'):
1977 d = Decimal(s)
1978 self.assertRaises(ValueError, float, d)
1979
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001980 def test_eval_round_trip(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01001981 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00001982
1983 #with zero
1984 d = Decimal( (0, (0,), 0) )
1985 self.assertEqual(d, eval(repr(d)))
1986
1987 #int
1988 d = Decimal( (1, (4, 5), 0) )
1989 self.assertEqual(d, eval(repr(d)))
1990
1991 #float
1992 d = Decimal( (0, (4, 5, 3, 4), -2) )
1993 self.assertEqual(d, eval(repr(d)))
1994
1995 #weird
1996 d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
1997 self.assertEqual(d, eval(repr(d)))
1998
1999 def test_as_tuple(self):
Stefan Krah1919b7e2012-03-21 18:25:23 +01002000 Decimal = self.decimal.Decimal
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002001
2002 #with zero
2003 d = Decimal(0)
2004 self.assertEqual(d.as_tuple(), (0, (0,), 0) )
2005
2006 #int
2007 d = Decimal(-45)
2008 self.assertEqual(d.as_tuple(), (1, (4, 5), 0) )
2009
2010 #complicated string
2011 d = Decimal("-4.34913534E-17")
2012 self.assertEqual(d.as_tuple(), (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
2013
Stefan Krah76e12172012-09-10 19:34:58 +02002014 # The '0' coefficient is implementation specific to decimal.py.
2015 # It has no meaning in the C-version and is ignored there.
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00002016 d = Decimal("Infinity")
2017 self.assertEqual(d.as_tuple(), (0, (0,), 'F') )
2018
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002019 #leading zeros in coefficient should be stripped
2020 d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), -2) )
2021 self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), -2) )
2022 d = Decimal( (1, (0, 0, 0), 37) )
2023 self.assertEqual(d.as_tuple(), (1, (0,), 37))
2024 d = Decimal( (1, (), 37) )
2025 self.assertEqual(d.as_tuple(), (1, (0,), 37))
2026
2027 #leading zeros in NaN diagnostic info should be stripped
2028 d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), 'n') )
2029 self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), 'n') )
2030 d = Decimal( (1, (0, 0, 0), 'N') )
2031 self.assertEqual(d.as_tuple(), (1, (), 'N') )
2032 d = Decimal( (1, (), 'n') )
2033 self.assertEqual(d.as_tuple(), (1, (), 'n') )
2034
Stefan Krah76e12172012-09-10 19:34:58 +02002035 # For infinities, decimal.py has always silently accepted any
2036 # coefficient tuple.
2037 d = Decimal( (0, (0,), 'F') )
2038 self.assertEqual(d.as_tuple(), (0, (0,), 'F'))
2039 d = Decimal( (0, (4, 5, 3, 4), 'F') )
2040 self.assertEqual(d.as_tuple(), (0, (0,), 'F'))
2041 d = Decimal( (1, (0, 2, 7, 1), 'F') )
2042 self.assertEqual(d.as_tuple(), (1, (0,), 'F'))
Guido van Rossum8ce8a782007-11-01 19:42:39 +00002043
Stefan Krah1919b7e2012-03-21 18:25:23 +01002044 def test_subclassing(self):
2045 # Different behaviours when subclassing Decimal
2046 Decimal = self.decimal.Decimal
2047
2048 class MyDecimal(Decimal):
Stefan Krah0f82b762012-11-08 11:17:29 +01002049 y = None
Stefan Krah1919b7e2012-03-21 18:25:23 +01002050
2051 d1 = MyDecimal(1)
2052 d2 = MyDecimal(2)
2053 d = d1 + d2
2054 self.assertIs(type(d), Decimal)
2055
2056 d = d1.max(d2)
2057 self.assertIs(type(d), Decimal)
2058
2059 d = copy.copy(d1)
2060 self.assertIs(type(d), MyDecimal)
2061 self.assertEqual(d, d1)
2062
2063 d = copy.deepcopy(d1)
2064 self.assertIs(type(d), MyDecimal)
2065 self.assertEqual(d, d1)
2066
Stefan Krah0f82b762012-11-08 11:17:29 +01002067 # Decimal(Decimal)
2068 d = Decimal('1.0')
2069 x = Decimal(d)
2070 self.assertIs(type(x), Decimal)
2071 self.assertEqual(x, d)
Stefan Krahf4abc7b2012-11-07 23:12:25 +01002072
Stefan Krah0f82b762012-11-08 11:17:29 +01002073 # MyDecimal(Decimal)
2074 m = MyDecimal(d)
2075 self.assertIs(type(m), MyDecimal)
2076 self.assertEqual(m, d)
2077 self.assertIs(m.y, None)
2078
2079 # Decimal(MyDecimal)
2080 x = Decimal(m)
2081 self.assertIs(type(x), Decimal)
2082 self.assertEqual(x, d)
2083
2084 # MyDecimal(MyDecimal)
2085 m.y = 9
2086 x = MyDecimal(m)
2087 self.assertIs(type(x), MyDecimal)
2088 self.assertEqual(x, d)
2089 self.assertIs(x.y, None)
Stefan Krahed16eff2012-11-07 23:47:19 +01002090
Stefan Krah1919b7e2012-03-21 18:25:23 +01002091 def test_implicit_context(self):
2092 Decimal = self.decimal.Decimal
2093 getcontext = self.decimal.getcontext
2094
2095 # Check results when context given implicitly. (Issue 2478)
2096 c = getcontext()
2097 self.assertEqual(str(Decimal(0).sqrt()),
2098 str(c.sqrt(Decimal(0))))
2099
Stefan Krah040e3112012-12-15 22:33:33 +01002100 def test_none_args(self):
2101 Decimal = self.decimal.Decimal
2102 Context = self.decimal.Context
2103 localcontext = self.decimal.localcontext
2104 InvalidOperation = self.decimal.InvalidOperation
2105 DivisionByZero = self.decimal.DivisionByZero
2106 Overflow = self.decimal.Overflow
2107 Underflow = self.decimal.Underflow
2108 Subnormal = self.decimal.Subnormal
2109 Inexact = self.decimal.Inexact
2110 Rounded = self.decimal.Rounded
2111 Clamped = self.decimal.Clamped
Stefan Krah040e3112012-12-15 22:33:33 +01002112
2113 with localcontext(Context()) as c:
2114 c.prec = 7
2115 c.Emax = 999
2116 c.Emin = -999
2117
2118 x = Decimal("111")
2119 y = Decimal("1e9999")
2120 z = Decimal("1e-9999")
2121
2122 ##### Unary functions
2123 c.clear_flags()
2124 self.assertEqual(str(x.exp(context=None)), '1.609487E+48')
2125 self.assertTrue(c.flags[Inexact])
2126 self.assertTrue(c.flags[Rounded])
2127 c.clear_flags()
2128 self.assertRaises(Overflow, y.exp, context=None)
2129 self.assertTrue(c.flags[Overflow])
2130
2131 self.assertIs(z.is_normal(context=None), False)
2132 self.assertIs(z.is_subnormal(context=None), True)
2133
2134 c.clear_flags()
2135 self.assertEqual(str(x.ln(context=None)), '4.709530')
2136 self.assertTrue(c.flags[Inexact])
2137 self.assertTrue(c.flags[Rounded])
2138 c.clear_flags()
2139 self.assertRaises(InvalidOperation, Decimal(-1).ln, context=None)
2140 self.assertTrue(c.flags[InvalidOperation])
2141
2142 c.clear_flags()
2143 self.assertEqual(str(x.log10(context=None)), '2.045323')
2144 self.assertTrue(c.flags[Inexact])
2145 self.assertTrue(c.flags[Rounded])
2146 c.clear_flags()
2147 self.assertRaises(InvalidOperation, Decimal(-1).log10, context=None)
2148 self.assertTrue(c.flags[InvalidOperation])
2149
2150 c.clear_flags()
2151 self.assertEqual(str(x.logb(context=None)), '2')
2152 self.assertRaises(DivisionByZero, Decimal(0).logb, context=None)
2153 self.assertTrue(c.flags[DivisionByZero])
2154
2155 c.clear_flags()
2156 self.assertEqual(str(x.logical_invert(context=None)), '1111000')
2157 self.assertRaises(InvalidOperation, y.logical_invert, context=None)
2158 self.assertTrue(c.flags[InvalidOperation])
2159
2160 c.clear_flags()
2161 self.assertEqual(str(y.next_minus(context=None)), '9.999999E+999')
2162 self.assertRaises(InvalidOperation, Decimal('sNaN').next_minus, context=None)
2163 self.assertTrue(c.flags[InvalidOperation])
2164
2165 c.clear_flags()
2166 self.assertEqual(str(y.next_plus(context=None)), 'Infinity')
2167 self.assertRaises(InvalidOperation, Decimal('sNaN').next_plus, context=None)
2168 self.assertTrue(c.flags[InvalidOperation])
2169
2170 c.clear_flags()
2171 self.assertEqual(str(z.normalize(context=None)), '0')
2172 self.assertRaises(Overflow, y.normalize, context=None)
2173 self.assertTrue(c.flags[Overflow])
2174
2175 self.assertEqual(str(z.number_class(context=None)), '+Subnormal')
2176
2177 c.clear_flags()
2178 self.assertEqual(str(z.sqrt(context=None)), '0E-1005')
2179 self.assertTrue(c.flags[Clamped])
2180 self.assertTrue(c.flags[Inexact])
2181 self.assertTrue(c.flags[Rounded])
2182 self.assertTrue(c.flags[Subnormal])
2183 self.assertTrue(c.flags[Underflow])
2184 c.clear_flags()
2185 self.assertRaises(Overflow, y.sqrt, context=None)
2186 self.assertTrue(c.flags[Overflow])
2187
2188 c.capitals = 0
2189 self.assertEqual(str(z.to_eng_string(context=None)), '1e-9999')
2190 c.capitals = 1
2191
2192
2193 ##### Binary functions
2194 c.clear_flags()
2195 ans = str(x.compare(Decimal('Nan891287828'), context=None))
2196 self.assertEqual(ans, 'NaN1287828')
2197 self.assertRaises(InvalidOperation, x.compare, Decimal('sNaN'), context=None)
2198 self.assertTrue(c.flags[InvalidOperation])
2199
2200 c.clear_flags()
2201 ans = str(x.compare_signal(8224, context=None))
2202 self.assertEqual(ans, '-1')
2203 self.assertRaises(InvalidOperation, x.compare_signal, Decimal('NaN'), context=None)
2204 self.assertTrue(c.flags[InvalidOperation])
2205
2206 c.clear_flags()
2207 ans = str(x.logical_and(101, context=None))
2208 self.assertEqual(ans, '101')
2209 self.assertRaises(InvalidOperation, x.logical_and, 123, context=None)
2210 self.assertTrue(c.flags[InvalidOperation])
2211
2212 c.clear_flags()
2213 ans = str(x.logical_or(101, context=None))
2214 self.assertEqual(ans, '111')
2215 self.assertRaises(InvalidOperation, x.logical_or, 123, context=None)
2216 self.assertTrue(c.flags[InvalidOperation])
2217
2218 c.clear_flags()
2219 ans = str(x.logical_xor(101, context=None))
2220 self.assertEqual(ans, '10')
2221 self.assertRaises(InvalidOperation, x.logical_xor, 123, context=None)
2222 self.assertTrue(c.flags[InvalidOperation])
2223
2224 c.clear_flags()
2225 ans = str(x.max(101, context=None))
2226 self.assertEqual(ans, '111')
2227 self.assertRaises(InvalidOperation, x.max, Decimal('sNaN'), context=None)
2228 self.assertTrue(c.flags[InvalidOperation])
2229
2230 c.clear_flags()
2231 ans = str(x.max_mag(101, context=None))
2232 self.assertEqual(ans, '111')
2233 self.assertRaises(InvalidOperation, x.max_mag, Decimal('sNaN'), context=None)
2234 self.assertTrue(c.flags[InvalidOperation])
2235
2236 c.clear_flags()
2237 ans = str(x.min(101, context=None))
2238 self.assertEqual(ans, '101')
2239 self.assertRaises(InvalidOperation, x.min, Decimal('sNaN'), context=None)
2240 self.assertTrue(c.flags[InvalidOperation])
2241
2242 c.clear_flags()
2243 ans = str(x.min_mag(101, context=None))
2244 self.assertEqual(ans, '101')
2245 self.assertRaises(InvalidOperation, x.min_mag, Decimal('sNaN'), context=None)
2246 self.assertTrue(c.flags[InvalidOperation])
2247
2248 c.clear_flags()
2249 ans = str(x.remainder_near(101, context=None))
2250 self.assertEqual(ans, '10')
2251 self.assertRaises(InvalidOperation, y.remainder_near, 101, context=None)
2252 self.assertTrue(c.flags[InvalidOperation])
2253
2254 c.clear_flags()
2255 ans = str(x.rotate(2, context=None))
2256 self.assertEqual(ans, '11100')
2257 self.assertRaises(InvalidOperation, x.rotate, 101, context=None)
2258 self.assertTrue(c.flags[InvalidOperation])
2259
2260 c.clear_flags()
2261 ans = str(x.scaleb(7, context=None))
2262 self.assertEqual(ans, '1.11E+9')
2263 self.assertRaises(InvalidOperation, x.scaleb, 10000, context=None)
2264 self.assertTrue(c.flags[InvalidOperation])
2265
2266 c.clear_flags()
2267 ans = str(x.shift(2, context=None))
2268 self.assertEqual(ans, '11100')
2269 self.assertRaises(InvalidOperation, x.shift, 10000, context=None)
2270 self.assertTrue(c.flags[InvalidOperation])
2271
2272
2273 ##### Ternary functions
2274 c.clear_flags()
2275 ans = str(x.fma(2, 3, context=None))
2276 self.assertEqual(ans, '225')
2277 self.assertRaises(Overflow, x.fma, Decimal('1e9999'), 3, context=None)
2278 self.assertTrue(c.flags[Overflow])
2279
2280
2281 ##### Special cases
2282 c.rounding = ROUND_HALF_EVEN
2283 ans = str(Decimal('1.5').to_integral(rounding=None, context=None))
2284 self.assertEqual(ans, '2')
2285 c.rounding = ROUND_DOWN
2286 ans = str(Decimal('1.5').to_integral(rounding=None, context=None))
2287 self.assertEqual(ans, '1')
2288 ans = str(Decimal('1.5').to_integral(rounding=ROUND_UP, context=None))
2289 self.assertEqual(ans, '2')
2290 c.clear_flags()
2291 self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral, context=None)
2292 self.assertTrue(c.flags[InvalidOperation])
2293
2294 c.rounding = ROUND_HALF_EVEN
2295 ans = str(Decimal('1.5').to_integral_value(rounding=None, context=None))
2296 self.assertEqual(ans, '2')
2297 c.rounding = ROUND_DOWN
2298 ans = str(Decimal('1.5').to_integral_value(rounding=None, context=None))
2299 self.assertEqual(ans, '1')
2300 ans = str(Decimal('1.5').to_integral_value(rounding=ROUND_UP, context=None))
2301 self.assertEqual(ans, '2')
2302 c.clear_flags()
2303 self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral_value, context=None)
2304 self.assertTrue(c.flags[InvalidOperation])
2305
2306 c.rounding = ROUND_HALF_EVEN
2307 ans = str(Decimal('1.5').to_integral_exact(rounding=None, context=None))
2308 self.assertEqual(ans, '2')
2309 c.rounding = ROUND_DOWN
2310 ans = str(Decimal('1.5').to_integral_exact(rounding=None, context=None))
2311 self.assertEqual(ans, '1')
2312 ans = str(Decimal('1.5').to_integral_exact(rounding=ROUND_UP, context=None))
2313 self.assertEqual(ans, '2')
2314 c.clear_flags()
2315 self.assertRaises(InvalidOperation, Decimal('sNaN').to_integral_exact, context=None)
2316 self.assertTrue(c.flags[InvalidOperation])
2317
2318 c.rounding = ROUND_UP
2319 ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=None, context=None))
2320 self.assertEqual(ans, '1.501')
2321 c.rounding = ROUND_DOWN
2322 ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=None, context=None))
2323 self.assertEqual(ans, '1.500')
2324 ans = str(Decimal('1.50001').quantize(exp=Decimal('1e-3'), rounding=ROUND_UP, context=None))
2325 self.assertEqual(ans, '1.501')
2326 c.clear_flags()
2327 self.assertRaises(InvalidOperation, y.quantize, Decimal('1e-10'), rounding=ROUND_UP, context=None)
2328 self.assertTrue(c.flags[InvalidOperation])
2329
2330 with localcontext(Context()) as context:
2331 context.prec = 7
2332 context.Emax = 999
2333 context.Emin = -999
2334 with localcontext(ctx=None) as c:
2335 self.assertEqual(c.prec, 7)
2336 self.assertEqual(c.Emax, 999)
2337 self.assertEqual(c.Emin, -999)
2338
Stefan Krah1919b7e2012-03-21 18:25:23 +01002339 def test_conversions_from_int(self):
2340 # Check that methods taking a second Decimal argument will
2341 # always accept an integer in place of a Decimal.
2342 Decimal = self.decimal.Decimal
2343
2344 self.assertEqual(Decimal(4).compare(3),
2345 Decimal(4).compare(Decimal(3)))
2346 self.assertEqual(Decimal(4).compare_signal(3),
2347 Decimal(4).compare_signal(Decimal(3)))
2348 self.assertEqual(Decimal(4).compare_total(3),
2349 Decimal(4).compare_total(Decimal(3)))
2350 self.assertEqual(Decimal(4).compare_total_mag(3),
2351 Decimal(4).compare_total_mag(Decimal(3)))
2352 self.assertEqual(Decimal(10101).logical_and(1001),
2353 Decimal(10101).logical_and(Decimal(1001)))
2354 self.assertEqual(Decimal(10101).logical_or(1001),
2355 Decimal(10101).logical_or(Decimal(1001)))
2356 self.assertEqual(Decimal(10101).logical_xor(1001),
2357 Decimal(10101).logical_xor(Decimal(1001)))
2358 self.assertEqual(Decimal(567).max(123),
2359 Decimal(567).max(Decimal(123)))
2360 self.assertEqual(Decimal(567).max_mag(123),
2361 Decimal(567).max_mag(Decimal(123)))
2362 self.assertEqual(Decimal(567).min(123),
2363 Decimal(567).min(Decimal(123)))
2364 self.assertEqual(Decimal(567).min_mag(123),
2365 Decimal(567).min_mag(Decimal(123)))
2366 self.assertEqual(Decimal(567).next_toward(123),
2367 Decimal(567).next_toward(Decimal(123)))
2368 self.assertEqual(Decimal(1234).quantize(100),
2369 Decimal(1234).quantize(Decimal(100)))
2370 self.assertEqual(Decimal(768).remainder_near(1234),
2371 Decimal(768).remainder_near(Decimal(1234)))
2372 self.assertEqual(Decimal(123).rotate(1),
2373 Decimal(123).rotate(Decimal(1)))
2374 self.assertEqual(Decimal(1234).same_quantum(1000),
2375 Decimal(1234).same_quantum(Decimal(1000)))
2376 self.assertEqual(Decimal('9.123').scaleb(-100),
2377 Decimal('9.123').scaleb(Decimal(-100)))
2378 self.assertEqual(Decimal(456).shift(-1),
2379 Decimal(456).shift(Decimal(-1)))
2380
2381 self.assertEqual(Decimal(-12).fma(Decimal(45), 67),
2382 Decimal(-12).fma(Decimal(45), Decimal(67)))
2383 self.assertEqual(Decimal(-12).fma(45, 67),
2384 Decimal(-12).fma(Decimal(45), Decimal(67)))
2385 self.assertEqual(Decimal(-12).fma(45, Decimal(67)),
2386 Decimal(-12).fma(Decimal(45), Decimal(67)))
2387
2388class CUsabilityTest(UsabilityTest):
2389 decimal = C
2390class PyUsabilityTest(UsabilityTest):
2391 decimal = P
2392
2393class PythonAPItests(unittest.TestCase):
2394
2395 def test_abc(self):
2396 Decimal = self.decimal.Decimal
2397
2398 self.assertTrue(issubclass(Decimal, numbers.Number))
2399 self.assertFalse(issubclass(Decimal, numbers.Real))
2400 self.assertIsInstance(Decimal(0), numbers.Number)
2401 self.assertNotIsInstance(Decimal(0), numbers.Real)
2402
2403 def test_pickle(self):
2404 Decimal = self.decimal.Decimal
2405
2406 savedecimal = sys.modules['decimal']
2407
2408 # Round trip
2409 sys.modules['decimal'] = self.decimal
2410 d = Decimal('-3.141590000')
2411 p = pickle.dumps(d)
2412 e = pickle.loads(p)
2413 self.assertEqual(d, e)
2414
2415 if C:
2416 # Test interchangeability
2417 x = C.Decimal('-3.123e81723')
2418 y = P.Decimal('-3.123e81723')
2419
2420 sys.modules['decimal'] = C
2421 sx = pickle.dumps(x)
2422 sys.modules['decimal'] = P
2423 r = pickle.loads(sx)
2424 self.assertIsInstance(r, P.Decimal)
2425 self.assertEqual(r, y)
2426
2427 sys.modules['decimal'] = P
2428 sy = pickle.dumps(y)
2429 sys.modules['decimal'] = C
2430 r = pickle.loads(sy)
2431 self.assertIsInstance(r, C.Decimal)
2432 self.assertEqual(r, x)
2433
2434 sys.modules['decimal'] = savedecimal
2435
2436 def test_int(self):
2437 Decimal = self.decimal.Decimal
Stefan Krah1919b7e2012-03-21 18:25:23 +01002438
2439 for x in range(-250, 250):
2440 s = '%0.2f' % (x / 100.0)
2441 # should work the same as for floats
2442 self.assertEqual(int(Decimal(s)), int(float(s)))
2443 # should work the same as to_integral in the ROUND_DOWN mode
2444 d = Decimal(s)
2445 r = d.to_integral(ROUND_DOWN)
2446 self.assertEqual(Decimal(int(d)), r)
2447
2448 self.assertRaises(ValueError, int, Decimal('-nan'))
2449 self.assertRaises(ValueError, int, Decimal('snan'))
2450 self.assertRaises(OverflowError, int, Decimal('inf'))
2451 self.assertRaises(OverflowError, int, Decimal('-inf'))
2452
2453 def test_trunc(self):
2454 Decimal = self.decimal.Decimal
Stefan Krah1919b7e2012-03-21 18:25:23 +01002455
2456 for x in range(-250, 250):
2457 s = '%0.2f' % (x / 100.0)
2458 # should work the same as for floats
2459 self.assertEqual(int(Decimal(s)), int(float(s)))
2460 # should work the same as to_integral in the ROUND_DOWN mode
2461 d = Decimal(s)
2462 r = d.to_integral(ROUND_DOWN)
2463 self.assertEqual(Decimal(math.trunc(d)), r)
2464
2465 def test_from_float(self):
2466
2467 Decimal = self.decimal.Decimal
2468
2469 class MyDecimal(Decimal):
2470 pass
2471
2472 self.assertTrue(issubclass(MyDecimal, Decimal))
2473
2474 r = MyDecimal.from_float(0.1)
2475 self.assertEqual(type(r), MyDecimal)
2476 self.assertEqual(str(r),
2477 '0.1000000000000000055511151231257827021181583404541015625')
2478 bigint = 12345678901234567890123456789
2479 self.assertEqual(MyDecimal.from_float(bigint), MyDecimal(bigint))
2480 self.assertTrue(MyDecimal.from_float(float('nan')).is_qnan())
2481 self.assertTrue(MyDecimal.from_float(float('inf')).is_infinite())
2482 self.assertTrue(MyDecimal.from_float(float('-inf')).is_infinite())
2483 self.assertEqual(str(MyDecimal.from_float(float('nan'))),
2484 str(Decimal('NaN')))
2485 self.assertEqual(str(MyDecimal.from_float(float('inf'))),
2486 str(Decimal('Infinity')))
2487 self.assertEqual(str(MyDecimal.from_float(float('-inf'))),
2488 str(Decimal('-Infinity')))
2489 self.assertRaises(TypeError, MyDecimal.from_float, 'abc')
2490 for i in range(200):
2491 x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
2492 self.assertEqual(x, float(MyDecimal.from_float(x))) # roundtrip
2493
2494 def test_create_decimal_from_float(self):
2495 Decimal = self.decimal.Decimal
2496 Context = self.decimal.Context
Stefan Krah1919b7e2012-03-21 18:25:23 +01002497 Inexact = self.decimal.Inexact
2498
2499 context = Context(prec=5, rounding=ROUND_DOWN)
2500 self.assertEqual(
2501 context.create_decimal_from_float(math.pi),
2502 Decimal('3.1415')
2503 )
2504 context = Context(prec=5, rounding=ROUND_UP)
2505 self.assertEqual(
2506 context.create_decimal_from_float(math.pi),
2507 Decimal('3.1416')
2508 )
2509 context = Context(prec=5, traps=[Inexact])
2510 self.assertRaises(
2511 Inexact,
2512 context.create_decimal_from_float,
2513 math.pi
2514 )
2515 self.assertEqual(repr(context.create_decimal_from_float(-0.0)),
2516 "Decimal('-0')")
2517 self.assertEqual(repr(context.create_decimal_from_float(1.0)),
2518 "Decimal('1')")
2519 self.assertEqual(repr(context.create_decimal_from_float(10)),
2520 "Decimal('10')")
2521
2522 def test_quantize(self):
2523 Decimal = self.decimal.Decimal
2524 Context = self.decimal.Context
2525 InvalidOperation = self.decimal.InvalidOperation
Stefan Krah1919b7e2012-03-21 18:25:23 +01002526
2527 c = Context(Emax=99999, Emin=-99999)
2528 self.assertEqual(
2529 Decimal('7.335').quantize(Decimal('.01')),
2530 Decimal('7.34')
2531 )
2532 self.assertEqual(
2533 Decimal('7.335').quantize(Decimal('.01'), rounding=ROUND_DOWN),
2534 Decimal('7.33')
2535 )
2536 self.assertRaises(
2537 InvalidOperation,
2538 Decimal("10e99999").quantize, Decimal('1e100000'), context=c
2539 )
2540
2541 c = Context()
2542 d = Decimal("0.871831e800")
2543 x = d.quantize(context=c, exp=Decimal("1e797"), rounding=ROUND_DOWN)
2544 self.assertEqual(x, Decimal('8.71E+799'))
2545
2546 def test_complex(self):
2547 Decimal = self.decimal.Decimal
2548
2549 x = Decimal("9.8182731e181273")
2550 self.assertEqual(x.real, x)
2551 self.assertEqual(x.imag, 0)
2552 self.assertEqual(x.conjugate(), x)
2553
2554 x = Decimal("1")
2555 self.assertEqual(complex(x), complex(float(1)))
2556
2557 self.assertRaises(AttributeError, setattr, x, 'real', 100)
2558 self.assertRaises(AttributeError, setattr, x, 'imag', 100)
2559 self.assertRaises(AttributeError, setattr, x, 'conjugate', 100)
2560 self.assertRaises(AttributeError, setattr, x, '__complex__', 100)
2561
2562 def test_named_parameters(self):
2563 D = self.decimal.Decimal
2564 Context = self.decimal.Context
2565 localcontext = self.decimal.localcontext
2566 InvalidOperation = self.decimal.InvalidOperation
2567 Overflow = self.decimal.Overflow
2568
2569 xc = Context()
2570 xc.prec = 1
2571 xc.Emax = 1
2572 xc.Emin = -1
2573
2574 with localcontext() as c:
2575 c.clear_flags()
2576
2577 self.assertEqual(D(9, xc), 9)
2578 self.assertEqual(D(9, context=xc), 9)
2579 self.assertEqual(D(context=xc, value=9), 9)
2580 self.assertEqual(D(context=xc), 0)
2581 xc.clear_flags()
2582 self.assertRaises(InvalidOperation, D, "xyz", context=xc)
2583 self.assertTrue(xc.flags[InvalidOperation])
2584 self.assertFalse(c.flags[InvalidOperation])
2585
2586 xc.clear_flags()
2587 self.assertEqual(D(2).exp(context=xc), 7)
2588 self.assertRaises(Overflow, D(8).exp, context=xc)
2589 self.assertTrue(xc.flags[Overflow])
2590 self.assertFalse(c.flags[Overflow])
2591
2592 xc.clear_flags()
2593 self.assertEqual(D(2).ln(context=xc), D('0.7'))
2594 self.assertRaises(InvalidOperation, D(-1).ln, context=xc)
2595 self.assertTrue(xc.flags[InvalidOperation])
2596 self.assertFalse(c.flags[InvalidOperation])
2597
2598 self.assertEqual(D(0).log10(context=xc), D('-inf'))
2599 self.assertEqual(D(-1).next_minus(context=xc), -2)
2600 self.assertEqual(D(-1).next_plus(context=xc), D('-0.9'))
2601 self.assertEqual(D("9.73").normalize(context=xc), D('1E+1'))
2602 self.assertEqual(D("9999").to_integral(context=xc), 9999)
2603 self.assertEqual(D("-2000").to_integral_exact(context=xc), -2000)
2604 self.assertEqual(D("123").to_integral_value(context=xc), 123)
2605 self.assertEqual(D("0.0625").sqrt(context=xc), D('0.2'))
2606
2607 self.assertEqual(D("0.0625").compare(context=xc, other=3), -1)
2608 xc.clear_flags()
2609 self.assertRaises(InvalidOperation,
2610 D("0").compare_signal, D('nan'), context=xc)
2611 self.assertTrue(xc.flags[InvalidOperation])
2612 self.assertFalse(c.flags[InvalidOperation])
2613 self.assertEqual(D("0.01").max(D('0.0101'), context=xc), D('0.0'))
2614 self.assertEqual(D("0.01").max(D('0.0101'), context=xc), D('0.0'))
2615 self.assertEqual(D("0.2").max_mag(D('-0.3'), context=xc),
2616 D('-0.3'))
2617 self.assertEqual(D("0.02").min(D('-0.03'), context=xc), D('-0.0'))
2618 self.assertEqual(D("0.02").min_mag(D('-0.03'), context=xc),
2619 D('0.0'))
2620 self.assertEqual(D("0.2").next_toward(D('-1'), context=xc), D('0.1'))
2621 xc.clear_flags()
2622 self.assertRaises(InvalidOperation,
2623 D("0.2").quantize, D('1e10'), context=xc)
2624 self.assertTrue(xc.flags[InvalidOperation])
2625 self.assertFalse(c.flags[InvalidOperation])
2626 self.assertEqual(D("9.99").remainder_near(D('1.5'), context=xc),
2627 D('-0.5'))
2628
2629 self.assertEqual(D("9.9").fma(third=D('0.9'), context=xc, other=7),
2630 D('7E+1'))
2631
2632 self.assertRaises(TypeError, D(1).is_canonical, context=xc)
2633 self.assertRaises(TypeError, D(1).is_finite, context=xc)
2634 self.assertRaises(TypeError, D(1).is_infinite, context=xc)
2635 self.assertRaises(TypeError, D(1).is_nan, context=xc)
2636 self.assertRaises(TypeError, D(1).is_qnan, context=xc)
2637 self.assertRaises(TypeError, D(1).is_snan, context=xc)
2638 self.assertRaises(TypeError, D(1).is_signed, context=xc)
2639 self.assertRaises(TypeError, D(1).is_zero, context=xc)
2640
2641 self.assertFalse(D("0.01").is_normal(context=xc))
2642 self.assertTrue(D("0.01").is_subnormal(context=xc))
2643
2644 self.assertRaises(TypeError, D(1).adjusted, context=xc)
2645 self.assertRaises(TypeError, D(1).conjugate, context=xc)
2646 self.assertRaises(TypeError, D(1).radix, context=xc)
2647
2648 self.assertEqual(D(-111).logb(context=xc), 2)
2649 self.assertEqual(D(0).logical_invert(context=xc), 1)
2650 self.assertEqual(D('0.01').number_class(context=xc), '+Subnormal')
2651 self.assertEqual(D('0.21').to_eng_string(context=xc), '0.21')
2652
2653 self.assertEqual(D('11').logical_and(D('10'), context=xc), 0)
2654 self.assertEqual(D('11').logical_or(D('10'), context=xc), 1)
2655 self.assertEqual(D('01').logical_xor(D('10'), context=xc), 1)
2656 self.assertEqual(D('23').rotate(1, context=xc), 3)
2657 self.assertEqual(D('23').rotate(1, context=xc), 3)
2658 xc.clear_flags()
2659 self.assertRaises(Overflow,
2660 D('23').scaleb, 1, context=xc)
2661 self.assertTrue(xc.flags[Overflow])
2662 self.assertFalse(c.flags[Overflow])
2663 self.assertEqual(D('23').shift(-1, context=xc), 0)
2664
2665 self.assertRaises(TypeError, D.from_float, 1.1, context=xc)
2666 self.assertRaises(TypeError, D(0).as_tuple, context=xc)
2667
Stefan Krah040e3112012-12-15 22:33:33 +01002668 self.assertEqual(D(1).canonical(), 1)
2669 self.assertRaises(TypeError, D("-1").copy_abs, context=xc)
2670 self.assertRaises(TypeError, D("-1").copy_negate, context=xc)
2671 self.assertRaises(TypeError, D(1).canonical, context="x")
2672 self.assertRaises(TypeError, D(1).canonical, xyz="x")
Stefan Krah1919b7e2012-03-21 18:25:23 +01002673
Stefan Krahb6405ef2012-03-23 14:46:48 +01002674 def test_exception_hierarchy(self):
2675
2676 decimal = self.decimal
2677 DecimalException = decimal.DecimalException
2678 InvalidOperation = decimal.InvalidOperation
2679 FloatOperation = decimal.FloatOperation
2680 DivisionByZero = decimal.DivisionByZero
2681 Overflow = decimal.Overflow
2682 Underflow = decimal.Underflow
2683 Subnormal = decimal.Subnormal
2684 Inexact = decimal.Inexact
2685 Rounded = decimal.Rounded
2686 Clamped = decimal.Clamped
2687
2688 self.assertTrue(issubclass(DecimalException, ArithmeticError))
2689
2690 self.assertTrue(issubclass(InvalidOperation, DecimalException))
2691 self.assertTrue(issubclass(FloatOperation, DecimalException))
2692 self.assertTrue(issubclass(FloatOperation, TypeError))
2693 self.assertTrue(issubclass(DivisionByZero, DecimalException))
2694 self.assertTrue(issubclass(DivisionByZero, ZeroDivisionError))
2695 self.assertTrue(issubclass(Overflow, Rounded))
2696 self.assertTrue(issubclass(Overflow, Inexact))
2697 self.assertTrue(issubclass(Overflow, DecimalException))
2698 self.assertTrue(issubclass(Underflow, Inexact))
2699 self.assertTrue(issubclass(Underflow, Rounded))
2700 self.assertTrue(issubclass(Underflow, Subnormal))
2701 self.assertTrue(issubclass(Underflow, DecimalException))
2702
2703 self.assertTrue(issubclass(Subnormal, DecimalException))
2704 self.assertTrue(issubclass(Inexact, DecimalException))
2705 self.assertTrue(issubclass(Rounded, DecimalException))
2706 self.assertTrue(issubclass(Clamped, DecimalException))
2707
2708 self.assertTrue(issubclass(decimal.ConversionSyntax, InvalidOperation))
2709 self.assertTrue(issubclass(decimal.DivisionImpossible, InvalidOperation))
2710 self.assertTrue(issubclass(decimal.DivisionUndefined, InvalidOperation))
2711 self.assertTrue(issubclass(decimal.DivisionUndefined, ZeroDivisionError))
2712 self.assertTrue(issubclass(decimal.InvalidContext, InvalidOperation))
2713
Stefan Krah1919b7e2012-03-21 18:25:23 +01002714class CPythonAPItests(PythonAPItests):
2715 decimal = C
2716class PyPythonAPItests(PythonAPItests):
2717 decimal = P
2718
2719class ContextAPItests(unittest.TestCase):
2720
Stefan Krah9a4ff432012-12-16 21:10:35 +01002721 def test_none_args(self):
2722 Context = self.decimal.Context
2723 InvalidOperation = self.decimal.InvalidOperation
2724 DivisionByZero = self.decimal.DivisionByZero
2725 Overflow = self.decimal.Overflow
Stefan Krah9a4ff432012-12-16 21:10:35 +01002726
2727 c1 = Context()
2728 c2 = Context(prec=None, rounding=None, Emax=None, Emin=None,
2729 capitals=None, clamp=None, flags=None, traps=None)
2730 for c in [c1, c2]:
2731 self.assertEqual(c.prec, 28)
2732 self.assertEqual(c.rounding, ROUND_HALF_EVEN)
2733 self.assertEqual(c.Emax, 999999)
2734 self.assertEqual(c.Emin, -999999)
2735 self.assertEqual(c.capitals, 1)
2736 self.assertEqual(c.clamp, 0)
2737 assert_signals(self, c, 'flags', [])
2738 assert_signals(self, c, 'traps', [InvalidOperation, DivisionByZero,
2739 Overflow])
2740
Stefan Krah59a4a932013-01-16 12:58:59 +01002741 @cpython_only
2742 def test_from_legacy_strings(self):
2743 import _testcapi
2744 c = self.decimal.Context()
2745
2746 for rnd in RoundingModes:
2747 c.rounding = _testcapi.unicode_legacy_string(rnd)
2748 self.assertEqual(c.rounding, rnd)
2749
2750 s = _testcapi.unicode_legacy_string('')
2751 self.assertRaises(TypeError, setattr, c, 'rounding', s)
2752
2753 s = _testcapi.unicode_legacy_string('ROUND_\x00UP')
2754 self.assertRaises(TypeError, setattr, c, 'rounding', s)
2755
Stefan Krah1919b7e2012-03-21 18:25:23 +01002756 def test_pickle(self):
2757
2758 Context = self.decimal.Context
2759
2760 savedecimal = sys.modules['decimal']
2761
2762 # Round trip
2763 sys.modules['decimal'] = self.decimal
2764 c = Context()
2765 e = pickle.loads(pickle.dumps(c))
2766
2767 self.assertEqual(c.prec, e.prec)
2768 self.assertEqual(c.Emin, e.Emin)
2769 self.assertEqual(c.Emax, e.Emax)
2770 self.assertEqual(c.rounding, e.rounding)
2771 self.assertEqual(c.capitals, e.capitals)
2772 self.assertEqual(c.clamp, e.clamp)
2773 self.assertEqual(c.flags, e.flags)
2774 self.assertEqual(c.traps, e.traps)
2775
2776 # Test interchangeability
2777 combinations = [(C, P), (P, C)] if C else [(P, P)]
2778 for dumper, loader in combinations:
Stefan Krah59a4a932013-01-16 12:58:59 +01002779 for ri, _ in enumerate(RoundingModes):
Stefan Krah1919b7e2012-03-21 18:25:23 +01002780 for fi, _ in enumerate(OrderedSignals[dumper]):
2781 for ti, _ in enumerate(OrderedSignals[dumper]):
2782
2783 prec = random.randrange(1, 100)
2784 emin = random.randrange(-100, 0)
2785 emax = random.randrange(1, 100)
2786 caps = random.randrange(2)
2787 clamp = random.randrange(2)
2788
2789 # One module dumps
2790 sys.modules['decimal'] = dumper
2791 c = dumper.Context(
2792 prec=prec, Emin=emin, Emax=emax,
Stefan Krah59a4a932013-01-16 12:58:59 +01002793 rounding=RoundingModes[ri],
Stefan Krah1919b7e2012-03-21 18:25:23 +01002794 capitals=caps, clamp=clamp,
2795 flags=OrderedSignals[dumper][:fi],
2796 traps=OrderedSignals[dumper][:ti]
2797 )
2798 s = pickle.dumps(c)
2799
2800 # The other module loads
2801 sys.modules['decimal'] = loader
2802 d = pickle.loads(s)
2803 self.assertIsInstance(d, loader.Context)
2804
2805 self.assertEqual(d.prec, prec)
2806 self.assertEqual(d.Emin, emin)
2807 self.assertEqual(d.Emax, emax)
Stefan Krah59a4a932013-01-16 12:58:59 +01002808 self.assertEqual(d.rounding, RoundingModes[ri])
Stefan Krah1919b7e2012-03-21 18:25:23 +01002809 self.assertEqual(d.capitals, caps)
2810 self.assertEqual(d.clamp, clamp)
2811 assert_signals(self, d, 'flags', OrderedSignals[loader][:fi])
2812 assert_signals(self, d, 'traps', OrderedSignals[loader][:ti])
2813
2814 sys.modules['decimal'] = savedecimal
2815
2816 def test_equality_with_other_types(self):
2817 Decimal = self.decimal.Decimal
2818
2819 self.assertIn(Decimal(10), ['a', 1.0, Decimal(10), (1,2), {}])
2820 self.assertNotIn(Decimal(10), ['a', 1.0, (1,2), {}])
2821
2822 def test_copy(self):
2823 # All copies should be deep
2824 Decimal = self.decimal.Decimal
2825 Context = self.decimal.Context
2826
2827 c = Context()
2828 d = c.copy()
2829 self.assertNotEqual(id(c), id(d))
2830 self.assertNotEqual(id(c.flags), id(d.flags))
2831 self.assertNotEqual(id(c.traps), id(d.traps))
2832 k1 = set(c.flags.keys())
2833 k2 = set(d.flags.keys())
2834 self.assertEqual(k1, k2)
2835 self.assertEqual(c.flags, d.flags)
2836
2837 def test__clamp(self):
2838 # In Python 3.2, the private attribute `_clamp` was made
2839 # public (issue 8540), with the old `_clamp` becoming a
2840 # property wrapping `clamp`. For the duration of Python 3.2
2841 # only, the attribute should be gettable/settable via both
2842 # `clamp` and `_clamp`; in Python 3.3, `_clamp` should be
2843 # removed.
2844 Context = self.decimal.Context
2845 c = Context()
2846 self.assertRaises(AttributeError, getattr, c, '_clamp')
2847
2848 def test_abs(self):
2849 Decimal = self.decimal.Decimal
2850 Context = self.decimal.Context
2851
2852 c = Context()
2853 d = c.abs(Decimal(-1))
2854 self.assertEqual(c.abs(-1), d)
2855 self.assertRaises(TypeError, c.abs, '-1')
2856
2857 def test_add(self):
2858 Decimal = self.decimal.Decimal
2859 Context = self.decimal.Context
2860
2861 c = Context()
2862 d = c.add(Decimal(1), Decimal(1))
2863 self.assertEqual(c.add(1, 1), d)
2864 self.assertEqual(c.add(Decimal(1), 1), d)
2865 self.assertEqual(c.add(1, Decimal(1)), d)
2866 self.assertRaises(TypeError, c.add, '1', 1)
2867 self.assertRaises(TypeError, c.add, 1, '1')
2868
2869 def test_compare(self):
2870 Decimal = self.decimal.Decimal
2871 Context = self.decimal.Context
2872
2873 c = Context()
2874 d = c.compare(Decimal(1), Decimal(1))
2875 self.assertEqual(c.compare(1, 1), d)
2876 self.assertEqual(c.compare(Decimal(1), 1), d)
2877 self.assertEqual(c.compare(1, Decimal(1)), d)
2878 self.assertRaises(TypeError, c.compare, '1', 1)
2879 self.assertRaises(TypeError, c.compare, 1, '1')
2880
2881 def test_compare_signal(self):
2882 Decimal = self.decimal.Decimal
2883 Context = self.decimal.Context
2884
2885 c = Context()
2886 d = c.compare_signal(Decimal(1), Decimal(1))
2887 self.assertEqual(c.compare_signal(1, 1), d)
2888 self.assertEqual(c.compare_signal(Decimal(1), 1), d)
2889 self.assertEqual(c.compare_signal(1, Decimal(1)), d)
2890 self.assertRaises(TypeError, c.compare_signal, '1', 1)
2891 self.assertRaises(TypeError, c.compare_signal, 1, '1')
2892
2893 def test_compare_total(self):
2894 Decimal = self.decimal.Decimal
2895 Context = self.decimal.Context
2896
2897 c = Context()
2898 d = c.compare_total(Decimal(1), Decimal(1))
2899 self.assertEqual(c.compare_total(1, 1), d)
2900 self.assertEqual(c.compare_total(Decimal(1), 1), d)
2901 self.assertEqual(c.compare_total(1, Decimal(1)), d)
2902 self.assertRaises(TypeError, c.compare_total, '1', 1)
2903 self.assertRaises(TypeError, c.compare_total, 1, '1')
2904
2905 def test_compare_total_mag(self):
2906 Decimal = self.decimal.Decimal
2907 Context = self.decimal.Context
2908
2909 c = Context()
2910 d = c.compare_total_mag(Decimal(1), Decimal(1))
2911 self.assertEqual(c.compare_total_mag(1, 1), d)
2912 self.assertEqual(c.compare_total_mag(Decimal(1), 1), d)
2913 self.assertEqual(c.compare_total_mag(1, Decimal(1)), d)
2914 self.assertRaises(TypeError, c.compare_total_mag, '1', 1)
2915 self.assertRaises(TypeError, c.compare_total_mag, 1, '1')
2916
2917 def test_copy_abs(self):
2918 Decimal = self.decimal.Decimal
2919 Context = self.decimal.Context
2920
2921 c = Context()
2922 d = c.copy_abs(Decimal(-1))
2923 self.assertEqual(c.copy_abs(-1), d)
2924 self.assertRaises(TypeError, c.copy_abs, '-1')
2925
2926 def test_copy_decimal(self):
2927 Decimal = self.decimal.Decimal
2928 Context = self.decimal.Context
2929
2930 c = Context()
2931 d = c.copy_decimal(Decimal(-1))
2932 self.assertEqual(c.copy_decimal(-1), d)
2933 self.assertRaises(TypeError, c.copy_decimal, '-1')
2934
2935 def test_copy_negate(self):
2936 Decimal = self.decimal.Decimal
2937 Context = self.decimal.Context
2938
2939 c = Context()
2940 d = c.copy_negate(Decimal(-1))
2941 self.assertEqual(c.copy_negate(-1), d)
2942 self.assertRaises(TypeError, c.copy_negate, '-1')
2943
2944 def test_copy_sign(self):
2945 Decimal = self.decimal.Decimal
2946 Context = self.decimal.Context
2947
2948 c = Context()
2949 d = c.copy_sign(Decimal(1), Decimal(-2))
2950 self.assertEqual(c.copy_sign(1, -2), d)
2951 self.assertEqual(c.copy_sign(Decimal(1), -2), d)
2952 self.assertEqual(c.copy_sign(1, Decimal(-2)), d)
2953 self.assertRaises(TypeError, c.copy_sign, '1', -2)
2954 self.assertRaises(TypeError, c.copy_sign, 1, '-2')
2955
2956 def test_divide(self):
2957 Decimal = self.decimal.Decimal
2958 Context = self.decimal.Context
2959
2960 c = Context()
2961 d = c.divide(Decimal(1), Decimal(2))
2962 self.assertEqual(c.divide(1, 2), d)
2963 self.assertEqual(c.divide(Decimal(1), 2), d)
2964 self.assertEqual(c.divide(1, Decimal(2)), d)
2965 self.assertRaises(TypeError, c.divide, '1', 2)
2966 self.assertRaises(TypeError, c.divide, 1, '2')
2967
2968 def test_divide_int(self):
2969 Decimal = self.decimal.Decimal
2970 Context = self.decimal.Context
2971
2972 c = Context()
2973 d = c.divide_int(Decimal(1), Decimal(2))
2974 self.assertEqual(c.divide_int(1, 2), d)
2975 self.assertEqual(c.divide_int(Decimal(1), 2), d)
2976 self.assertEqual(c.divide_int(1, Decimal(2)), d)
2977 self.assertRaises(TypeError, c.divide_int, '1', 2)
2978 self.assertRaises(TypeError, c.divide_int, 1, '2')
2979
2980 def test_divmod(self):
2981 Decimal = self.decimal.Decimal
2982 Context = self.decimal.Context
2983
2984 c = Context()
2985 d = c.divmod(Decimal(1), Decimal(2))
2986 self.assertEqual(c.divmod(1, 2), d)
2987 self.assertEqual(c.divmod(Decimal(1), 2), d)
2988 self.assertEqual(c.divmod(1, Decimal(2)), d)
2989 self.assertRaises(TypeError, c.divmod, '1', 2)
2990 self.assertRaises(TypeError, c.divmod, 1, '2')
2991
2992 def test_exp(self):
2993 Decimal = self.decimal.Decimal
2994 Context = self.decimal.Context
2995
2996 c = Context()
2997 d = c.exp(Decimal(10))
2998 self.assertEqual(c.exp(10), d)
2999 self.assertRaises(TypeError, c.exp, '10')
3000
3001 def test_fma(self):
3002 Decimal = self.decimal.Decimal
3003 Context = self.decimal.Context
3004
3005 c = Context()
3006 d = c.fma(Decimal(2), Decimal(3), Decimal(4))
3007 self.assertEqual(c.fma(2, 3, 4), d)
3008 self.assertEqual(c.fma(Decimal(2), 3, 4), d)
3009 self.assertEqual(c.fma(2, Decimal(3), 4), d)
3010 self.assertEqual(c.fma(2, 3, Decimal(4)), d)
3011 self.assertEqual(c.fma(Decimal(2), Decimal(3), 4), d)
3012 self.assertRaises(TypeError, c.fma, '2', 3, 4)
3013 self.assertRaises(TypeError, c.fma, 2, '3', 4)
3014 self.assertRaises(TypeError, c.fma, 2, 3, '4')
3015
3016 # Issue 12079 for Context.fma ...
3017 self.assertRaises(TypeError, c.fma,
3018 Decimal('Infinity'), Decimal(0), "not a decimal")
3019 self.assertRaises(TypeError, c.fma,
3020 Decimal(1), Decimal('snan'), 1.222)
3021 # ... and for Decimal.fma.
3022 self.assertRaises(TypeError, Decimal('Infinity').fma,
3023 Decimal(0), "not a decimal")
3024 self.assertRaises(TypeError, Decimal(1).fma,
3025 Decimal('snan'), 1.222)
3026
3027 def test_is_finite(self):
3028 Decimal = self.decimal.Decimal
3029 Context = self.decimal.Context
3030
3031 c = Context()
3032 d = c.is_finite(Decimal(10))
3033 self.assertEqual(c.is_finite(10), d)
3034 self.assertRaises(TypeError, c.is_finite, '10')
3035
3036 def test_is_infinite(self):
3037 Decimal = self.decimal.Decimal
3038 Context = self.decimal.Context
3039
3040 c = Context()
3041 d = c.is_infinite(Decimal(10))
3042 self.assertEqual(c.is_infinite(10), d)
3043 self.assertRaises(TypeError, c.is_infinite, '10')
3044
3045 def test_is_nan(self):
3046 Decimal = self.decimal.Decimal
3047 Context = self.decimal.Context
3048
3049 c = Context()
3050 d = c.is_nan(Decimal(10))
3051 self.assertEqual(c.is_nan(10), d)
3052 self.assertRaises(TypeError, c.is_nan, '10')
3053
3054 def test_is_normal(self):
3055 Decimal = self.decimal.Decimal
3056 Context = self.decimal.Context
3057
3058 c = Context()
3059 d = c.is_normal(Decimal(10))
3060 self.assertEqual(c.is_normal(10), d)
3061 self.assertRaises(TypeError, c.is_normal, '10')
3062
3063 def test_is_qnan(self):
3064 Decimal = self.decimal.Decimal
3065 Context = self.decimal.Context
3066
3067 c = Context()
3068 d = c.is_qnan(Decimal(10))
3069 self.assertEqual(c.is_qnan(10), d)
3070 self.assertRaises(TypeError, c.is_qnan, '10')
3071
3072 def test_is_signed(self):
3073 Decimal = self.decimal.Decimal
3074 Context = self.decimal.Context
3075
3076 c = Context()
3077 d = c.is_signed(Decimal(10))
3078 self.assertEqual(c.is_signed(10), d)
3079 self.assertRaises(TypeError, c.is_signed, '10')
3080
3081 def test_is_snan(self):
3082 Decimal = self.decimal.Decimal
3083 Context = self.decimal.Context
3084
3085 c = Context()
3086 d = c.is_snan(Decimal(10))
3087 self.assertEqual(c.is_snan(10), d)
3088 self.assertRaises(TypeError, c.is_snan, '10')
3089
3090 def test_is_subnormal(self):
3091 Decimal = self.decimal.Decimal
3092 Context = self.decimal.Context
3093
3094 c = Context()
3095 d = c.is_subnormal(Decimal(10))
3096 self.assertEqual(c.is_subnormal(10), d)
3097 self.assertRaises(TypeError, c.is_subnormal, '10')
3098
3099 def test_is_zero(self):
3100 Decimal = self.decimal.Decimal
3101 Context = self.decimal.Context
3102
3103 c = Context()
3104 d = c.is_zero(Decimal(10))
3105 self.assertEqual(c.is_zero(10), d)
3106 self.assertRaises(TypeError, c.is_zero, '10')
3107
3108 def test_ln(self):
3109 Decimal = self.decimal.Decimal
3110 Context = self.decimal.Context
3111
3112 c = Context()
3113 d = c.ln(Decimal(10))
3114 self.assertEqual(c.ln(10), d)
3115 self.assertRaises(TypeError, c.ln, '10')
3116
3117 def test_log10(self):
3118 Decimal = self.decimal.Decimal
3119 Context = self.decimal.Context
3120
3121 c = Context()
3122 d = c.log10(Decimal(10))
3123 self.assertEqual(c.log10(10), d)
3124 self.assertRaises(TypeError, c.log10, '10')
3125
3126 def test_logb(self):
3127 Decimal = self.decimal.Decimal
3128 Context = self.decimal.Context
3129
3130 c = Context()
3131 d = c.logb(Decimal(10))
3132 self.assertEqual(c.logb(10), d)
3133 self.assertRaises(TypeError, c.logb, '10')
3134
3135 def test_logical_and(self):
3136 Decimal = self.decimal.Decimal
3137 Context = self.decimal.Context
3138
3139 c = Context()
3140 d = c.logical_and(Decimal(1), Decimal(1))
3141 self.assertEqual(c.logical_and(1, 1), d)
3142 self.assertEqual(c.logical_and(Decimal(1), 1), d)
3143 self.assertEqual(c.logical_and(1, Decimal(1)), d)
3144 self.assertRaises(TypeError, c.logical_and, '1', 1)
3145 self.assertRaises(TypeError, c.logical_and, 1, '1')
3146
3147 def test_logical_invert(self):
3148 Decimal = self.decimal.Decimal
3149 Context = self.decimal.Context
3150
3151 c = Context()
3152 d = c.logical_invert(Decimal(1000))
3153 self.assertEqual(c.logical_invert(1000), d)
3154 self.assertRaises(TypeError, c.logical_invert, '1000')
3155
3156 def test_logical_or(self):
3157 Decimal = self.decimal.Decimal
3158 Context = self.decimal.Context
3159
3160 c = Context()
3161 d = c.logical_or(Decimal(1), Decimal(1))
3162 self.assertEqual(c.logical_or(1, 1), d)
3163 self.assertEqual(c.logical_or(Decimal(1), 1), d)
3164 self.assertEqual(c.logical_or(1, Decimal(1)), d)
3165 self.assertRaises(TypeError, c.logical_or, '1', 1)
3166 self.assertRaises(TypeError, c.logical_or, 1, '1')
3167
3168 def test_logical_xor(self):
3169 Decimal = self.decimal.Decimal
3170 Context = self.decimal.Context
3171
3172 c = Context()
3173 d = c.logical_xor(Decimal(1), Decimal(1))
3174 self.assertEqual(c.logical_xor(1, 1), d)
3175 self.assertEqual(c.logical_xor(Decimal(1), 1), d)
3176 self.assertEqual(c.logical_xor(1, Decimal(1)), d)
3177 self.assertRaises(TypeError, c.logical_xor, '1', 1)
3178 self.assertRaises(TypeError, c.logical_xor, 1, '1')
3179
3180 def test_max(self):
3181 Decimal = self.decimal.Decimal
3182 Context = self.decimal.Context
3183
3184 c = Context()
3185 d = c.max(Decimal(1), Decimal(2))
3186 self.assertEqual(c.max(1, 2), d)
3187 self.assertEqual(c.max(Decimal(1), 2), d)
3188 self.assertEqual(c.max(1, Decimal(2)), d)
3189 self.assertRaises(TypeError, c.max, '1', 2)
3190 self.assertRaises(TypeError, c.max, 1, '2')
3191
3192 def test_max_mag(self):
3193 Decimal = self.decimal.Decimal
3194 Context = self.decimal.Context
3195
3196 c = Context()
3197 d = c.max_mag(Decimal(1), Decimal(2))
3198 self.assertEqual(c.max_mag(1, 2), d)
3199 self.assertEqual(c.max_mag(Decimal(1), 2), d)
3200 self.assertEqual(c.max_mag(1, Decimal(2)), d)
3201 self.assertRaises(TypeError, c.max_mag, '1', 2)
3202 self.assertRaises(TypeError, c.max_mag, 1, '2')
3203
3204 def test_min(self):
3205 Decimal = self.decimal.Decimal
3206 Context = self.decimal.Context
3207
3208 c = Context()
3209 d = c.min(Decimal(1), Decimal(2))
3210 self.assertEqual(c.min(1, 2), d)
3211 self.assertEqual(c.min(Decimal(1), 2), d)
3212 self.assertEqual(c.min(1, Decimal(2)), d)
3213 self.assertRaises(TypeError, c.min, '1', 2)
3214 self.assertRaises(TypeError, c.min, 1, '2')
3215
3216 def test_min_mag(self):
3217 Decimal = self.decimal.Decimal
3218 Context = self.decimal.Context
3219
3220 c = Context()
3221 d = c.min_mag(Decimal(1), Decimal(2))
3222 self.assertEqual(c.min_mag(1, 2), d)
3223 self.assertEqual(c.min_mag(Decimal(1), 2), d)
3224 self.assertEqual(c.min_mag(1, Decimal(2)), d)
3225 self.assertRaises(TypeError, c.min_mag, '1', 2)
3226 self.assertRaises(TypeError, c.min_mag, 1, '2')
3227
3228 def test_minus(self):
3229 Decimal = self.decimal.Decimal
3230 Context = self.decimal.Context
3231
3232 c = Context()
3233 d = c.minus(Decimal(10))
3234 self.assertEqual(c.minus(10), d)
3235 self.assertRaises(TypeError, c.minus, '10')
3236
3237 def test_multiply(self):
3238 Decimal = self.decimal.Decimal
3239 Context = self.decimal.Context
3240
3241 c = Context()
3242 d = c.multiply(Decimal(1), Decimal(2))
3243 self.assertEqual(c.multiply(1, 2), d)
3244 self.assertEqual(c.multiply(Decimal(1), 2), d)
3245 self.assertEqual(c.multiply(1, Decimal(2)), d)
3246 self.assertRaises(TypeError, c.multiply, '1', 2)
3247 self.assertRaises(TypeError, c.multiply, 1, '2')
3248
3249 def test_next_minus(self):
3250 Decimal = self.decimal.Decimal
3251 Context = self.decimal.Context
3252
3253 c = Context()
3254 d = c.next_minus(Decimal(10))
3255 self.assertEqual(c.next_minus(10), d)
3256 self.assertRaises(TypeError, c.next_minus, '10')
3257
3258 def test_next_plus(self):
3259 Decimal = self.decimal.Decimal
3260 Context = self.decimal.Context
3261
3262 c = Context()
3263 d = c.next_plus(Decimal(10))
3264 self.assertEqual(c.next_plus(10), d)
3265 self.assertRaises(TypeError, c.next_plus, '10')
3266
3267 def test_next_toward(self):
3268 Decimal = self.decimal.Decimal
3269 Context = self.decimal.Context
3270
3271 c = Context()
3272 d = c.next_toward(Decimal(1), Decimal(2))
3273 self.assertEqual(c.next_toward(1, 2), d)
3274 self.assertEqual(c.next_toward(Decimal(1), 2), d)
3275 self.assertEqual(c.next_toward(1, Decimal(2)), d)
3276 self.assertRaises(TypeError, c.next_toward, '1', 2)
3277 self.assertRaises(TypeError, c.next_toward, 1, '2')
3278
3279 def test_normalize(self):
3280 Decimal = self.decimal.Decimal
3281 Context = self.decimal.Context
3282
3283 c = Context()
3284 d = c.normalize(Decimal(10))
3285 self.assertEqual(c.normalize(10), d)
3286 self.assertRaises(TypeError, c.normalize, '10')
3287
3288 def test_number_class(self):
3289 Decimal = self.decimal.Decimal
3290 Context = self.decimal.Context
3291
3292 c = Context()
3293 self.assertEqual(c.number_class(123), c.number_class(Decimal(123)))
3294 self.assertEqual(c.number_class(0), c.number_class(Decimal(0)))
3295 self.assertEqual(c.number_class(-45), c.number_class(Decimal(-45)))
3296
3297 def test_plus(self):
3298 Decimal = self.decimal.Decimal
3299 Context = self.decimal.Context
3300
3301 c = Context()
3302 d = c.plus(Decimal(10))
3303 self.assertEqual(c.plus(10), d)
3304 self.assertRaises(TypeError, c.plus, '10')
3305
3306 def test_power(self):
3307 Decimal = self.decimal.Decimal
3308 Context = self.decimal.Context
3309
3310 c = Context()
3311 d = c.power(Decimal(1), Decimal(4))
3312 self.assertEqual(c.power(1, 4), d)
3313 self.assertEqual(c.power(Decimal(1), 4), d)
3314 self.assertEqual(c.power(1, Decimal(4)), d)
3315 self.assertEqual(c.power(Decimal(1), Decimal(4)), d)
3316 self.assertRaises(TypeError, c.power, '1', 4)
3317 self.assertRaises(TypeError, c.power, 1, '4')
3318 self.assertEqual(c.power(modulo=5, b=8, a=2), 1)
3319
3320 def test_quantize(self):
3321 Decimal = self.decimal.Decimal
3322 Context = self.decimal.Context
3323
3324 c = Context()
3325 d = c.quantize(Decimal(1), Decimal(2))
3326 self.assertEqual(c.quantize(1, 2), d)
3327 self.assertEqual(c.quantize(Decimal(1), 2), d)
3328 self.assertEqual(c.quantize(1, Decimal(2)), d)
3329 self.assertRaises(TypeError, c.quantize, '1', 2)
3330 self.assertRaises(TypeError, c.quantize, 1, '2')
3331
3332 def test_remainder(self):
3333 Decimal = self.decimal.Decimal
3334 Context = self.decimal.Context
3335
3336 c = Context()
3337 d = c.remainder(Decimal(1), Decimal(2))
3338 self.assertEqual(c.remainder(1, 2), d)
3339 self.assertEqual(c.remainder(Decimal(1), 2), d)
3340 self.assertEqual(c.remainder(1, Decimal(2)), d)
3341 self.assertRaises(TypeError, c.remainder, '1', 2)
3342 self.assertRaises(TypeError, c.remainder, 1, '2')
3343
3344 def test_remainder_near(self):
3345 Decimal = self.decimal.Decimal
3346 Context = self.decimal.Context
3347
3348 c = Context()
3349 d = c.remainder_near(Decimal(1), Decimal(2))
3350 self.assertEqual(c.remainder_near(1, 2), d)
3351 self.assertEqual(c.remainder_near(Decimal(1), 2), d)
3352 self.assertEqual(c.remainder_near(1, Decimal(2)), d)
3353 self.assertRaises(TypeError, c.remainder_near, '1', 2)
3354 self.assertRaises(TypeError, c.remainder_near, 1, '2')
3355
3356 def test_rotate(self):
3357 Decimal = self.decimal.Decimal
3358 Context = self.decimal.Context
3359
3360 c = Context()
3361 d = c.rotate(Decimal(1), Decimal(2))
3362 self.assertEqual(c.rotate(1, 2), d)
3363 self.assertEqual(c.rotate(Decimal(1), 2), d)
3364 self.assertEqual(c.rotate(1, Decimal(2)), d)
3365 self.assertRaises(TypeError, c.rotate, '1', 2)
3366 self.assertRaises(TypeError, c.rotate, 1, '2')
3367
3368 def test_sqrt(self):
3369 Decimal = self.decimal.Decimal
3370 Context = self.decimal.Context
3371
3372 c = Context()
3373 d = c.sqrt(Decimal(10))
3374 self.assertEqual(c.sqrt(10), d)
3375 self.assertRaises(TypeError, c.sqrt, '10')
3376
3377 def test_same_quantum(self):
3378 Decimal = self.decimal.Decimal
3379 Context = self.decimal.Context
3380
3381 c = Context()
3382 d = c.same_quantum(Decimal(1), Decimal(2))
3383 self.assertEqual(c.same_quantum(1, 2), d)
3384 self.assertEqual(c.same_quantum(Decimal(1), 2), d)
3385 self.assertEqual(c.same_quantum(1, Decimal(2)), d)
3386 self.assertRaises(TypeError, c.same_quantum, '1', 2)
3387 self.assertRaises(TypeError, c.same_quantum, 1, '2')
3388
3389 def test_scaleb(self):
3390 Decimal = self.decimal.Decimal
3391 Context = self.decimal.Context
3392
3393 c = Context()
3394 d = c.scaleb(Decimal(1), Decimal(2))
3395 self.assertEqual(c.scaleb(1, 2), d)
3396 self.assertEqual(c.scaleb(Decimal(1), 2), d)
3397 self.assertEqual(c.scaleb(1, Decimal(2)), d)
3398 self.assertRaises(TypeError, c.scaleb, '1', 2)
3399 self.assertRaises(TypeError, c.scaleb, 1, '2')
3400
3401 def test_shift(self):
3402 Decimal = self.decimal.Decimal
3403 Context = self.decimal.Context
3404
3405 c = Context()
3406 d = c.shift(Decimal(1), Decimal(2))
3407 self.assertEqual(c.shift(1, 2), d)
3408 self.assertEqual(c.shift(Decimal(1), 2), d)
3409 self.assertEqual(c.shift(1, Decimal(2)), d)
3410 self.assertRaises(TypeError, c.shift, '1', 2)
3411 self.assertRaises(TypeError, c.shift, 1, '2')
3412
3413 def test_subtract(self):
3414 Decimal = self.decimal.Decimal
3415 Context = self.decimal.Context
3416
3417 c = Context()
3418 d = c.subtract(Decimal(1), Decimal(2))
3419 self.assertEqual(c.subtract(1, 2), d)
3420 self.assertEqual(c.subtract(Decimal(1), 2), d)
3421 self.assertEqual(c.subtract(1, Decimal(2)), d)
3422 self.assertRaises(TypeError, c.subtract, '1', 2)
3423 self.assertRaises(TypeError, c.subtract, 1, '2')
3424
3425 def test_to_eng_string(self):
3426 Decimal = self.decimal.Decimal
3427 Context = self.decimal.Context
3428
3429 c = Context()
3430 d = c.to_eng_string(Decimal(10))
3431 self.assertEqual(c.to_eng_string(10), d)
3432 self.assertRaises(TypeError, c.to_eng_string, '10')
3433
3434 def test_to_sci_string(self):
3435 Decimal = self.decimal.Decimal
3436 Context = self.decimal.Context
3437
3438 c = Context()
3439 d = c.to_sci_string(Decimal(10))
3440 self.assertEqual(c.to_sci_string(10), d)
3441 self.assertRaises(TypeError, c.to_sci_string, '10')
3442
3443 def test_to_integral_exact(self):
3444 Decimal = self.decimal.Decimal
3445 Context = self.decimal.Context
3446
3447 c = Context()
3448 d = c.to_integral_exact(Decimal(10))
3449 self.assertEqual(c.to_integral_exact(10), d)
3450 self.assertRaises(TypeError, c.to_integral_exact, '10')
3451
3452 def test_to_integral_value(self):
3453 Decimal = self.decimal.Decimal
3454 Context = self.decimal.Context
3455
3456 c = Context()
3457 d = c.to_integral_value(Decimal(10))
3458 self.assertEqual(c.to_integral_value(10), d)
3459 self.assertRaises(TypeError, c.to_integral_value, '10')
3460 self.assertRaises(TypeError, c.to_integral_value, 10, 'x')
3461
3462class CContextAPItests(ContextAPItests):
3463 decimal = C
3464class PyContextAPItests(ContextAPItests):
3465 decimal = P
3466
3467class ContextWithStatement(unittest.TestCase):
3468 # Can't do these as docstrings until Python 2.6
3469 # as doctest can't handle __future__ statements
3470
3471 def test_localcontext(self):
3472 # Use a copy of the current context in the block
3473 getcontext = self.decimal.getcontext
3474 localcontext = self.decimal.localcontext
3475
3476 orig_ctx = getcontext()
3477 with localcontext() as enter_ctx:
3478 set_ctx = getcontext()
3479 final_ctx = getcontext()
3480 self.assertIs(orig_ctx, final_ctx, 'did not restore context correctly')
3481 self.assertIsNot(orig_ctx, set_ctx, 'did not copy the context')
3482 self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context')
3483
3484 def test_localcontextarg(self):
3485 # Use a copy of the supplied context in the block
3486 Context = self.decimal.Context
3487 getcontext = self.decimal.getcontext
3488 localcontext = self.decimal.localcontext
3489
3490 localcontext = self.decimal.localcontext
3491 orig_ctx = getcontext()
3492 new_ctx = Context(prec=42)
3493 with localcontext(new_ctx) as enter_ctx:
3494 set_ctx = getcontext()
3495 final_ctx = getcontext()
3496 self.assertIs(orig_ctx, final_ctx, 'did not restore context correctly')
3497 self.assertEqual(set_ctx.prec, new_ctx.prec, 'did not set correct context')
3498 self.assertIsNot(new_ctx, set_ctx, 'did not copy the context')
3499 self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context')
3500
3501 def test_nested_with_statements(self):
3502 # Use a copy of the supplied context in the block
3503 Decimal = self.decimal.Decimal
3504 Context = self.decimal.Context
3505 getcontext = self.decimal.getcontext
3506 localcontext = self.decimal.localcontext
3507 Clamped = self.decimal.Clamped
3508 Overflow = self.decimal.Overflow
3509
3510 orig_ctx = getcontext()
3511 orig_ctx.clear_flags()
3512 new_ctx = Context(Emax=384)
3513 with localcontext() as c1:
3514 self.assertEqual(c1.flags, orig_ctx.flags)
3515 self.assertEqual(c1.traps, orig_ctx.traps)
3516 c1.traps[Clamped] = True
3517 c1.Emin = -383
3518 self.assertNotEqual(orig_ctx.Emin, -383)
3519 self.assertRaises(Clamped, c1.create_decimal, '0e-999')
3520 self.assertTrue(c1.flags[Clamped])
3521 with localcontext(new_ctx) as c2:
3522 self.assertEqual(c2.flags, new_ctx.flags)
3523 self.assertEqual(c2.traps, new_ctx.traps)
3524 self.assertRaises(Overflow, c2.power, Decimal('3.4e200'), 2)
3525 self.assertFalse(c2.flags[Clamped])
3526 self.assertTrue(c2.flags[Overflow])
3527 del c2
3528 self.assertFalse(c1.flags[Overflow])
3529 del c1
3530 self.assertNotEqual(orig_ctx.Emin, -383)
3531 self.assertFalse(orig_ctx.flags[Clamped])
3532 self.assertFalse(orig_ctx.flags[Overflow])
3533 self.assertFalse(new_ctx.flags[Clamped])
3534 self.assertFalse(new_ctx.flags[Overflow])
3535
3536 def test_with_statements_gc1(self):
3537 localcontext = self.decimal.localcontext
3538
3539 with localcontext() as c1:
3540 del c1
3541 with localcontext() as c2:
3542 del c2
3543 with localcontext() as c3:
3544 del c3
3545 with localcontext() as c4:
3546 del c4
3547
3548 def test_with_statements_gc2(self):
3549 localcontext = self.decimal.localcontext
3550
3551 with localcontext() as c1:
3552 with localcontext(c1) as c2:
3553 del c1
3554 with localcontext(c2) as c3:
3555 del c2
3556 with localcontext(c3) as c4:
3557 del c3
3558 del c4
3559
3560 def test_with_statements_gc3(self):
3561 Context = self.decimal.Context
3562 localcontext = self.decimal.localcontext
3563 getcontext = self.decimal.getcontext
3564 setcontext = self.decimal.setcontext
3565
3566 with localcontext() as c1:
3567 del c1
3568 n1 = Context(prec=1)
3569 setcontext(n1)
3570 with localcontext(n1) as c2:
3571 del n1
3572 self.assertEqual(c2.prec, 1)
3573 del c2
3574 n2 = Context(prec=2)
3575 setcontext(n2)
3576 del n2
3577 self.assertEqual(getcontext().prec, 2)
3578 n3 = Context(prec=3)
3579 setcontext(n3)
3580 self.assertEqual(getcontext().prec, 3)
3581 with localcontext(n3) as c3:
3582 del n3
3583 self.assertEqual(c3.prec, 3)
3584 del c3
3585 n4 = Context(prec=4)
3586 setcontext(n4)
3587 del n4
3588 self.assertEqual(getcontext().prec, 4)
3589 with localcontext() as c4:
3590 self.assertEqual(c4.prec, 4)
3591 del c4
3592
3593class CContextWithStatement(ContextWithStatement):
3594 decimal = C
3595class PyContextWithStatement(ContextWithStatement):
3596 decimal = P
3597
3598class ContextFlags(unittest.TestCase):
3599
3600 def test_flags_irrelevant(self):
3601 # check that the result (numeric result + flags raised) of an
3602 # arithmetic operation doesn't depend on the current flags
3603 Decimal = self.decimal.Decimal
3604 Context = self.decimal.Context
3605 Inexact = self.decimal.Inexact
3606 Rounded = self.decimal.Rounded
3607 Underflow = self.decimal.Underflow
3608 Clamped = self.decimal.Clamped
3609 Subnormal = self.decimal.Subnormal
Stefan Krah1919b7e2012-03-21 18:25:23 +01003610
3611 def raise_error(context, flag):
3612 if self.decimal == C:
3613 context.flags[flag] = True
3614 if context.traps[flag]:
3615 raise flag
3616 else:
3617 context._raise_error(flag)
3618
3619 context = Context(prec=9, Emin = -425000000, Emax = 425000000,
3620 rounding=ROUND_HALF_EVEN, traps=[], flags=[])
3621
3622 # operations that raise various flags, in the form (function, arglist)
3623 operations = [
3624 (context._apply, [Decimal("100E-425000010")]),
3625 (context.sqrt, [Decimal(2)]),
3626 (context.add, [Decimal("1.23456789"), Decimal("9.87654321")]),
3627 (context.multiply, [Decimal("1.23456789"), Decimal("9.87654321")]),
3628 (context.subtract, [Decimal("1.23456789"), Decimal("9.87654321")]),
3629 ]
3630
3631 # try various flags individually, then a whole lot at once
3632 flagsets = [[Inexact], [Rounded], [Underflow], [Clamped], [Subnormal],
3633 [Inexact, Rounded, Underflow, Clamped, Subnormal]]
3634
3635 for fn, args in operations:
3636 # find answer and flags raised using a clean context
3637 context.clear_flags()
3638 ans = fn(*args)
3639 flags = [k for k, v in context.flags.items() if v]
3640
3641 for extra_flags in flagsets:
3642 # set flags, before calling operation
3643 context.clear_flags()
3644 for flag in extra_flags:
3645 raise_error(context, flag)
3646 new_ans = fn(*args)
3647
3648 # flags that we expect to be set after the operation
3649 expected_flags = list(flags)
3650 for flag in extra_flags:
3651 if flag not in expected_flags:
3652 expected_flags.append(flag)
3653 expected_flags.sort(key=id)
3654
3655 # flags we actually got
3656 new_flags = [k for k,v in context.flags.items() if v]
3657 new_flags.sort(key=id)
3658
3659 self.assertEqual(ans, new_ans,
3660 "operation produces different answers depending on flags set: " +
3661 "expected %s, got %s." % (ans, new_ans))
3662 self.assertEqual(new_flags, expected_flags,
3663 "operation raises different flags depending on flags set: " +
3664 "expected %s, got %s" % (expected_flags, new_flags))
3665
3666 def test_flag_comparisons(self):
3667 Context = self.decimal.Context
3668 Inexact = self.decimal.Inexact
3669 Rounded = self.decimal.Rounded
3670
3671 c = Context()
3672
3673 # Valid SignalDict
3674 self.assertNotEqual(c.flags, c.traps)
3675 self.assertNotEqual(c.traps, c.flags)
3676
3677 c.flags = c.traps
3678 self.assertEqual(c.flags, c.traps)
3679 self.assertEqual(c.traps, c.flags)
3680
3681 c.flags[Rounded] = True
3682 c.traps = c.flags
3683 self.assertEqual(c.flags, c.traps)
3684 self.assertEqual(c.traps, c.flags)
3685
3686 d = {}
3687 d.update(c.flags)
3688 self.assertEqual(d, c.flags)
3689 self.assertEqual(c.flags, d)
3690
3691 d[Inexact] = True
3692 self.assertNotEqual(d, c.flags)
3693 self.assertNotEqual(c.flags, d)
3694
3695 # Invalid SignalDict
3696 d = {Inexact:False}
3697 self.assertNotEqual(d, c.flags)
3698 self.assertNotEqual(c.flags, d)
3699
3700 d = ["xyz"]
3701 self.assertNotEqual(d, c.flags)
3702 self.assertNotEqual(c.flags, d)
3703
3704 @requires_IEEE_754
3705 def test_float_operation(self):
3706 Decimal = self.decimal.Decimal
3707 FloatOperation = self.decimal.FloatOperation
3708 localcontext = self.decimal.localcontext
3709
3710 with localcontext() as c:
3711 ##### trap is off by default
3712 self.assertFalse(c.traps[FloatOperation])
3713
3714 # implicit conversion sets the flag
3715 c.clear_flags()
3716 self.assertEqual(Decimal(7.5), 7.5)
3717 self.assertTrue(c.flags[FloatOperation])
3718
3719 c.clear_flags()
3720 self.assertEqual(c.create_decimal(7.5), 7.5)
3721 self.assertTrue(c.flags[FloatOperation])
3722
3723 # explicit conversion does not set the flag
3724 c.clear_flags()
3725 x = Decimal.from_float(7.5)
3726 self.assertFalse(c.flags[FloatOperation])
3727 # comparison sets the flag
3728 self.assertEqual(x, 7.5)
3729 self.assertTrue(c.flags[FloatOperation])
3730
3731 c.clear_flags()
3732 x = c.create_decimal_from_float(7.5)
3733 self.assertFalse(c.flags[FloatOperation])
3734 self.assertEqual(x, 7.5)
3735 self.assertTrue(c.flags[FloatOperation])
3736
3737 ##### set the trap
3738 c.traps[FloatOperation] = True
3739
3740 # implicit conversion raises
3741 c.clear_flags()
3742 self.assertRaises(FloatOperation, Decimal, 7.5)
3743 self.assertTrue(c.flags[FloatOperation])
3744
3745 c.clear_flags()
3746 self.assertRaises(FloatOperation, c.create_decimal, 7.5)
3747 self.assertTrue(c.flags[FloatOperation])
3748
3749 # explicit conversion is silent
3750 c.clear_flags()
3751 x = Decimal.from_float(7.5)
3752 self.assertFalse(c.flags[FloatOperation])
3753
3754 c.clear_flags()
3755 x = c.create_decimal_from_float(7.5)
3756 self.assertFalse(c.flags[FloatOperation])
3757
3758 def test_float_comparison(self):
3759 Decimal = self.decimal.Decimal
3760 Context = self.decimal.Context
3761 FloatOperation = self.decimal.FloatOperation
3762 localcontext = self.decimal.localcontext
3763
3764 def assert_attr(a, b, attr, context, signal=None):
3765 context.clear_flags()
3766 f = getattr(a, attr)
3767 if signal == FloatOperation:
3768 self.assertRaises(signal, f, b)
3769 else:
3770 self.assertIs(f(b), True)
3771 self.assertTrue(context.flags[FloatOperation])
3772
3773 small_d = Decimal('0.25')
3774 big_d = Decimal('3.0')
3775 small_f = 0.25
3776 big_f = 3.0
3777
3778 zero_d = Decimal('0.0')
3779 neg_zero_d = Decimal('-0.0')
3780 zero_f = 0.0
3781 neg_zero_f = -0.0
3782
3783 inf_d = Decimal('Infinity')
3784 neg_inf_d = Decimal('-Infinity')
3785 inf_f = float('inf')
3786 neg_inf_f = float('-inf')
3787
3788 def doit(c, signal=None):
3789 # Order
3790 for attr in '__lt__', '__le__':
3791 assert_attr(small_d, big_f, attr, c, signal)
3792
3793 for attr in '__gt__', '__ge__':
3794 assert_attr(big_d, small_f, attr, c, signal)
3795
3796 # Equality
3797 assert_attr(small_d, small_f, '__eq__', c, None)
3798
3799 assert_attr(neg_zero_d, neg_zero_f, '__eq__', c, None)
3800 assert_attr(neg_zero_d, zero_f, '__eq__', c, None)
3801
3802 assert_attr(zero_d, neg_zero_f, '__eq__', c, None)
3803 assert_attr(zero_d, zero_f, '__eq__', c, None)
3804
3805 assert_attr(neg_inf_d, neg_inf_f, '__eq__', c, None)
3806 assert_attr(inf_d, inf_f, '__eq__', c, None)
3807
3808 # Inequality
3809 assert_attr(small_d, big_f, '__ne__', c, None)
3810
3811 assert_attr(Decimal('0.1'), 0.1, '__ne__', c, None)
3812
3813 assert_attr(neg_inf_d, inf_f, '__ne__', c, None)
3814 assert_attr(inf_d, neg_inf_f, '__ne__', c, None)
3815
3816 assert_attr(Decimal('NaN'), float('nan'), '__ne__', c, None)
3817
3818 def test_containers(c, signal=None):
3819 c.clear_flags()
3820 s = set([100.0, Decimal('100.0')])
3821 self.assertEqual(len(s), 1)
3822 self.assertTrue(c.flags[FloatOperation])
3823
3824 c.clear_flags()
3825 if signal:
3826 self.assertRaises(signal, sorted, [1.0, Decimal('10.0')])
3827 else:
3828 s = sorted([10.0, Decimal('10.0')])
3829 self.assertTrue(c.flags[FloatOperation])
3830
3831 c.clear_flags()
3832 b = 10.0 in [Decimal('10.0'), 1.0]
3833 self.assertTrue(c.flags[FloatOperation])
3834
3835 c.clear_flags()
3836 b = 10.0 in {Decimal('10.0'):'a', 1.0:'b'}
3837 self.assertTrue(c.flags[FloatOperation])
3838
3839 nc = Context()
3840 with localcontext(nc) as c:
3841 self.assertFalse(c.traps[FloatOperation])
3842 doit(c, signal=None)
3843 test_containers(c, signal=None)
3844
3845 c.traps[FloatOperation] = True
3846 doit(c, signal=FloatOperation)
3847 test_containers(c, signal=FloatOperation)
3848
3849 def test_float_operation_default(self):
3850 Decimal = self.decimal.Decimal
3851 Context = self.decimal.Context
3852 Inexact = self.decimal.Inexact
3853 FloatOperation= self.decimal.FloatOperation
3854
3855 context = Context()
3856 self.assertFalse(context.flags[FloatOperation])
3857 self.assertFalse(context.traps[FloatOperation])
3858
3859 context.clear_traps()
3860 context.traps[Inexact] = True
3861 context.traps[FloatOperation] = True
3862 self.assertTrue(context.traps[FloatOperation])
3863 self.assertTrue(context.traps[Inexact])
3864
3865class CContextFlags(ContextFlags):
3866 decimal = C
3867class PyContextFlags(ContextFlags):
3868 decimal = P
3869
3870class SpecialContexts(unittest.TestCase):
3871 """Test the context templates."""
3872
3873 def test_context_templates(self):
3874 BasicContext = self.decimal.BasicContext
3875 ExtendedContext = self.decimal.ExtendedContext
3876 getcontext = self.decimal.getcontext
3877 setcontext = self.decimal.setcontext
3878 InvalidOperation = self.decimal.InvalidOperation
3879 DivisionByZero = self.decimal.DivisionByZero
3880 Overflow = self.decimal.Overflow
3881 Underflow = self.decimal.Underflow
3882 Clamped = self.decimal.Clamped
3883
3884 assert_signals(self, BasicContext, 'traps',
3885 [InvalidOperation, DivisionByZero, Overflow, Underflow, Clamped]
3886 )
3887
3888 savecontext = getcontext().copy()
3889 basic_context_prec = BasicContext.prec
3890 extended_context_prec = ExtendedContext.prec
3891
3892 ex = None
3893 try:
3894 BasicContext.prec = ExtendedContext.prec = 441
3895 for template in BasicContext, ExtendedContext:
3896 setcontext(template)
3897 c = getcontext()
3898 self.assertIsNot(c, template)
3899 self.assertEqual(c.prec, 441)
3900 except Exception as e:
3901 ex = e.__class__
3902 finally:
3903 BasicContext.prec = basic_context_prec
3904 ExtendedContext.prec = extended_context_prec
3905 setcontext(savecontext)
3906 if ex:
3907 raise ex
3908
3909 def test_default_context(self):
3910 DefaultContext = self.decimal.DefaultContext
3911 BasicContext = self.decimal.BasicContext
3912 ExtendedContext = self.decimal.ExtendedContext
3913 getcontext = self.decimal.getcontext
3914 setcontext = self.decimal.setcontext
3915 InvalidOperation = self.decimal.InvalidOperation
3916 DivisionByZero = self.decimal.DivisionByZero
3917 Overflow = self.decimal.Overflow
3918
3919 self.assertEqual(BasicContext.prec, 9)
3920 self.assertEqual(ExtendedContext.prec, 9)
3921
3922 assert_signals(self, DefaultContext, 'traps',
3923 [InvalidOperation, DivisionByZero, Overflow]
3924 )
3925
3926 savecontext = getcontext().copy()
3927 default_context_prec = DefaultContext.prec
3928
3929 ex = None
3930 try:
3931 c = getcontext()
3932 saveprec = c.prec
3933
3934 DefaultContext.prec = 961
3935 c = getcontext()
3936 self.assertEqual(c.prec, saveprec)
3937
3938 setcontext(DefaultContext)
3939 c = getcontext()
3940 self.assertIsNot(c, DefaultContext)
3941 self.assertEqual(c.prec, 961)
3942 except Exception as e:
3943 ex = e.__class__
3944 finally:
3945 DefaultContext.prec = default_context_prec
3946 setcontext(savecontext)
3947 if ex:
3948 raise ex
3949
3950class CSpecialContexts(SpecialContexts):
3951 decimal = C
3952class PySpecialContexts(SpecialContexts):
3953 decimal = P
3954
3955class ContextInputValidation(unittest.TestCase):
3956
3957 def test_invalid_context(self):
3958 Context = self.decimal.Context
3959 DefaultContext = self.decimal.DefaultContext
3960
3961 c = DefaultContext.copy()
3962
3963 # prec, Emax
3964 for attr in ['prec', 'Emax']:
3965 setattr(c, attr, 999999)
3966 self.assertEqual(getattr(c, attr), 999999)
3967 self.assertRaises(ValueError, setattr, c, attr, -1)
3968 self.assertRaises(TypeError, setattr, c, attr, 'xyz')
3969
3970 # Emin
3971 setattr(c, 'Emin', -999999)
3972 self.assertEqual(getattr(c, 'Emin'), -999999)
3973 self.assertRaises(ValueError, setattr, c, 'Emin', 1)
3974 self.assertRaises(TypeError, setattr, c, 'Emin', (1,2,3))
3975
Stefan Krah1919b7e2012-03-21 18:25:23 +01003976 self.assertRaises(TypeError, setattr, c, 'rounding', -1)
3977 self.assertRaises(TypeError, setattr, c, 'rounding', 9)
3978 self.assertRaises(TypeError, setattr, c, 'rounding', 1.0)
3979 self.assertRaises(TypeError, setattr, c, 'rounding', 'xyz')
3980
3981 # capitals, clamp
3982 for attr in ['capitals', 'clamp']:
3983 self.assertRaises(ValueError, setattr, c, attr, -1)
3984 self.assertRaises(ValueError, setattr, c, attr, 2)
3985 self.assertRaises(TypeError, setattr, c, attr, [1,2,3])
3986
3987 # Invalid attribute
3988 self.assertRaises(AttributeError, setattr, c, 'emax', 100)
3989
3990 # Invalid signal dict
3991 self.assertRaises(TypeError, setattr, c, 'flags', [])
3992 self.assertRaises(KeyError, setattr, c, 'flags', {})
3993 self.assertRaises(KeyError, setattr, c, 'traps',
3994 {'InvalidOperation':0})
3995
3996 # Attributes cannot be deleted
3997 for attr in ['prec', 'Emax', 'Emin', 'rounding', 'capitals', 'clamp',
3998 'flags', 'traps']:
3999 self.assertRaises(AttributeError, c.__delattr__, attr)
4000
4001 # Invalid attributes
4002 self.assertRaises(TypeError, getattr, c, 9)
4003 self.assertRaises(TypeError, setattr, c, 9)
4004
4005 # Invalid values in constructor
4006 self.assertRaises(TypeError, Context, rounding=999999)
4007 self.assertRaises(TypeError, Context, rounding='xyz')
4008 self.assertRaises(ValueError, Context, clamp=2)
4009 self.assertRaises(ValueError, Context, capitals=-1)
4010 self.assertRaises(KeyError, Context, flags=["P"])
4011 self.assertRaises(KeyError, Context, traps=["Q"])
4012
4013 # Type error in conversion
4014 self.assertRaises(TypeError, Context, flags=(0,1))
4015 self.assertRaises(TypeError, Context, traps=(1,0))
4016
4017class CContextInputValidation(ContextInputValidation):
4018 decimal = C
4019class PyContextInputValidation(ContextInputValidation):
4020 decimal = P
4021
4022class ContextSubclassing(unittest.TestCase):
4023
4024 def test_context_subclassing(self):
4025 decimal = self.decimal
4026 Decimal = decimal.Decimal
4027 Context = decimal.Context
Stefan Krah1919b7e2012-03-21 18:25:23 +01004028 Clamped = decimal.Clamped
4029 DivisionByZero = decimal.DivisionByZero
4030 Inexact = decimal.Inexact
4031 Overflow = decimal.Overflow
4032 Rounded = decimal.Rounded
4033 Subnormal = decimal.Subnormal
4034 Underflow = decimal.Underflow
4035 InvalidOperation = decimal.InvalidOperation
4036
4037 class MyContext(Context):
4038 def __init__(self, prec=None, rounding=None, Emin=None, Emax=None,
4039 capitals=None, clamp=None, flags=None,
4040 traps=None):
4041 Context.__init__(self)
4042 if prec is not None:
4043 self.prec = prec
4044 if rounding is not None:
4045 self.rounding = rounding
4046 if Emin is not None:
4047 self.Emin = Emin
4048 if Emax is not None:
4049 self.Emax = Emax
4050 if capitals is not None:
4051 self.capitals = capitals
4052 if clamp is not None:
4053 self.clamp = clamp
4054 if flags is not None:
4055 if isinstance(flags, list):
4056 flags = {v:(v in flags) for v in OrderedSignals[decimal] + flags}
4057 self.flags = flags
4058 if traps is not None:
4059 if isinstance(traps, list):
4060 traps = {v:(v in traps) for v in OrderedSignals[decimal] + traps}
4061 self.traps = traps
4062
4063 c = Context()
4064 d = MyContext()
4065 for attr in ('prec', 'rounding', 'Emin', 'Emax', 'capitals', 'clamp',
4066 'flags', 'traps'):
4067 self.assertEqual(getattr(c, attr), getattr(d, attr))
4068
4069 # prec
4070 self.assertRaises(ValueError, MyContext, **{'prec':-1})
4071 c = MyContext(prec=1)
4072 self.assertEqual(c.prec, 1)
4073 self.assertRaises(InvalidOperation, c.quantize, Decimal('9e2'), 0)
4074
4075 # rounding
4076 self.assertRaises(TypeError, MyContext, **{'rounding':'XYZ'})
4077 c = MyContext(rounding=ROUND_DOWN, prec=1)
4078 self.assertEqual(c.rounding, ROUND_DOWN)
4079 self.assertEqual(c.plus(Decimal('9.9')), 9)
4080
4081 # Emin
4082 self.assertRaises(ValueError, MyContext, **{'Emin':5})
4083 c = MyContext(Emin=-1, prec=1)
4084 self.assertEqual(c.Emin, -1)
4085 x = c.add(Decimal('1e-99'), Decimal('2.234e-2000'))
4086 self.assertEqual(x, Decimal('0.0'))
4087 for signal in (Inexact, Underflow, Subnormal, Rounded, Clamped):
4088 self.assertTrue(c.flags[signal])
4089
4090 # Emax
4091 self.assertRaises(ValueError, MyContext, **{'Emax':-1})
4092 c = MyContext(Emax=1, prec=1)
4093 self.assertEqual(c.Emax, 1)
4094 self.assertRaises(Overflow, c.add, Decimal('1e99'), Decimal('2.234e2000'))
4095 if self.decimal == C:
4096 for signal in (Inexact, Overflow, Rounded):
4097 self.assertTrue(c.flags[signal])
4098
4099 # capitals
4100 self.assertRaises(ValueError, MyContext, **{'capitals':-1})
4101 c = MyContext(capitals=0)
4102 self.assertEqual(c.capitals, 0)
4103 x = c.create_decimal('1E222')
4104 self.assertEqual(c.to_sci_string(x), '1e+222')
4105
4106 # clamp
4107 self.assertRaises(ValueError, MyContext, **{'clamp':2})
4108 c = MyContext(clamp=1, Emax=99)
4109 self.assertEqual(c.clamp, 1)
4110 x = c.plus(Decimal('1e99'))
4111 self.assertEqual(str(x), '1.000000000000000000000000000E+99')
4112
4113 # flags
4114 self.assertRaises(TypeError, MyContext, **{'flags':'XYZ'})
4115 c = MyContext(flags=[Rounded, DivisionByZero])
4116 for signal in (Rounded, DivisionByZero):
4117 self.assertTrue(c.flags[signal])
4118 c.clear_flags()
4119 for signal in OrderedSignals[decimal]:
4120 self.assertFalse(c.flags[signal])
4121
4122 # traps
4123 self.assertRaises(TypeError, MyContext, **{'traps':'XYZ'})
4124 c = MyContext(traps=[Rounded, DivisionByZero])
4125 for signal in (Rounded, DivisionByZero):
4126 self.assertTrue(c.traps[signal])
4127 c.clear_traps()
4128 for signal in OrderedSignals[decimal]:
4129 self.assertFalse(c.traps[signal])
4130
4131class CContextSubclassing(ContextSubclassing):
4132 decimal = C
4133class PyContextSubclassing(ContextSubclassing):
4134 decimal = P
4135
4136@skip_if_extra_functionality
4137class CheckAttributes(unittest.TestCase):
4138
4139 def test_module_attributes(self):
4140
4141 # Architecture dependent context limits
4142 self.assertEqual(C.MAX_PREC, P.MAX_PREC)
4143 self.assertEqual(C.MAX_EMAX, P.MAX_EMAX)
4144 self.assertEqual(C.MIN_EMIN, P.MIN_EMIN)
4145 self.assertEqual(C.MIN_ETINY, P.MIN_ETINY)
4146
4147 self.assertTrue(C.HAVE_THREADS is True or C.HAVE_THREADS is False)
4148 self.assertTrue(P.HAVE_THREADS is True or P.HAVE_THREADS is False)
4149
4150 self.assertEqual(C.__version__, P.__version__)
Stefan Krah45059eb2013-11-24 19:44:57 +01004151 self.assertEqual(C.__libmpdec_version__, P.__libmpdec_version__)
Stefan Krah1919b7e2012-03-21 18:25:23 +01004152
4153 x = dir(C)
4154 y = [s for s in dir(P) if '__' in s or not s.startswith('_')]
Stefan Krahfe17b2b2012-03-25 18:59:21 +02004155 self.assertEqual(set(x) - set(y), set())
Stefan Krah1919b7e2012-03-21 18:25:23 +01004156
4157 def test_context_attributes(self):
4158
4159 x = [s for s in dir(C.Context()) if '__' in s or not s.startswith('_')]
4160 y = [s for s in dir(P.Context()) if '__' in s or not s.startswith('_')]
4161 self.assertEqual(set(x) - set(y), set())
4162
4163 def test_decimal_attributes(self):
4164
4165 x = [s for s in dir(C.Decimal(9)) if '__' in s or not s.startswith('_')]
4166 y = [s for s in dir(C.Decimal(9)) if '__' in s or not s.startswith('_')]
4167 self.assertEqual(set(x) - set(y), set())
4168
4169class Coverage(unittest.TestCase):
4170
4171 def test_adjusted(self):
4172 Decimal = self.decimal.Decimal
4173
4174 self.assertEqual(Decimal('1234e9999').adjusted(), 10002)
4175 # XXX raise?
4176 self.assertEqual(Decimal('nan').adjusted(), 0)
4177 self.assertEqual(Decimal('inf').adjusted(), 0)
4178
4179 def test_canonical(self):
4180 Decimal = self.decimal.Decimal
4181 getcontext = self.decimal.getcontext
4182
4183 x = Decimal(9).canonical()
4184 self.assertEqual(x, 9)
4185
4186 c = getcontext()
4187 x = c.canonical(Decimal(9))
4188 self.assertEqual(x, 9)
4189
4190 def test_context_repr(self):
4191 c = self.decimal.DefaultContext.copy()
4192
4193 c.prec = 425000000
4194 c.Emax = 425000000
4195 c.Emin = -425000000
Stefan Krah59a4a932013-01-16 12:58:59 +01004196 c.rounding = ROUND_HALF_DOWN
Stefan Krah1919b7e2012-03-21 18:25:23 +01004197 c.capitals = 0
4198 c.clamp = 1
4199 for sig in OrderedSignals[self.decimal]:
4200 c.flags[sig] = False
4201 c.traps[sig] = False
4202
4203 s = c.__repr__()
4204 t = "Context(prec=425000000, rounding=ROUND_HALF_DOWN, " \
4205 "Emin=-425000000, Emax=425000000, capitals=0, clamp=1, " \
4206 "flags=[], traps=[])"
4207 self.assertEqual(s, t)
4208
4209 def test_implicit_context(self):
4210 Decimal = self.decimal.Decimal
4211 localcontext = self.decimal.localcontext
4212
4213 with localcontext() as c:
4214 c.prec = 1
4215 c.Emax = 1
4216 c.Emin = -1
4217
4218 # abs
4219 self.assertEqual(abs(Decimal("-10")), 10)
4220 # add
4221 self.assertEqual(Decimal("7") + 1, 8)
4222 # divide
4223 self.assertEqual(Decimal("10") / 5, 2)
4224 # divide_int
4225 self.assertEqual(Decimal("10") // 7, 1)
4226 # fma
4227 self.assertEqual(Decimal("1.2").fma(Decimal("0.01"), 1), 1)
4228 self.assertIs(Decimal("NaN").fma(7, 1).is_nan(), True)
4229 # three arg power
4230 self.assertEqual(pow(Decimal(10), 2, 7), 2)
4231 # exp
4232 self.assertEqual(Decimal("1.01").exp(), 3)
4233 # is_normal
4234 self.assertIs(Decimal("0.01").is_normal(), False)
4235 # is_subnormal
4236 self.assertIs(Decimal("0.01").is_subnormal(), True)
4237 # ln
4238 self.assertEqual(Decimal("20").ln(), 3)
4239 # log10
4240 self.assertEqual(Decimal("20").log10(), 1)
4241 # logb
4242 self.assertEqual(Decimal("580").logb(), 2)
4243 # logical_invert
4244 self.assertEqual(Decimal("10").logical_invert(), 1)
4245 # minus
4246 self.assertEqual(-Decimal("-10"), 10)
4247 # multiply
4248 self.assertEqual(Decimal("2") * 4, 8)
4249 # next_minus
4250 self.assertEqual(Decimal("10").next_minus(), 9)
4251 # next_plus
4252 self.assertEqual(Decimal("10").next_plus(), Decimal('2E+1'))
4253 # normalize
4254 self.assertEqual(Decimal("-10").normalize(), Decimal('-1E+1'))
4255 # number_class
4256 self.assertEqual(Decimal("10").number_class(), '+Normal')
4257 # plus
4258 self.assertEqual(+Decimal("-1"), -1)
4259 # remainder
4260 self.assertEqual(Decimal("10") % 7, 3)
4261 # subtract
4262 self.assertEqual(Decimal("10") - 7, 3)
4263 # to_integral_exact
4264 self.assertEqual(Decimal("1.12345").to_integral_exact(), 1)
4265
4266 # Boolean functions
4267 self.assertTrue(Decimal("1").is_canonical())
4268 self.assertTrue(Decimal("1").is_finite())
4269 self.assertTrue(Decimal("1").is_finite())
4270 self.assertTrue(Decimal("snan").is_snan())
4271 self.assertTrue(Decimal("-1").is_signed())
4272 self.assertTrue(Decimal("0").is_zero())
4273 self.assertTrue(Decimal("0").is_zero())
4274
4275 # Copy
4276 with localcontext() as c:
4277 c.prec = 10000
4278 x = 1228 ** 1523
4279 y = -Decimal(x)
4280
4281 z = y.copy_abs()
4282 self.assertEqual(z, x)
4283
4284 z = y.copy_negate()
4285 self.assertEqual(z, x)
4286
4287 z = y.copy_sign(Decimal(1))
4288 self.assertEqual(z, x)
4289
4290 def test_divmod(self):
4291 Decimal = self.decimal.Decimal
4292 localcontext = self.decimal.localcontext
4293 InvalidOperation = self.decimal.InvalidOperation
4294 DivisionByZero = self.decimal.DivisionByZero
4295
4296 with localcontext() as c:
4297 q, r = divmod(Decimal("10912837129"), 1001)
4298 self.assertEqual(q, Decimal('10901935'))
4299 self.assertEqual(r, Decimal('194'))
4300
4301 q, r = divmod(Decimal("NaN"), 7)
4302 self.assertTrue(q.is_nan() and r.is_nan())
4303
4304 c.traps[InvalidOperation] = False
4305 q, r = divmod(Decimal("NaN"), 7)
4306 self.assertTrue(q.is_nan() and r.is_nan())
4307
4308 c.traps[InvalidOperation] = False
4309 c.clear_flags()
4310 q, r = divmod(Decimal("inf"), Decimal("inf"))
4311 self.assertTrue(q.is_nan() and r.is_nan())
4312 self.assertTrue(c.flags[InvalidOperation])
4313
4314 c.clear_flags()
4315 q, r = divmod(Decimal("inf"), 101)
4316 self.assertTrue(q.is_infinite() and r.is_nan())
4317 self.assertTrue(c.flags[InvalidOperation])
4318
4319 c.clear_flags()
4320 q, r = divmod(Decimal(0), 0)
4321 self.assertTrue(q.is_nan() and r.is_nan())
4322 self.assertTrue(c.flags[InvalidOperation])
4323
4324 c.traps[DivisionByZero] = False
4325 c.clear_flags()
4326 q, r = divmod(Decimal(11), 0)
4327 self.assertTrue(q.is_infinite() and r.is_nan())
4328 self.assertTrue(c.flags[InvalidOperation] and
4329 c.flags[DivisionByZero])
4330
4331 def test_power(self):
4332 Decimal = self.decimal.Decimal
4333 localcontext = self.decimal.localcontext
4334 Overflow = self.decimal.Overflow
4335 Rounded = self.decimal.Rounded
4336
4337 with localcontext() as c:
4338 c.prec = 3
4339 c.clear_flags()
4340 self.assertEqual(Decimal("1.0") ** 100, Decimal('1.00'))
4341 self.assertTrue(c.flags[Rounded])
4342
4343 c.prec = 1
4344 c.Emax = 1
4345 c.Emin = -1
4346 c.clear_flags()
4347 c.traps[Overflow] = False
4348 self.assertEqual(Decimal(10000) ** Decimal("0.5"), Decimal('inf'))
4349 self.assertTrue(c.flags[Overflow])
4350
4351 def test_quantize(self):
4352 Decimal = self.decimal.Decimal
4353 localcontext = self.decimal.localcontext
4354 InvalidOperation = self.decimal.InvalidOperation
4355
4356 with localcontext() as c:
4357 c.prec = 1
4358 c.Emax = 1
4359 c.Emin = -1
4360 c.traps[InvalidOperation] = False
4361 x = Decimal(99).quantize(Decimal("1e1"))
4362 self.assertTrue(x.is_nan())
4363
4364 def test_radix(self):
4365 Decimal = self.decimal.Decimal
4366 getcontext = self.decimal.getcontext
4367
4368 c = getcontext()
4369 self.assertEqual(Decimal("1").radix(), 10)
4370 self.assertEqual(c.radix(), 10)
4371
4372 def test_rop(self):
4373 Decimal = self.decimal.Decimal
4374
4375 for attr in ('__radd__', '__rsub__', '__rmul__', '__rtruediv__',
4376 '__rdivmod__', '__rmod__', '__rfloordiv__', '__rpow__'):
4377 self.assertIs(getattr(Decimal("1"), attr)("xyz"), NotImplemented)
4378
4379 def test_round(self):
4380 # Python3 behavior: round() returns Decimal
4381 Decimal = self.decimal.Decimal
4382 getcontext = self.decimal.getcontext
4383
4384 c = getcontext()
4385 c.prec = 28
4386
4387 self.assertEqual(str(Decimal("9.99").__round__()), "10")
4388 self.assertEqual(str(Decimal("9.99e-5").__round__()), "0")
4389 self.assertEqual(str(Decimal("1.23456789").__round__(5)), "1.23457")
4390 self.assertEqual(str(Decimal("1.2345").__round__(10)), "1.2345000000")
4391 self.assertEqual(str(Decimal("1.2345").__round__(-10)), "0E+10")
4392
4393 self.assertRaises(TypeError, Decimal("1.23").__round__, "5")
4394 self.assertRaises(TypeError, Decimal("1.23").__round__, 5, 8)
4395
4396 def test_create_decimal(self):
4397 c = self.decimal.Context()
4398 self.assertRaises(ValueError, c.create_decimal, ["%"])
4399
4400 def test_int(self):
4401 Decimal = self.decimal.Decimal
4402 localcontext = self.decimal.localcontext
4403
4404 with localcontext() as c:
4405 c.prec = 9999
4406 x = Decimal(1221**1271) / 10**3923
4407 self.assertEqual(int(x), 1)
4408 self.assertEqual(x.to_integral(), 2)
4409
4410 def test_copy(self):
4411 Context = self.decimal.Context
4412
4413 c = Context()
4414 c.prec = 10000
4415 x = -(1172 ** 1712)
4416
4417 y = c.copy_abs(x)
4418 self.assertEqual(y, -x)
4419
4420 y = c.copy_negate(x)
4421 self.assertEqual(y, -x)
4422
4423 y = c.copy_sign(x, 1)
4424 self.assertEqual(y, -x)
4425
4426class CCoverage(Coverage):
4427 decimal = C
4428class PyCoverage(Coverage):
4429 decimal = P
4430
4431class PyFunctionality(unittest.TestCase):
4432 """Extra functionality in decimal.py"""
4433
4434 def test_py_quantize_watchexp(self):
4435 # watchexp functionality
4436 Decimal = P.Decimal
4437 localcontext = P.localcontext
4438
4439 with localcontext() as c:
4440 c.prec = 1
4441 c.Emax = 1
4442 c.Emin = -1
4443 x = Decimal(99999).quantize(Decimal("1e3"), watchexp=False)
4444 self.assertEqual(x, Decimal('1.00E+5'))
4445
4446 def test_py_alternate_formatting(self):
4447 # triples giving a format, a Decimal, and the expected result
4448 Decimal = P.Decimal
4449 localcontext = P.localcontext
4450
4451 test_values = [
4452 # Issue 7094: Alternate formatting (specified by #)
4453 ('.0e', '1.0', '1e+0'),
4454 ('#.0e', '1.0', '1.e+0'),
4455 ('.0f', '1.0', '1'),
4456 ('#.0f', '1.0', '1.'),
4457 ('g', '1.1', '1.1'),
4458 ('#g', '1.1', '1.1'),
4459 ('.0g', '1', '1'),
4460 ('#.0g', '1', '1.'),
4461 ('.0%', '1.0', '100%'),
4462 ('#.0%', '1.0', '100.%'),
4463 ]
4464 for fmt, d, result in test_values:
4465 self.assertEqual(format(Decimal(d), fmt), result)
4466
4467class PyWhitebox(unittest.TestCase):
4468 """White box testing for decimal.py"""
4469
4470 def test_py_exact_power(self):
4471 # Rarely exercised lines in _power_exact.
4472 Decimal = P.Decimal
4473 localcontext = P.localcontext
4474
4475 with localcontext() as c:
4476 c.prec = 8
4477 x = Decimal(2**16) ** Decimal("-0.5")
4478 self.assertEqual(x, Decimal('0.00390625'))
4479
4480 x = Decimal(2**16) ** Decimal("-0.6")
4481 self.assertEqual(x, Decimal('0.0012885819'))
4482
4483 x = Decimal("256e7") ** Decimal("-0.5")
4484
4485 x = Decimal(152587890625) ** Decimal('-0.0625')
4486 self.assertEqual(x, Decimal("0.2"))
4487
4488 x = Decimal("152587890625e7") ** Decimal('-0.0625')
4489
4490 x = Decimal(5**2659) ** Decimal('-0.0625')
4491
4492 c.prec = 1
4493 x = Decimal("152587890625") ** Decimal('-0.5')
4494 c.prec = 201
4495 x = Decimal(2**578) ** Decimal("-0.5")
4496
4497 def test_py_immutability_operations(self):
Terry Jan Reedy0f847642013-03-11 18:34:00 -04004498 # Do operations and check that it didn't change internal objects.
Stefan Krah1919b7e2012-03-21 18:25:23 +01004499 Decimal = P.Decimal
4500 DefaultContext = P.DefaultContext
4501 setcontext = P.setcontext
4502
4503 c = DefaultContext.copy()
4504 c.traps = dict((s, 0) for s in OrderedSignals[P])
4505 setcontext(c)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004506
4507 d1 = Decimal('-25e55')
4508 b1 = Decimal('-25e55')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00004509 d2 = Decimal('33e+33')
4510 b2 = Decimal('33e+33')
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004511
4512 def checkSameDec(operation, useOther=False):
4513 if useOther:
4514 eval("d1." + operation + "(d2)")
4515 self.assertEqual(d1._sign, b1._sign)
4516 self.assertEqual(d1._int, b1._int)
4517 self.assertEqual(d1._exp, b1._exp)
4518 self.assertEqual(d2._sign, b2._sign)
4519 self.assertEqual(d2._int, b2._int)
4520 self.assertEqual(d2._exp, b2._exp)
4521 else:
4522 eval("d1." + operation + "()")
4523 self.assertEqual(d1._sign, b1._sign)
4524 self.assertEqual(d1._int, b1._int)
4525 self.assertEqual(d1._exp, b1._exp)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004526
4527 Decimal(d1)
4528 self.assertEqual(d1._sign, b1._sign)
4529 self.assertEqual(d1._int, b1._int)
4530 self.assertEqual(d1._exp, b1._exp)
4531
4532 checkSameDec("__abs__")
4533 checkSameDec("__add__", True)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004534 checkSameDec("__divmod__", True)
Christian Heimes77c02eb2008-02-09 02:18:51 +00004535 checkSameDec("__eq__", True)
4536 checkSameDec("__ne__", True)
4537 checkSameDec("__le__", True)
4538 checkSameDec("__lt__", True)
4539 checkSameDec("__ge__", True)
4540 checkSameDec("__gt__", True)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004541 checkSameDec("__float__")
4542 checkSameDec("__floordiv__", True)
4543 checkSameDec("__hash__")
4544 checkSameDec("__int__")
Christian Heimes969fe572008-01-25 11:23:10 +00004545 checkSameDec("__trunc__")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004546 checkSameDec("__mod__", True)
4547 checkSameDec("__mul__", True)
4548 checkSameDec("__neg__")
Jack Diederich4dafcc42006-11-28 19:15:13 +00004549 checkSameDec("__bool__")
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004550 checkSameDec("__pos__")
4551 checkSameDec("__pow__", True)
4552 checkSameDec("__radd__", True)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004553 checkSameDec("__rdivmod__", True)
4554 checkSameDec("__repr__")
4555 checkSameDec("__rfloordiv__", True)
4556 checkSameDec("__rmod__", True)
4557 checkSameDec("__rmul__", True)
4558 checkSameDec("__rpow__", True)
4559 checkSameDec("__rsub__", True)
4560 checkSameDec("__str__")
4561 checkSameDec("__sub__", True)
4562 checkSameDec("__truediv__", True)
4563 checkSameDec("adjusted")
4564 checkSameDec("as_tuple")
4565 checkSameDec("compare", True)
4566 checkSameDec("max", True)
4567 checkSameDec("min", True)
4568 checkSameDec("normalize")
4569 checkSameDec("quantize", True)
4570 checkSameDec("remainder_near", True)
4571 checkSameDec("same_quantum", True)
4572 checkSameDec("sqrt")
4573 checkSameDec("to_eng_string")
4574 checkSameDec("to_integral")
4575
Stefan Krah1919b7e2012-03-21 18:25:23 +01004576 def test_py_decimal_id(self):
4577 Decimal = P.Decimal
Thomas Wouters1b7f8912007-09-19 03:06:30 +00004578
Stefan Krah1919b7e2012-03-21 18:25:23 +01004579 d = Decimal(45)
4580 e = Decimal(d)
4581 self.assertEqual(str(e), '45')
4582 self.assertNotEqual(id(d), id(e))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00004583
Stefan Krah1919b7e2012-03-21 18:25:23 +01004584 def test_py_rescale(self):
4585 # Coverage
4586 Decimal = P.Decimal
Stefan Krah1919b7e2012-03-21 18:25:23 +01004587 localcontext = P.localcontext
Thomas Wouters1b7f8912007-09-19 03:06:30 +00004588
Stefan Krah1919b7e2012-03-21 18:25:23 +01004589 with localcontext() as c:
4590 x = Decimal("NaN")._rescale(3, ROUND_UP)
4591 self.assertTrue(x.is_nan())
Thomas Wouters1b7f8912007-09-19 03:06:30 +00004592
Stefan Krah1919b7e2012-03-21 18:25:23 +01004593 def test_py__round(self):
4594 # Coverage
4595 Decimal = P.Decimal
Christian Heimes0348fb62008-03-26 12:55:56 +00004596
Stefan Krah1919b7e2012-03-21 18:25:23 +01004597 self.assertRaises(ValueError, Decimal("3.1234")._round, 0, ROUND_UP)
Mark Dickinsona2d1fe02009-10-29 12:23:02 +00004598
Stefan Krah1919b7e2012-03-21 18:25:23 +01004599class CFunctionality(unittest.TestCase):
4600 """Extra functionality in _decimal"""
Mark Dickinsona2d1fe02009-10-29 12:23:02 +00004601
Stefan Krah1919b7e2012-03-21 18:25:23 +01004602 @requires_extra_functionality
4603 def test_c_ieee_context(self):
4604 # issue 8786: Add support for IEEE 754 contexts to decimal module.
4605 IEEEContext = C.IEEEContext
4606 DECIMAL32 = C.DECIMAL32
4607 DECIMAL64 = C.DECIMAL64
4608 DECIMAL128 = C.DECIMAL128
Thomas Wouters1b7f8912007-09-19 03:06:30 +00004609
Stefan Krah1919b7e2012-03-21 18:25:23 +01004610 def assert_rest(self, context):
4611 self.assertEqual(context.clamp, 1)
4612 assert_signals(self, context, 'traps', [])
4613 assert_signals(self, context, 'flags', [])
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004614
Stefan Krah1919b7e2012-03-21 18:25:23 +01004615 c = IEEEContext(DECIMAL32)
4616 self.assertEqual(c.prec, 7)
4617 self.assertEqual(c.Emax, 96)
4618 self.assertEqual(c.Emin, -95)
4619 assert_rest(self, c)
Raymond Hettinger82417ca2009-02-03 03:54:28 +00004620
Stefan Krah1919b7e2012-03-21 18:25:23 +01004621 c = IEEEContext(DECIMAL64)
4622 self.assertEqual(c.prec, 16)
4623 self.assertEqual(c.Emax, 384)
4624 self.assertEqual(c.Emin, -383)
4625 assert_rest(self, c)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00004626
Stefan Krah1919b7e2012-03-21 18:25:23 +01004627 c = IEEEContext(DECIMAL128)
4628 self.assertEqual(c.prec, 34)
4629 self.assertEqual(c.Emax, 6144)
4630 self.assertEqual(c.Emin, -6143)
4631 assert_rest(self, c)
Raymond Hettinger5548be22004-07-05 18:49:38 +00004632
Stefan Krah1919b7e2012-03-21 18:25:23 +01004633 # Invalid values
4634 self.assertRaises(OverflowError, IEEEContext, 2**63)
4635 self.assertRaises(ValueError, IEEEContext, -1)
4636 self.assertRaises(ValueError, IEEEContext, 1024)
Mark Dickinson825fce32009-09-07 18:08:12 +00004637
Stefan Krah1919b7e2012-03-21 18:25:23 +01004638 @requires_extra_functionality
4639 def test_c_context(self):
4640 Context = C.Context
Christian Heimes969fe572008-01-25 11:23:10 +00004641
Stefan Krah1919b7e2012-03-21 18:25:23 +01004642 c = Context(flags=C.DecClamped, traps=C.DecRounded)
4643 self.assertEqual(c._flags, C.DecClamped)
4644 self.assertEqual(c._traps, C.DecRounded)
Raymond Hettinger771ed762009-01-03 19:20:32 +00004645
Stefan Krah1919b7e2012-03-21 18:25:23 +01004646 @requires_extra_functionality
4647 def test_constants(self):
4648 # Condition flags
4649 cond = (
4650 C.DecClamped, C.DecConversionSyntax, C.DecDivisionByZero,
4651 C.DecDivisionImpossible, C.DecDivisionUndefined,
4652 C.DecFpuError, C.DecInexact, C.DecInvalidContext,
4653 C.DecInvalidOperation, C.DecMallocError,
4654 C.DecFloatOperation, C.DecOverflow, C.DecRounded,
4655 C.DecSubnormal, C.DecUnderflow
Raymond Hettinger771ed762009-01-03 19:20:32 +00004656 )
Stefan Krah1919b7e2012-03-21 18:25:23 +01004657
4658 # IEEEContext
4659 self.assertEqual(C.DECIMAL32, 32)
4660 self.assertEqual(C.DECIMAL64, 64)
4661 self.assertEqual(C.DECIMAL128, 128)
4662 self.assertEqual(C.IEEE_CONTEXT_MAX_BITS, 512)
4663
Stefan Krah1919b7e2012-03-21 18:25:23 +01004664 # Conditions
4665 for i, v in enumerate(cond):
4666 self.assertEqual(v, 1<<i)
4667
4668 self.assertEqual(C.DecIEEEInvalidOperation,
4669 C.DecConversionSyntax|
4670 C.DecDivisionImpossible|
4671 C.DecDivisionUndefined|
4672 C.DecFpuError|
4673 C.DecInvalidContext|
4674 C.DecInvalidOperation|
4675 C.DecMallocError)
4676
4677 self.assertEqual(C.DecErrors,
4678 C.DecIEEEInvalidOperation|
4679 C.DecDivisionByZero)
4680
4681 self.assertEqual(C.DecTraps,
4682 C.DecErrors|C.DecOverflow|C.DecUnderflow)
4683
4684class CWhitebox(unittest.TestCase):
4685 """Whitebox testing for _decimal"""
4686
4687 def test_bignum(self):
4688 # Not exactly whitebox, but too slow with pydecimal.
4689
4690 Decimal = C.Decimal
4691 localcontext = C.localcontext
4692
4693 b1 = 10**35
4694 b2 = 10**36
4695 with localcontext() as c:
4696 c.prec = 1000000
4697 for i in range(5):
4698 a = random.randrange(b1, b2)
4699 b = random.randrange(1000, 1200)
4700 x = a ** b
4701 y = Decimal(a) ** Decimal(b)
4702 self.assertEqual(x, y)
4703
4704 def test_invalid_construction(self):
4705 self.assertRaises(TypeError, C.Decimal, 9, "xyz")
4706
4707 def test_c_input_restriction(self):
4708 # Too large for _decimal to be converted exactly
4709 Decimal = C.Decimal
4710 InvalidOperation = C.InvalidOperation
4711 Context = C.Context
4712 localcontext = C.localcontext
4713
4714 with localcontext(Context()):
4715 self.assertRaises(InvalidOperation, Decimal,
4716 "1e9999999999999999999")
4717
4718 def test_c_context_repr(self):
4719 # This test is _decimal-only because flags are not printed
4720 # in the same order.
4721 DefaultContext = C.DefaultContext
4722 FloatOperation = C.FloatOperation
Stefan Krah1919b7e2012-03-21 18:25:23 +01004723
4724 c = DefaultContext.copy()
4725
4726 c.prec = 425000000
4727 c.Emax = 425000000
4728 c.Emin = -425000000
4729 c.rounding = ROUND_HALF_DOWN
4730 c.capitals = 0
4731 c.clamp = 1
4732 for sig in OrderedSignals[C]:
4733 c.flags[sig] = True
4734 c.traps[sig] = True
4735 c.flags[FloatOperation] = True
4736 c.traps[FloatOperation] = True
4737
4738 s = c.__repr__()
4739 t = "Context(prec=425000000, rounding=ROUND_HALF_DOWN, " \
4740 "Emin=-425000000, Emax=425000000, capitals=0, clamp=1, " \
4741 "flags=[Clamped, InvalidOperation, DivisionByZero, Inexact, " \
4742 "FloatOperation, Overflow, Rounded, Subnormal, Underflow], " \
4743 "traps=[Clamped, InvalidOperation, DivisionByZero, Inexact, " \
4744 "FloatOperation, Overflow, Rounded, Subnormal, Underflow])"
4745 self.assertEqual(s, t)
4746
4747 def test_c_context_errors(self):
4748 Context = C.Context
4749 InvalidOperation = C.InvalidOperation
4750 Overflow = C.Overflow
4751 FloatOperation = C.FloatOperation
4752 localcontext = C.localcontext
4753 getcontext = C.getcontext
4754 setcontext = C.setcontext
4755 HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
4756
4757 c = Context()
4758
4759 # SignalDict: input validation
4760 self.assertRaises(KeyError, c.flags.__setitem__, 801, 0)
4761 self.assertRaises(KeyError, c.traps.__setitem__, 801, 0)
4762 self.assertRaises(ValueError, c.flags.__delitem__, Overflow)
4763 self.assertRaises(ValueError, c.traps.__delitem__, InvalidOperation)
4764 self.assertRaises(TypeError, setattr, c, 'flags', ['x'])
4765 self.assertRaises(TypeError, setattr, c,'traps', ['y'])
4766 self.assertRaises(KeyError, setattr, c, 'flags', {0:1})
4767 self.assertRaises(KeyError, setattr, c, 'traps', {0:1})
4768
4769 # Test assignment from a signal dict with the correct length but
4770 # one invalid key.
4771 d = c.flags.copy()
4772 del d[FloatOperation]
4773 d["XYZ"] = 91283719
4774 self.assertRaises(KeyError, setattr, c, 'flags', d)
4775 self.assertRaises(KeyError, setattr, c, 'traps', d)
4776
4777 # Input corner cases
4778 int_max = 2**63-1 if HAVE_CONFIG_64 else 2**31-1
4779 gt_max_emax = 10**18 if HAVE_CONFIG_64 else 10**9
4780
4781 # prec, Emax, Emin
4782 for attr in ['prec', 'Emax']:
4783 self.assertRaises(ValueError, setattr, c, attr, gt_max_emax)
4784 self.assertRaises(ValueError, setattr, c, 'Emin', -gt_max_emax)
4785
4786 # prec, Emax, Emin in context constructor
4787 self.assertRaises(ValueError, Context, prec=gt_max_emax)
4788 self.assertRaises(ValueError, Context, Emax=gt_max_emax)
4789 self.assertRaises(ValueError, Context, Emin=-gt_max_emax)
4790
4791 # Overflow in conversion
4792 self.assertRaises(OverflowError, Context, prec=int_max+1)
4793 self.assertRaises(OverflowError, Context, Emax=int_max+1)
4794 self.assertRaises(OverflowError, Context, Emin=-int_max-2)
Stefan Krah1919b7e2012-03-21 18:25:23 +01004795 self.assertRaises(OverflowError, Context, clamp=int_max+1)
4796 self.assertRaises(OverflowError, Context, capitals=int_max+1)
4797
4798 # OverflowError, general ValueError
4799 for attr in ('prec', 'Emin', 'Emax', 'capitals', 'clamp'):
4800 self.assertRaises(OverflowError, setattr, c, attr, int_max+1)
4801 self.assertRaises(OverflowError, setattr, c, attr, -int_max-2)
4802 if sys.platform != 'win32':
4803 self.assertRaises(ValueError, setattr, c, attr, int_max)
4804 self.assertRaises(ValueError, setattr, c, attr, -int_max-1)
4805
Stefan Krah1919b7e2012-03-21 18:25:23 +01004806 # OverflowError: _unsafe_setprec, _unsafe_setemin, _unsafe_setemax
4807 if C.MAX_PREC == 425000000:
4808 self.assertRaises(OverflowError, getattr(c, '_unsafe_setprec'),
4809 int_max+1)
4810 self.assertRaises(OverflowError, getattr(c, '_unsafe_setemax'),
4811 int_max+1)
4812 self.assertRaises(OverflowError, getattr(c, '_unsafe_setemin'),
4813 -int_max-2)
4814
4815 # ValueError: _unsafe_setprec, _unsafe_setemin, _unsafe_setemax
4816 if C.MAX_PREC == 425000000:
4817 self.assertRaises(ValueError, getattr(c, '_unsafe_setprec'), 0)
4818 self.assertRaises(ValueError, getattr(c, '_unsafe_setprec'),
4819 1070000001)
4820 self.assertRaises(ValueError, getattr(c, '_unsafe_setemax'), -1)
4821 self.assertRaises(ValueError, getattr(c, '_unsafe_setemax'),
4822 1070000001)
4823 self.assertRaises(ValueError, getattr(c, '_unsafe_setemin'),
4824 -1070000001)
4825 self.assertRaises(ValueError, getattr(c, '_unsafe_setemin'), 1)
4826
4827 # capitals, clamp
4828 for attr in ['capitals', 'clamp']:
4829 self.assertRaises(ValueError, setattr, c, attr, -1)
4830 self.assertRaises(ValueError, setattr, c, attr, 2)
4831 self.assertRaises(TypeError, setattr, c, attr, [1,2,3])
4832 if HAVE_CONFIG_64:
4833 self.assertRaises(ValueError, setattr, c, attr, 2**32)
4834 self.assertRaises(ValueError, setattr, c, attr, 2**32+1)
4835
4836 # Invalid local context
4837 self.assertRaises(TypeError, exec, 'with localcontext("xyz"): pass',
4838 locals())
Stefan Krah040e3112012-12-15 22:33:33 +01004839 self.assertRaises(TypeError, exec,
4840 'with localcontext(context=getcontext()): pass',
4841 locals())
Stefan Krah1919b7e2012-03-21 18:25:23 +01004842
4843 # setcontext
4844 saved_context = getcontext()
4845 self.assertRaises(TypeError, setcontext, "xyz")
4846 setcontext(saved_context)
4847
Stefan Krah59a4a932013-01-16 12:58:59 +01004848 def test_rounding_strings_interned(self):
4849
4850 self.assertIs(C.ROUND_UP, P.ROUND_UP)
4851 self.assertIs(C.ROUND_DOWN, P.ROUND_DOWN)
4852 self.assertIs(C.ROUND_CEILING, P.ROUND_CEILING)
4853 self.assertIs(C.ROUND_FLOOR, P.ROUND_FLOOR)
4854 self.assertIs(C.ROUND_HALF_UP, P.ROUND_HALF_UP)
4855 self.assertIs(C.ROUND_HALF_DOWN, P.ROUND_HALF_DOWN)
4856 self.assertIs(C.ROUND_HALF_EVEN, P.ROUND_HALF_EVEN)
4857 self.assertIs(C.ROUND_05UP, P.ROUND_05UP)
4858
Stefan Krah1919b7e2012-03-21 18:25:23 +01004859 @requires_extra_functionality
4860 def test_c_context_errors_extra(self):
4861 Context = C.Context
4862 InvalidOperation = C.InvalidOperation
4863 Overflow = C.Overflow
4864 localcontext = C.localcontext
4865 getcontext = C.getcontext
4866 setcontext = C.setcontext
4867 HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
4868
4869 c = Context()
4870
4871 # Input corner cases
4872 int_max = 2**63-1 if HAVE_CONFIG_64 else 2**31-1
4873
4874 # OverflowError, general ValueError
4875 self.assertRaises(OverflowError, setattr, c, '_allcr', int_max+1)
4876 self.assertRaises(OverflowError, setattr, c, '_allcr', -int_max-2)
4877 if sys.platform != 'win32':
4878 self.assertRaises(ValueError, setattr, c, '_allcr', int_max)
4879 self.assertRaises(ValueError, setattr, c, '_allcr', -int_max-1)
4880
4881 # OverflowError, general TypeError
4882 for attr in ('_flags', '_traps'):
4883 self.assertRaises(OverflowError, setattr, c, attr, int_max+1)
4884 self.assertRaises(OverflowError, setattr, c, attr, -int_max-2)
4885 if sys.platform != 'win32':
4886 self.assertRaises(TypeError, setattr, c, attr, int_max)
4887 self.assertRaises(TypeError, setattr, c, attr, -int_max-1)
4888
4889 # _allcr
4890 self.assertRaises(ValueError, setattr, c, '_allcr', -1)
4891 self.assertRaises(ValueError, setattr, c, '_allcr', 2)
4892 self.assertRaises(TypeError, setattr, c, '_allcr', [1,2,3])
4893 if HAVE_CONFIG_64:
4894 self.assertRaises(ValueError, setattr, c, '_allcr', 2**32)
4895 self.assertRaises(ValueError, setattr, c, '_allcr', 2**32+1)
4896
4897 # _flags, _traps
4898 for attr in ['_flags', '_traps']:
4899 self.assertRaises(TypeError, setattr, c, attr, 999999)
4900 self.assertRaises(TypeError, setattr, c, attr, 'x')
4901
4902 def test_c_valid_context(self):
4903 # These tests are for code coverage in _decimal.
4904 DefaultContext = C.DefaultContext
Stefan Krah1919b7e2012-03-21 18:25:23 +01004905 Clamped = C.Clamped
4906 Underflow = C.Underflow
4907 Inexact = C.Inexact
4908 Rounded = C.Rounded
4909 Subnormal = C.Subnormal
4910
4911 c = DefaultContext.copy()
4912
4913 # Exercise all getters and setters
4914 c.prec = 34
4915 c.rounding = ROUND_HALF_UP
4916 c.Emax = 3000
4917 c.Emin = -3000
4918 c.capitals = 1
4919 c.clamp = 0
4920
4921 self.assertEqual(c.prec, 34)
4922 self.assertEqual(c.rounding, ROUND_HALF_UP)
4923 self.assertEqual(c.Emin, -3000)
4924 self.assertEqual(c.Emax, 3000)
4925 self.assertEqual(c.capitals, 1)
4926 self.assertEqual(c.clamp, 0)
4927
4928 self.assertEqual(c.Etiny(), -3033)
4929 self.assertEqual(c.Etop(), 2967)
4930
4931 # Exercise all unsafe setters
4932 if C.MAX_PREC == 425000000:
4933 c._unsafe_setprec(999999999)
4934 c._unsafe_setemax(999999999)
4935 c._unsafe_setemin(-999999999)
4936 self.assertEqual(c.prec, 999999999)
4937 self.assertEqual(c.Emax, 999999999)
4938 self.assertEqual(c.Emin, -999999999)
4939
4940 @requires_extra_functionality
4941 def test_c_valid_context_extra(self):
4942 DefaultContext = C.DefaultContext
4943
4944 c = DefaultContext.copy()
4945 self.assertEqual(c._allcr, 1)
4946 c._allcr = 0
4947 self.assertEqual(c._allcr, 0)
4948
4949 def test_c_round(self):
4950 # Restricted input.
4951 Decimal = C.Decimal
4952 InvalidOperation = C.InvalidOperation
4953 localcontext = C.localcontext
4954 MAX_EMAX = C.MAX_EMAX
4955 MIN_ETINY = C.MIN_ETINY
4956 int_max = 2**63-1 if C.MAX_PREC > 425000000 else 2**31-1
4957
4958 with localcontext() as c:
4959 c.traps[InvalidOperation] = True
4960 self.assertRaises(InvalidOperation, Decimal("1.23").__round__,
4961 -int_max-1)
4962 self.assertRaises(InvalidOperation, Decimal("1.23").__round__,
4963 int_max)
4964 self.assertRaises(InvalidOperation, Decimal("1").__round__,
4965 int(MAX_EMAX+1))
4966 self.assertRaises(C.InvalidOperation, Decimal("1").__round__,
4967 -int(MIN_ETINY-1))
4968 self.assertRaises(OverflowError, Decimal("1.23").__round__,
4969 -int_max-2)
4970 self.assertRaises(OverflowError, Decimal("1.23").__round__,
4971 int_max+1)
4972
4973 def test_c_format(self):
4974 # Restricted input
4975 Decimal = C.Decimal
Stefan Krah1919b7e2012-03-21 18:25:23 +01004976 HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
4977
4978 self.assertRaises(TypeError, Decimal(1).__format__, "=10.10", [], 9)
4979 self.assertRaises(TypeError, Decimal(1).__format__, "=10.10", 9)
4980 self.assertRaises(TypeError, Decimal(1).__format__, [])
4981
Stefan Kraheb8c4512013-01-24 15:22:33 +01004982 self.assertRaises(ValueError, Decimal(1).__format__, "<>=10.10")
4983 maxsize = 2**63-1 if HAVE_CONFIG_64 else 2**31-1
4984 self.assertRaises(ValueError, Decimal("1.23456789").__format__,
4985 "=%d.1" % maxsize)
Stefan Krah1919b7e2012-03-21 18:25:23 +01004986
4987 def test_c_integral(self):
4988 Decimal = C.Decimal
4989 Inexact = C.Inexact
Stefan Krah1919b7e2012-03-21 18:25:23 +01004990 localcontext = C.localcontext
4991
4992 x = Decimal(10)
4993 self.assertEqual(x.to_integral(), 10)
4994 self.assertRaises(TypeError, x.to_integral, '10')
4995 self.assertRaises(TypeError, x.to_integral, 10, 'x')
4996 self.assertRaises(TypeError, x.to_integral, 10)
4997
4998 self.assertEqual(x.to_integral_value(), 10)
4999 self.assertRaises(TypeError, x.to_integral_value, '10')
5000 self.assertRaises(TypeError, x.to_integral_value, 10, 'x')
5001 self.assertRaises(TypeError, x.to_integral_value, 10)
5002
5003 self.assertEqual(x.to_integral_exact(), 10)
5004 self.assertRaises(TypeError, x.to_integral_exact, '10')
5005 self.assertRaises(TypeError, x.to_integral_exact, 10, 'x')
5006 self.assertRaises(TypeError, x.to_integral_exact, 10)
5007
5008 with localcontext() as c:
5009 x = Decimal("99999999999999999999999999.9").to_integral_value(ROUND_UP)
5010 self.assertEqual(x, Decimal('100000000000000000000000000'))
5011
5012 x = Decimal("99999999999999999999999999.9").to_integral_exact(ROUND_UP)
5013 self.assertEqual(x, Decimal('100000000000000000000000000'))
5014
5015 c.traps[Inexact] = True
5016 self.assertRaises(Inexact, Decimal("999.9").to_integral_exact, ROUND_UP)
5017
5018 def test_c_funcs(self):
5019 # Invalid arguments
5020 Decimal = C.Decimal
5021 InvalidOperation = C.InvalidOperation
5022 DivisionByZero = C.DivisionByZero
Stefan Krah1919b7e2012-03-21 18:25:23 +01005023 getcontext = C.getcontext
5024 localcontext = C.localcontext
5025
5026 self.assertEqual(Decimal('9.99e10').to_eng_string(), '99.9E+9')
5027
5028 self.assertRaises(TypeError, pow, Decimal(1), 2, "3")
5029 self.assertRaises(TypeError, Decimal(9).number_class, "x", "y")
5030 self.assertRaises(TypeError, Decimal(9).same_quantum, 3, "x", "y")
5031
Raymond Hettinger771ed762009-01-03 19:20:32 +00005032 self.assertRaises(
Stefan Krah1919b7e2012-03-21 18:25:23 +01005033 TypeError,
5034 Decimal("1.23456789").quantize, Decimal('1e-100000'), []
Raymond Hettinger771ed762009-01-03 19:20:32 +00005035 )
Stefan Krah1919b7e2012-03-21 18:25:23 +01005036 self.assertRaises(
5037 TypeError,
5038 Decimal("1.23456789").quantize, Decimal('1e-100000'), getcontext()
5039 )
5040 self.assertRaises(
5041 TypeError,
5042 Decimal("1.23456789").quantize, Decimal('1e-100000'), 10
5043 )
5044 self.assertRaises(
5045 TypeError,
5046 Decimal("1.23456789").quantize, Decimal('1e-100000'), ROUND_UP, 1000
5047 )
Raymond Hettinger771ed762009-01-03 19:20:32 +00005048
Stefan Krah1919b7e2012-03-21 18:25:23 +01005049 with localcontext() as c:
5050 c.clear_traps()
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00005051
Stefan Krah1919b7e2012-03-21 18:25:23 +01005052 # Invalid arguments
5053 self.assertRaises(TypeError, c.copy_sign, Decimal(1), "x", "y")
5054 self.assertRaises(TypeError, c.canonical, 200)
5055 self.assertRaises(TypeError, c.is_canonical, 200)
5056 self.assertRaises(TypeError, c.divmod, 9, 8, "x", "y")
5057 self.assertRaises(TypeError, c.same_quantum, 9, 3, "x", "y")
Raymond Hettingerd9c0a7a2004-07-03 10:02:28 +00005058
Stefan Krah1919b7e2012-03-21 18:25:23 +01005059 self.assertEqual(str(c.canonical(Decimal(200))), '200')
5060 self.assertEqual(c.radix(), 10)
Raymond Hettinger0aeac102004-07-05 22:53:03 +00005061
Stefan Krah1919b7e2012-03-21 18:25:23 +01005062 c.traps[DivisionByZero] = True
5063 self.assertRaises(DivisionByZero, Decimal(9).__divmod__, 0)
5064 self.assertRaises(DivisionByZero, c.divmod, 9, 0)
5065 self.assertTrue(c.flags[InvalidOperation])
Raymond Hettinger955d2b22004-08-08 20:17:45 +00005066
Stefan Krah1919b7e2012-03-21 18:25:23 +01005067 c.clear_flags()
5068 c.traps[InvalidOperation] = True
5069 self.assertRaises(InvalidOperation, Decimal(9).__divmod__, 0)
5070 self.assertRaises(InvalidOperation, c.divmod, 9, 0)
5071 self.assertTrue(c.flags[DivisionByZero])
Mark Dickinsonb1d8e322010-05-22 18:35:36 +00005072
Stefan Krah1919b7e2012-03-21 18:25:23 +01005073 c.traps[InvalidOperation] = True
5074 c.prec = 2
5075 self.assertRaises(InvalidOperation, pow, Decimal(1000), 1, 501)
Mark Dickinson84230a12010-02-18 14:49:50 +00005076
Stefan Krah040e3112012-12-15 22:33:33 +01005077 def test_va_args_exceptions(self):
5078 Decimal = C.Decimal
5079 Context = C.Context
5080
5081 x = Decimal("10001111111")
5082
5083 for attr in ['exp', 'is_normal', 'is_subnormal', 'ln', 'log10',
5084 'logb', 'logical_invert', 'next_minus', 'next_plus',
5085 'normalize', 'number_class', 'sqrt', 'to_eng_string']:
5086 func = getattr(x, attr)
5087 self.assertRaises(TypeError, func, context="x")
5088 self.assertRaises(TypeError, func, "x", context=None)
5089
5090 for attr in ['compare', 'compare_signal', 'logical_and',
5091 'logical_or', 'max', 'max_mag', 'min', 'min_mag',
5092 'remainder_near', 'rotate', 'scaleb', 'shift']:
5093 func = getattr(x, attr)
5094 self.assertRaises(TypeError, func, context="x")
5095 self.assertRaises(TypeError, func, "x", context=None)
5096
5097 self.assertRaises(TypeError, x.to_integral, rounding=None, context=[])
5098 self.assertRaises(TypeError, x.to_integral, rounding={}, context=[])
5099 self.assertRaises(TypeError, x.to_integral, [], [])
5100
5101 self.assertRaises(TypeError, x.to_integral_value, rounding=None, context=[])
5102 self.assertRaises(TypeError, x.to_integral_value, rounding={}, context=[])
5103 self.assertRaises(TypeError, x.to_integral_value, [], [])
5104
5105 self.assertRaises(TypeError, x.to_integral_exact, rounding=None, context=[])
5106 self.assertRaises(TypeError, x.to_integral_exact, rounding={}, context=[])
5107 self.assertRaises(TypeError, x.to_integral_exact, [], [])
5108
5109 self.assertRaises(TypeError, x.fma, 1, 2, context="x")
5110 self.assertRaises(TypeError, x.fma, 1, 2, "x", context=None)
5111
5112 self.assertRaises(TypeError, x.quantize, 1, [], context=None)
5113 self.assertRaises(TypeError, x.quantize, 1, [], rounding=None)
5114 self.assertRaises(TypeError, x.quantize, 1, [], [])
5115
5116 c = Context()
5117 self.assertRaises(TypeError, c.power, 1, 2, mod="x")
5118 self.assertRaises(TypeError, c.power, 1, "x", mod=None)
5119 self.assertRaises(TypeError, c.power, "x", 2, mod=None)
5120
Stefan Krah1919b7e2012-03-21 18:25:23 +01005121 @requires_extra_functionality
5122 def test_c_context_templates(self):
5123 self.assertEqual(
5124 C.BasicContext._traps,
5125 C.DecIEEEInvalidOperation|C.DecDivisionByZero|C.DecOverflow|
5126 C.DecUnderflow|C.DecClamped
5127 )
5128 self.assertEqual(
5129 C.DefaultContext._traps,
5130 C.DecIEEEInvalidOperation|C.DecDivisionByZero|C.DecOverflow
5131 )
Mark Dickinson84230a12010-02-18 14:49:50 +00005132
Stefan Krah1919b7e2012-03-21 18:25:23 +01005133 @requires_extra_functionality
5134 def test_c_signal_dict(self):
Mark Dickinson84230a12010-02-18 14:49:50 +00005135
Stefan Krah1919b7e2012-03-21 18:25:23 +01005136 # SignalDict coverage
5137 Context = C.Context
5138 DefaultContext = C.DefaultContext
Mark Dickinson84230a12010-02-18 14:49:50 +00005139
Stefan Krah1919b7e2012-03-21 18:25:23 +01005140 InvalidOperation = C.InvalidOperation
5141 DivisionByZero = C.DivisionByZero
5142 Overflow = C.Overflow
5143 Subnormal = C.Subnormal
5144 Underflow = C.Underflow
5145 Rounded = C.Rounded
5146 Inexact = C.Inexact
5147 Clamped = C.Clamped
Mark Dickinson84230a12010-02-18 14:49:50 +00005148
Stefan Krah1919b7e2012-03-21 18:25:23 +01005149 DecClamped = C.DecClamped
5150 DecInvalidOperation = C.DecInvalidOperation
5151 DecIEEEInvalidOperation = C.DecIEEEInvalidOperation
Mark Dickinson84230a12010-02-18 14:49:50 +00005152
Stefan Krah1919b7e2012-03-21 18:25:23 +01005153 def assertIsExclusivelySet(signal, signal_dict):
5154 for sig in signal_dict:
5155 if sig == signal:
5156 self.assertTrue(signal_dict[sig])
5157 else:
5158 self.assertFalse(signal_dict[sig])
Mark Dickinson84230a12010-02-18 14:49:50 +00005159
Stefan Krah1919b7e2012-03-21 18:25:23 +01005160 c = DefaultContext.copy()
Mark Dickinson84230a12010-02-18 14:49:50 +00005161
Stefan Krah1919b7e2012-03-21 18:25:23 +01005162 # Signal dict methods
5163 self.assertTrue(Overflow in c.traps)
5164 c.clear_traps()
5165 for k in c.traps.keys():
5166 c.traps[k] = True
5167 for v in c.traps.values():
5168 self.assertTrue(v)
5169 c.clear_traps()
5170 for k, v in c.traps.items():
5171 self.assertFalse(v)
Mark Dickinson84230a12010-02-18 14:49:50 +00005172
Stefan Krah1919b7e2012-03-21 18:25:23 +01005173 self.assertFalse(c.flags.get(Overflow))
5174 self.assertIs(c.flags.get("x"), None)
5175 self.assertEqual(c.flags.get("x", "y"), "y")
5176 self.assertRaises(TypeError, c.flags.get, "x", "y", "z")
Mark Dickinson84230a12010-02-18 14:49:50 +00005177
Stefan Krah1919b7e2012-03-21 18:25:23 +01005178 self.assertEqual(len(c.flags), len(c.traps))
5179 s = sys.getsizeof(c.flags)
5180 s = sys.getsizeof(c.traps)
5181 s = c.flags.__repr__()
Mark Dickinson84230a12010-02-18 14:49:50 +00005182
Stefan Krah1919b7e2012-03-21 18:25:23 +01005183 # Set flags/traps.
5184 c.clear_flags()
5185 c._flags = DecClamped
5186 self.assertTrue(c.flags[Clamped])
Mark Dickinson84230a12010-02-18 14:49:50 +00005187
Stefan Krah1919b7e2012-03-21 18:25:23 +01005188 c.clear_traps()
5189 c._traps = DecInvalidOperation
5190 self.assertTrue(c.traps[InvalidOperation])
Mark Dickinson84230a12010-02-18 14:49:50 +00005191
Stefan Krah1919b7e2012-03-21 18:25:23 +01005192 # Set flags/traps from dictionary.
5193 c.clear_flags()
5194 d = c.flags.copy()
5195 d[DivisionByZero] = True
5196 c.flags = d
5197 assertIsExclusivelySet(DivisionByZero, c.flags)
Mark Dickinson84230a12010-02-18 14:49:50 +00005198
Stefan Krah1919b7e2012-03-21 18:25:23 +01005199 c.clear_traps()
5200 d = c.traps.copy()
5201 d[Underflow] = True
5202 c.traps = d
5203 assertIsExclusivelySet(Underflow, c.traps)
Mark Dickinson84230a12010-02-18 14:49:50 +00005204
Stefan Krah1919b7e2012-03-21 18:25:23 +01005205 # Random constructors
5206 IntSignals = {
5207 Clamped: C.DecClamped,
5208 Rounded: C.DecRounded,
5209 Inexact: C.DecInexact,
5210 Subnormal: C.DecSubnormal,
5211 Underflow: C.DecUnderflow,
5212 Overflow: C.DecOverflow,
5213 DivisionByZero: C.DecDivisionByZero,
5214 InvalidOperation: C.DecIEEEInvalidOperation
5215 }
5216 IntCond = [
5217 C.DecDivisionImpossible, C.DecDivisionUndefined, C.DecFpuError,
5218 C.DecInvalidContext, C.DecInvalidOperation, C.DecMallocError,
5219 C.DecConversionSyntax,
5220 ]
Mark Dickinsonb455e582011-05-22 12:53:18 +01005221
Stefan Krah1919b7e2012-03-21 18:25:23 +01005222 lim = len(OrderedSignals[C])
5223 for r in range(lim):
5224 for t in range(lim):
Stefan Krah59a4a932013-01-16 12:58:59 +01005225 for round in RoundingModes:
Stefan Krah1919b7e2012-03-21 18:25:23 +01005226 flags = random.sample(OrderedSignals[C], r)
5227 traps = random.sample(OrderedSignals[C], t)
5228 prec = random.randrange(1, 10000)
5229 emin = random.randrange(-10000, 0)
5230 emax = random.randrange(0, 10000)
5231 clamp = random.randrange(0, 2)
5232 caps = random.randrange(0, 2)
5233 cr = random.randrange(0, 2)
5234 c = Context(prec=prec, rounding=round, Emin=emin, Emax=emax,
5235 capitals=caps, clamp=clamp, flags=list(flags),
5236 traps=list(traps))
Mark Dickinson84230a12010-02-18 14:49:50 +00005237
Stefan Krah1919b7e2012-03-21 18:25:23 +01005238 self.assertEqual(c.prec, prec)
5239 self.assertEqual(c.rounding, round)
5240 self.assertEqual(c.Emin, emin)
5241 self.assertEqual(c.Emax, emax)
5242 self.assertEqual(c.capitals, caps)
5243 self.assertEqual(c.clamp, clamp)
Mark Dickinson84230a12010-02-18 14:49:50 +00005244
Stefan Krah1919b7e2012-03-21 18:25:23 +01005245 f = 0
5246 for x in flags:
5247 f |= IntSignals[x]
5248 self.assertEqual(c._flags, f)
Mark Dickinson84230a12010-02-18 14:49:50 +00005249
Stefan Krah1919b7e2012-03-21 18:25:23 +01005250 f = 0
5251 for x in traps:
5252 f |= IntSignals[x]
5253 self.assertEqual(c._traps, f)
Mark Dickinson84230a12010-02-18 14:49:50 +00005254
Stefan Krah1919b7e2012-03-21 18:25:23 +01005255 for cond in IntCond:
5256 c._flags = cond
5257 self.assertTrue(c._flags&DecIEEEInvalidOperation)
5258 assertIsExclusivelySet(InvalidOperation, c.flags)
Mark Dickinson84230a12010-02-18 14:49:50 +00005259
Stefan Krah1919b7e2012-03-21 18:25:23 +01005260 for cond in IntCond:
5261 c._traps = cond
5262 self.assertTrue(c._traps&DecIEEEInvalidOperation)
5263 assertIsExclusivelySet(InvalidOperation, c.traps)
Mark Dickinson84230a12010-02-18 14:49:50 +00005264
Stefan Krah1919b7e2012-03-21 18:25:23 +01005265 def test_invalid_override(self):
5266 Decimal = C.Decimal
Mark Dickinson84230a12010-02-18 14:49:50 +00005267
Stefan Krah1919b7e2012-03-21 18:25:23 +01005268 try:
5269 from locale import CHAR_MAX
5270 except ImportError:
Zachary Ware9fe6d862013-12-08 00:20:35 -06005271 self.skipTest('locale.CHAR_MAX not available')
Mark Dickinson84230a12010-02-18 14:49:50 +00005272
Stefan Krah1919b7e2012-03-21 18:25:23 +01005273 def make_grouping(lst):
5274 return ''.join([chr(x) for x in lst])
Mark Dickinson84230a12010-02-18 14:49:50 +00005275
Stefan Krah1919b7e2012-03-21 18:25:23 +01005276 def get_fmt(x, override=None, fmt='n'):
5277 return Decimal(x).__format__(fmt, override)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005278
Stefan Krah1919b7e2012-03-21 18:25:23 +01005279 invalid_grouping = {
5280 'decimal_point' : ',',
5281 'grouping' : make_grouping([255, 255, 0]),
5282 'thousands_sep' : ','
5283 }
5284 invalid_dot = {
5285 'decimal_point' : 'xxxxx',
5286 'grouping' : make_grouping([3, 3, 0]),
5287 'thousands_sep' : ','
5288 }
5289 invalid_sep = {
5290 'decimal_point' : '.',
5291 'grouping' : make_grouping([3, 3, 0]),
5292 'thousands_sep' : 'yyyyy'
5293 }
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005294
Stefan Krah1919b7e2012-03-21 18:25:23 +01005295 if CHAR_MAX == 127: # negative grouping in override
5296 self.assertRaises(ValueError, get_fmt, 12345,
5297 invalid_grouping, 'g')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005298
Stefan Krah1919b7e2012-03-21 18:25:23 +01005299 self.assertRaises(ValueError, get_fmt, 12345, invalid_dot, 'g')
5300 self.assertRaises(ValueError, get_fmt, 12345, invalid_sep, 'g')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005301
Stefan Krah0774e9b2012-04-05 15:21:58 +02005302 def test_exact_conversion(self):
5303 Decimal = C.Decimal
5304 localcontext = C.localcontext
5305 InvalidOperation = C.InvalidOperation
5306
5307 with localcontext() as c:
5308
5309 c.traps[InvalidOperation] = True
5310
5311 # Clamped
5312 x = "0e%d" % sys.maxsize
5313 self.assertRaises(InvalidOperation, Decimal, x)
5314
5315 x = "0e%d" % (-sys.maxsize-1)
5316 self.assertRaises(InvalidOperation, Decimal, x)
5317
5318 # Overflow
5319 x = "1e%d" % sys.maxsize
5320 self.assertRaises(InvalidOperation, Decimal, x)
5321
5322 # Underflow
5323 x = "1e%d" % (-sys.maxsize-1)
5324 self.assertRaises(InvalidOperation, Decimal, x)
5325
Stefan Krahff3eca02012-04-05 15:46:19 +02005326 def test_from_tuple(self):
5327 Decimal = C.Decimal
5328 localcontext = C.localcontext
5329 InvalidOperation = C.InvalidOperation
5330 Overflow = C.Overflow
5331 Underflow = C.Underflow
5332
5333 with localcontext() as c:
5334
5335 c.traps[InvalidOperation] = True
5336 c.traps[Overflow] = True
5337 c.traps[Underflow] = True
5338
5339 # SSIZE_MAX
5340 x = (1, (), sys.maxsize)
5341 self.assertEqual(str(c.create_decimal(x)), '-0E+999999')
5342 self.assertRaises(InvalidOperation, Decimal, x)
5343
5344 x = (1, (0, 1, 2), sys.maxsize)
5345 self.assertRaises(Overflow, c.create_decimal, x)
5346 self.assertRaises(InvalidOperation, Decimal, x)
5347
5348 # SSIZE_MIN
5349 x = (1, (), -sys.maxsize-1)
5350 self.assertEqual(str(c.create_decimal(x)), '-0E-1000026')
5351 self.assertRaises(InvalidOperation, Decimal, x)
5352
5353 x = (1, (0, 1, 2), -sys.maxsize-1)
5354 self.assertRaises(Underflow, c.create_decimal, x)
5355 self.assertRaises(InvalidOperation, Decimal, x)
5356
5357 # OverflowError
5358 x = (1, (), sys.maxsize+1)
5359 self.assertRaises(OverflowError, c.create_decimal, x)
5360 self.assertRaises(OverflowError, Decimal, x)
5361
5362 x = (1, (), -sys.maxsize-2)
5363 self.assertRaises(OverflowError, c.create_decimal, x)
5364 self.assertRaises(OverflowError, Decimal, x)
5365
5366 # Specials
5367 x = (1, (), "N")
5368 self.assertEqual(str(Decimal(x)), '-sNaN')
5369 x = (1, (0,), "N")
5370 self.assertEqual(str(Decimal(x)), '-sNaN')
5371 x = (1, (0, 1), "N")
5372 self.assertEqual(str(Decimal(x)), '-sNaN1')
5373
Stefan Krah891ca9e2013-05-29 19:14:17 +02005374 def test_sizeof(self):
5375 Decimal = C.Decimal
5376 HAVE_CONFIG_64 = (C.MAX_PREC > 425000000)
5377
5378 self.assertGreater(Decimal(0).__sizeof__(), 0)
5379 if HAVE_CONFIG_64:
5380 x = Decimal(10**(19*24)).__sizeof__()
5381 y = Decimal(10**(19*25)).__sizeof__()
5382 self.assertEqual(y, x+8)
5383 else:
5384 x = Decimal(10**(9*24)).__sizeof__()
5385 y = Decimal(10**(9*25)).__sizeof__()
5386 self.assertEqual(y, x+4)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005387
Stefan Krah1919b7e2012-03-21 18:25:23 +01005388all_tests = [
5389 CExplicitConstructionTest, PyExplicitConstructionTest,
5390 CImplicitConstructionTest, PyImplicitConstructionTest,
5391 CFormatTest, PyFormatTest,
5392 CArithmeticOperatorsTest, PyArithmeticOperatorsTest,
5393 CThreadingTest, PyThreadingTest,
5394 CUsabilityTest, PyUsabilityTest,
5395 CPythonAPItests, PyPythonAPItests,
5396 CContextAPItests, PyContextAPItests,
5397 CContextWithStatement, PyContextWithStatement,
5398 CContextFlags, PyContextFlags,
5399 CSpecialContexts, PySpecialContexts,
5400 CContextInputValidation, PyContextInputValidation,
5401 CContextSubclassing, PyContextSubclassing,
5402 CCoverage, PyCoverage,
5403 CFunctionality, PyFunctionality,
5404 CWhitebox, PyWhitebox,
5405 CIBMTestCases, PyIBMTestCases,
5406]
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005407
Stefan Krah1919b7e2012-03-21 18:25:23 +01005408# Delete C tests if _decimal.so is not present.
5409if not C:
5410 all_tests = all_tests[1::2]
5411else:
5412 all_tests.insert(0, CheckAttributes)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005413
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005414
5415def test_main(arith=False, verbose=None, todo_tests=None, debug=None):
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00005416 """ Execute the tests.
5417
Raymond Hettingered20ad82004-09-04 20:09:13 +00005418 Runs all arithmetic tests if arith is True or if the "decimal" resource
5419 is enabled in regrtest.py
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00005420 """
Raymond Hettingered20ad82004-09-04 20:09:13 +00005421
Stefan Krah1919b7e2012-03-21 18:25:23 +01005422 init(C)
5423 init(P)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005424 global TEST_ALL, DEBUG
Raymond Hettingered20ad82004-09-04 20:09:13 +00005425 TEST_ALL = arith or is_resource_enabled('decimal')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005426 DEBUG = debug
Raymond Hettingered20ad82004-09-04 20:09:13 +00005427
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005428 if todo_tests is None:
Stefan Krah1919b7e2012-03-21 18:25:23 +01005429 test_classes = all_tests
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005430 else:
Stefan Krah1919b7e2012-03-21 18:25:23 +01005431 test_classes = [CIBMTestCases, PyIBMTestCases]
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005432
5433 # Dynamically build custom test definition for each file in the test
5434 # directory and add the definitions to the DecimalTest class. This
5435 # procedure insures that new files do not get skipped.
5436 for filename in os.listdir(directory):
5437 if '.decTest' not in filename or filename.startswith("."):
5438 continue
5439 head, tail = filename.split('.')
5440 if todo_tests is not None and head not in todo_tests:
5441 continue
5442 tester = lambda self, f=filename: self.eval_file(directory + f)
Stefan Krah1919b7e2012-03-21 18:25:23 +01005443 setattr(CIBMTestCases, 'test_' + head, tester)
5444 setattr(PyIBMTestCases, 'test_' + head, tester)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005445 del filename, head, tail, tester
5446
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00005447
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005448 try:
5449 run_unittest(*test_classes)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005450 if todo_tests is None:
Stefan Krah1919b7e2012-03-21 18:25:23 +01005451 from doctest import IGNORE_EXCEPTION_DETAIL
5452 savedecimal = sys.modules['decimal']
5453 if C:
5454 sys.modules['decimal'] = C
5455 run_doctest(C, verbose, optionflags=IGNORE_EXCEPTION_DETAIL)
5456 sys.modules['decimal'] = P
5457 run_doctest(P, verbose)
5458 sys.modules['decimal'] = savedecimal
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00005459 finally:
Stefan Krah1919b7e2012-03-21 18:25:23 +01005460 if C: C.setcontext(ORIGINAL_CONTEXT[C])
5461 P.setcontext(ORIGINAL_CONTEXT[P])
5462 if not C:
5463 warnings.warn('C tests skipped: no module named _decimal.',
5464 UserWarning)
5465 if not orig_sys_decimal is sys.modules['decimal']:
5466 raise TestFailed("Internal error: unbalanced number of changes to "
5467 "sys.modules['decimal'].")
5468
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00005469
5470if __name__ == '__main__':
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005471 import optparse
5472 p = optparse.OptionParser("test_decimal.py [--debug] [{--skip | test1 [test2 [...]]}]")
5473 p.add_option('--debug', '-d', action='store_true', help='shows the test number and context before each test')
5474 p.add_option('--skip', '-s', action='store_true', help='skip over 90% of the arithmetic tests')
5475 (opt, args) = p.parse_args()
5476
5477 if opt.skip:
5478 test_main(arith=False, verbose=True)
5479 elif args:
5480 test_main(arith=True, verbose=True, todo_tests=args, debug=opt.debug)
Raymond Hettinger7c85fa42004-07-01 11:01:35 +00005481 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00005482 test_main(arith=True, verbose=True)