test_decimal.py 83 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363
  1. # Copyright (c) 2004 Python Software Foundation.
  2. # All rights reserved.
  3. # Written by Eric Price <eprice at tjhsst.edu>
  4. # and Facundo Batista <facundo at taniquetil.com.ar>
  5. # and Raymond Hettinger <python at rcn.com>
  6. # and Aahz (aahz at pobox.com)
  7. # and Tim Peters
  8. """
  9. These are the test cases for the Decimal module.
  10. There are two groups of tests, Arithmetic and Behaviour. The former test
  11. the Decimal arithmetic using the tests provided by Mike Cowlishaw. The latter
  12. test the pythonic behaviour according to PEP 327.
  13. Cowlishaw's tests can be downloaded from:
  14. http://speleotrove.com/decimal/dectest.zip
  15. This test module can be called from command line with one parameter (Arithmetic
  16. or Behaviour) to test each part, or without parameter to test both parts. If
  17. you're working through IDLE, you can import this test module and call test_main()
  18. with the corresponding argument.
  19. """
  20. import math
  21. import os, sys
  22. import operator
  23. import pickle, copy
  24. import unittest
  25. from decimal import *
  26. import numbers
  27. from test.test_support import (run_unittest, run_doctest, requires_unicode, u,
  28. is_resource_enabled, check_py3k_warnings,
  29. run_with_locale)
  30. import random
  31. try:
  32. import threading
  33. except ImportError:
  34. threading = None
  35. # Useful Test Constant
  36. Signals = tuple(getcontext().flags.keys())
  37. # Signals ordered with respect to precedence: when an operation
  38. # produces multiple signals, signals occurring later in the list
  39. # should be handled before those occurring earlier in the list.
  40. OrderedSignals = (Clamped, Rounded, Inexact, Subnormal,
  41. Underflow, Overflow, DivisionByZero, InvalidOperation)
  42. # Tests are built around these assumed context defaults.
  43. # test_main() restores the original context.
  44. def init():
  45. global ORIGINAL_CONTEXT
  46. ORIGINAL_CONTEXT = getcontext().copy()
  47. DefaultTestContext = Context(
  48. prec = 9,
  49. rounding = ROUND_HALF_EVEN,
  50. traps = dict.fromkeys(Signals, 0)
  51. )
  52. setcontext(DefaultTestContext)
  53. # decorator for skipping tests on non-IEEE 754 platforms
  54. requires_IEEE_754 = unittest.skipUnless(
  55. float.__getformat__("double").startswith("IEEE"),
  56. "test requires IEEE 754 doubles")
  57. TESTDATADIR = 'decimaltestdata'
  58. if __name__ == '__main__':
  59. file = sys.argv[0]
  60. else:
  61. file = __file__
  62. testdir = os.path.dirname(file) or os.curdir
  63. directory = testdir + os.sep + TESTDATADIR + os.sep
  64. skip_expected = not os.path.isdir(directory)
  65. # list of individual .decTest test ids that correspond to tests that
  66. # we're skipping for one reason or another.
  67. skipped_test_ids = set([
  68. # Skip implementation-specific scaleb tests.
  69. 'scbx164',
  70. 'scbx165',
  71. # For some operations (currently exp, ln, log10, power), the decNumber
  72. # reference implementation imposes additional restrictions on the context
  73. # and operands. These restrictions are not part of the specification;
  74. # however, the effect of these restrictions does show up in some of the
  75. # testcases. We skip testcases that violate these restrictions, since
  76. # Decimal behaves differently from decNumber for these testcases so these
  77. # testcases would otherwise fail.
  78. 'expx901',
  79. 'expx902',
  80. 'expx903',
  81. 'expx905',
  82. 'lnx901',
  83. 'lnx902',
  84. 'lnx903',
  85. 'lnx905',
  86. 'logx901',
  87. 'logx902',
  88. 'logx903',
  89. 'logx905',
  90. 'powx1183',
  91. 'powx1184',
  92. 'powx4001',
  93. 'powx4002',
  94. 'powx4003',
  95. 'powx4005',
  96. 'powx4008',
  97. 'powx4010',
  98. 'powx4012',
  99. 'powx4014',
  100. ])
  101. # Make sure it actually raises errors when not expected and caught in flags
  102. # Slower, since it runs some things several times.
  103. EXTENDEDERRORTEST = False
  104. #Map the test cases' error names to the actual errors
  105. ErrorNames = {'clamped' : Clamped,
  106. 'conversion_syntax' : InvalidOperation,
  107. 'division_by_zero' : DivisionByZero,
  108. 'division_impossible' : InvalidOperation,
  109. 'division_undefined' : InvalidOperation,
  110. 'inexact' : Inexact,
  111. 'invalid_context' : InvalidOperation,
  112. 'invalid_operation' : InvalidOperation,
  113. 'overflow' : Overflow,
  114. 'rounded' : Rounded,
  115. 'subnormal' : Subnormal,
  116. 'underflow' : Underflow}
  117. def Nonfunction(*args):
  118. """Doesn't do anything."""
  119. return None
  120. RoundingDict = {'ceiling' : ROUND_CEILING, #Maps test-case names to roundings.
  121. 'down' : ROUND_DOWN,
  122. 'floor' : ROUND_FLOOR,
  123. 'half_down' : ROUND_HALF_DOWN,
  124. 'half_even' : ROUND_HALF_EVEN,
  125. 'half_up' : ROUND_HALF_UP,
  126. 'up' : ROUND_UP,
  127. '05up' : ROUND_05UP}
  128. # Name adapter to be able to change the Decimal and Context
  129. # interface without changing the test files from Cowlishaw
  130. nameAdapter = {'and':'logical_and',
  131. 'apply':'_apply',
  132. 'class':'number_class',
  133. 'comparesig':'compare_signal',
  134. 'comparetotal':'compare_total',
  135. 'comparetotmag':'compare_total_mag',
  136. 'copy':'copy_decimal',
  137. 'copyabs':'copy_abs',
  138. 'copynegate':'copy_negate',
  139. 'copysign':'copy_sign',
  140. 'divideint':'divide_int',
  141. 'invert':'logical_invert',
  142. 'iscanonical':'is_canonical',
  143. 'isfinite':'is_finite',
  144. 'isinfinite':'is_infinite',
  145. 'isnan':'is_nan',
  146. 'isnormal':'is_normal',
  147. 'isqnan':'is_qnan',
  148. 'issigned':'is_signed',
  149. 'issnan':'is_snan',
  150. 'issubnormal':'is_subnormal',
  151. 'iszero':'is_zero',
  152. 'maxmag':'max_mag',
  153. 'minmag':'min_mag',
  154. 'nextminus':'next_minus',
  155. 'nextplus':'next_plus',
  156. 'nexttoward':'next_toward',
  157. 'or':'logical_or',
  158. 'reduce':'normalize',
  159. 'remaindernear':'remainder_near',
  160. 'samequantum':'same_quantum',
  161. 'squareroot':'sqrt',
  162. 'toeng':'to_eng_string',
  163. 'tointegral':'to_integral_value',
  164. 'tointegralx':'to_integral_exact',
  165. 'tosci':'to_sci_string',
  166. 'xor':'logical_xor',
  167. }
  168. # The following functions return True/False rather than a Decimal instance
  169. LOGICAL_FUNCTIONS = (
  170. 'is_canonical',
  171. 'is_finite',
  172. 'is_infinite',
  173. 'is_nan',
  174. 'is_normal',
  175. 'is_qnan',
  176. 'is_signed',
  177. 'is_snan',
  178. 'is_subnormal',
  179. 'is_zero',
  180. 'same_quantum',
  181. )
  182. class DecimalTest(unittest.TestCase):
  183. """Class which tests the Decimal class against the test cases.
  184. Changed for unittest.
  185. """
  186. def setUp(self):
  187. self.context = Context()
  188. self.ignore_list = ['#']
  189. # Basically, a # means return NaN InvalidOperation.
  190. # Different from a sNaN in trim
  191. self.ChangeDict = {'precision' : self.change_precision,
  192. 'rounding' : self.change_rounding_method,
  193. 'maxexponent' : self.change_max_exponent,
  194. 'minexponent' : self.change_min_exponent,
  195. 'clamp' : self.change_clamp}
  196. def eval_file(self, file):
  197. global skip_expected
  198. if skip_expected:
  199. raise unittest.SkipTest
  200. with open(file) as f:
  201. for line in f:
  202. line = line.replace('\r\n', '').replace('\n', '')
  203. #print line
  204. try:
  205. t = self.eval_line(line)
  206. except DecimalException as exception:
  207. #Exception raised where there shouldn't have been one.
  208. self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line)
  209. def eval_line(self, s):
  210. if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith(' --'):
  211. s = (s.split('->')[0] + '->' +
  212. s.split('->')[1].split('--')[0]).strip()
  213. else:
  214. s = s.split('--')[0].strip()
  215. for ignore in self.ignore_list:
  216. if s.find(ignore) >= 0:
  217. #print s.split()[0], 'NotImplemented--', ignore
  218. return
  219. if not s:
  220. return
  221. elif ':' in s:
  222. return self.eval_directive(s)
  223. else:
  224. return self.eval_equation(s)
  225. def eval_directive(self, s):
  226. funct, value = map(lambda x: x.strip().lower(), s.split(':'))
  227. if funct == 'rounding':
  228. value = RoundingDict[value]
  229. else:
  230. try:
  231. value = int(value)
  232. except ValueError:
  233. pass
  234. funct = self.ChangeDict.get(funct, Nonfunction)
  235. funct(value)
  236. def eval_equation(self, s):
  237. #global DEFAULT_PRECISION
  238. #print DEFAULT_PRECISION
  239. if not TEST_ALL and random.random() < 0.90:
  240. return
  241. try:
  242. Sides = s.split('->')
  243. L = Sides[0].strip().split()
  244. id = L[0]
  245. if DEBUG:
  246. print "Test ", id,
  247. funct = L[1].lower()
  248. valstemp = L[2:]
  249. L = Sides[1].strip().split()
  250. ans = L[0]
  251. exceptions = L[1:]
  252. except (TypeError, AttributeError, IndexError):
  253. raise InvalidOperation
  254. def FixQuotes(val):
  255. val = val.replace("''", 'SingleQuote').replace('""', 'DoubleQuote')
  256. val = val.replace("'", '').replace('"', '')
  257. val = val.replace('SingleQuote', "'").replace('DoubleQuote', '"')
  258. return val
  259. if id in skipped_test_ids:
  260. return
  261. fname = nameAdapter.get(funct, funct)
  262. if fname == 'rescale':
  263. return
  264. funct = getattr(self.context, fname)
  265. vals = []
  266. conglomerate = ''
  267. quote = 0
  268. theirexceptions = [ErrorNames[x.lower()] for x in exceptions]
  269. for exception in Signals:
  270. self.context.traps[exception] = 1 #Catch these bugs...
  271. for exception in theirexceptions:
  272. self.context.traps[exception] = 0
  273. for i, val in enumerate(valstemp):
  274. if val.count("'") % 2 == 1:
  275. quote = 1 - quote
  276. if quote:
  277. conglomerate = conglomerate + ' ' + val
  278. continue
  279. else:
  280. val = conglomerate + val
  281. conglomerate = ''
  282. v = FixQuotes(val)
  283. if fname in ('to_sci_string', 'to_eng_string'):
  284. if EXTENDEDERRORTEST:
  285. for error in theirexceptions:
  286. self.context.traps[error] = 1
  287. try:
  288. funct(self.context.create_decimal(v))
  289. except error:
  290. pass
  291. except Signals, e:
  292. self.fail("Raised %s in %s when %s disabled" % \
  293. (e, s, error))
  294. else:
  295. self.fail("Did not raise %s in %s" % (error, s))
  296. self.context.traps[error] = 0
  297. v = self.context.create_decimal(v)
  298. else:
  299. v = Decimal(v, self.context)
  300. vals.append(v)
  301. ans = FixQuotes(ans)
  302. if EXTENDEDERRORTEST and fname not in ('to_sci_string', 'to_eng_string'):
  303. for error in theirexceptions:
  304. self.context.traps[error] = 1
  305. try:
  306. funct(*vals)
  307. except error:
  308. pass
  309. except Signals, e:
  310. self.fail("Raised %s in %s when %s disabled" % \
  311. (e, s, error))
  312. else:
  313. self.fail("Did not raise %s in %s" % (error, s))
  314. self.context.traps[error] = 0
  315. # as above, but add traps cumulatively, to check precedence
  316. ordered_errors = [e for e in OrderedSignals if e in theirexceptions]
  317. for error in ordered_errors:
  318. self.context.traps[error] = 1
  319. try:
  320. funct(*vals)
  321. except error:
  322. pass
  323. except Signals, e:
  324. self.fail("Raised %s in %s; expected %s" %
  325. (type(e), s, error))
  326. else:
  327. self.fail("Did not raise %s in %s" % (error, s))
  328. # reset traps
  329. for error in ordered_errors:
  330. self.context.traps[error] = 0
  331. if DEBUG:
  332. print "--", self.context
  333. try:
  334. result = str(funct(*vals))
  335. if fname in LOGICAL_FUNCTIONS:
  336. result = str(int(eval(result))) # 'True', 'False' -> '1', '0'
  337. except Signals, error:
  338. self.fail("Raised %s in %s" % (error, s))
  339. except: #Catch any error long enough to state the test case.
  340. print "ERROR:", s
  341. raise
  342. myexceptions = self.getexceptions()
  343. self.context.clear_flags()
  344. self.assertEqual(result, ans,
  345. 'Incorrect answer for ' + s + ' -- got ' + result)
  346. self.assertItemsEqual(myexceptions, theirexceptions,
  347. 'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions))
  348. def getexceptions(self):
  349. return [e for e in Signals if self.context.flags[e]]
  350. def change_precision(self, prec):
  351. self.context.prec = prec
  352. def change_rounding_method(self, rounding):
  353. self.context.rounding = rounding
  354. def change_min_exponent(self, exp):
  355. self.context.Emin = exp
  356. def change_max_exponent(self, exp):
  357. self.context.Emax = exp
  358. def change_clamp(self, clamp):
  359. self.context._clamp = clamp
  360. # The following classes test the behaviour of Decimal according to PEP 327
  361. class DecimalExplicitConstructionTest(unittest.TestCase):
  362. '''Unit tests for Explicit Construction cases of Decimal.'''
  363. def test_explicit_empty(self):
  364. self.assertEqual(Decimal(), Decimal("0"))
  365. def test_explicit_from_None(self):
  366. self.assertRaises(TypeError, Decimal, None)
  367. def test_explicit_from_int(self):
  368. #positive
  369. d = Decimal(45)
  370. self.assertEqual(str(d), '45')
  371. #very large positive
  372. d = Decimal(500000123)
  373. self.assertEqual(str(d), '500000123')
  374. #negative
  375. d = Decimal(-45)
  376. self.assertEqual(str(d), '-45')
  377. #zero
  378. d = Decimal(0)
  379. self.assertEqual(str(d), '0')
  380. def test_explicit_from_string(self):
  381. #empty
  382. self.assertEqual(str(Decimal('')), 'NaN')
  383. #int
  384. self.assertEqual(str(Decimal('45')), '45')
  385. #float
  386. self.assertEqual(str(Decimal('45.34')), '45.34')
  387. #engineer notation
  388. self.assertEqual(str(Decimal('45e2')), '4.5E+3')
  389. #just not a number
  390. self.assertEqual(str(Decimal('ugly')), 'NaN')
  391. #leading and trailing whitespace permitted
  392. self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
  393. self.assertEqual(str(Decimal(' -7.89')), '-7.89')
  394. #unicode strings should be permitted
  395. self.assertEqual(str(Decimal(u'0E-017')), '0E-17')
  396. self.assertEqual(str(Decimal(u'45')), '45')
  397. self.assertEqual(str(Decimal(u'-Inf')), '-Infinity')
  398. self.assertEqual(str(Decimal(u'NaN123')), 'NaN123')
  399. def test_explicit_from_tuples(self):
  400. #zero
  401. d = Decimal( (0, (0,), 0) )
  402. self.assertEqual(str(d), '0')
  403. #int
  404. d = Decimal( (1, (4, 5), 0) )
  405. self.assertEqual(str(d), '-45')
  406. #float
  407. d = Decimal( (0, (4, 5, 3, 4), -2) )
  408. self.assertEqual(str(d), '45.34')
  409. #weird
  410. d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
  411. self.assertEqual(str(d), '-4.34913534E-17')
  412. #wrong number of items
  413. self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1)) )
  414. #bad sign
  415. self.assertRaises(ValueError, Decimal, (8, (4, 3, 4, 9, 1), 2) )
  416. self.assertRaises(ValueError, Decimal, (0., (4, 3, 4, 9, 1), 2) )
  417. self.assertRaises(ValueError, Decimal, (Decimal(1), (4, 3, 4, 9, 1), 2))
  418. #bad exp
  419. self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 'wrong!') )
  420. self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), 0.) )
  421. self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 9, 1), '1') )
  422. #bad coefficients
  423. self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, None, 1), 2) )
  424. self.assertRaises(ValueError, Decimal, (1, (4, -3, 4, 9, 1), 2) )
  425. self.assertRaises(ValueError, Decimal, (1, (4, 10, 4, 9, 1), 2) )
  426. self.assertRaises(ValueError, Decimal, (1, (4, 3, 4, 'a', 1), 2) )
  427. def test_explicit_from_bool(self):
  428. self.assertIs(bool(Decimal(0)), False)
  429. self.assertIs(bool(Decimal(1)), True)
  430. self.assertEqual(Decimal(False), Decimal(0))
  431. self.assertEqual(Decimal(True), Decimal(1))
  432. def test_explicit_from_Decimal(self):
  433. #positive
  434. d = Decimal(45)
  435. e = Decimal(d)
  436. self.assertEqual(str(e), '45')
  437. self.assertNotEqual(id(d), id(e))
  438. #very large positive
  439. d = Decimal(500000123)
  440. e = Decimal(d)
  441. self.assertEqual(str(e), '500000123')
  442. self.assertNotEqual(id(d), id(e))
  443. #negative
  444. d = Decimal(-45)
  445. e = Decimal(d)
  446. self.assertEqual(str(e), '-45')
  447. self.assertNotEqual(id(d), id(e))
  448. #zero
  449. d = Decimal(0)
  450. e = Decimal(d)
  451. self.assertEqual(str(e), '0')
  452. self.assertNotEqual(id(d), id(e))
  453. @requires_IEEE_754
  454. def test_explicit_from_float(self):
  455. r = Decimal(0.1)
  456. self.assertEqual(type(r), Decimal)
  457. self.assertEqual(str(r),
  458. '0.1000000000000000055511151231257827021181583404541015625')
  459. self.assertTrue(Decimal(float('nan')).is_qnan())
  460. self.assertTrue(Decimal(float('inf')).is_infinite())
  461. self.assertTrue(Decimal(float('-inf')).is_infinite())
  462. self.assertEqual(str(Decimal(float('nan'))),
  463. str(Decimal('NaN')))
  464. self.assertEqual(str(Decimal(float('inf'))),
  465. str(Decimal('Infinity')))
  466. self.assertEqual(str(Decimal(float('-inf'))),
  467. str(Decimal('-Infinity')))
  468. self.assertEqual(str(Decimal(float('-0.0'))),
  469. str(Decimal('-0')))
  470. for i in range(200):
  471. x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
  472. self.assertEqual(x, float(Decimal(x))) # roundtrip
  473. def test_explicit_context_create_decimal(self):
  474. nc = copy.copy(getcontext())
  475. nc.prec = 3
  476. # empty
  477. d = Decimal()
  478. self.assertEqual(str(d), '0')
  479. d = nc.create_decimal()
  480. self.assertEqual(str(d), '0')
  481. # from None
  482. self.assertRaises(TypeError, nc.create_decimal, None)
  483. # from int
  484. d = nc.create_decimal(456)
  485. self.assertIsInstance(d, Decimal)
  486. self.assertEqual(nc.create_decimal(45678),
  487. nc.create_decimal('457E+2'))
  488. # from string
  489. d = Decimal('456789')
  490. self.assertEqual(str(d), '456789')
  491. d = nc.create_decimal('456789')
  492. self.assertEqual(str(d), '4.57E+5')
  493. # leading and trailing whitespace should result in a NaN;
  494. # spaces are already checked in Cowlishaw's test-suite, so
  495. # here we just check that a trailing newline results in a NaN
  496. self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN')
  497. # from tuples
  498. d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
  499. self.assertEqual(str(d), '-4.34913534E-17')
  500. d = nc.create_decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
  501. self.assertEqual(str(d), '-4.35E-17')
  502. # from Decimal
  503. prevdec = Decimal(500000123)
  504. d = Decimal(prevdec)
  505. self.assertEqual(str(d), '500000123')
  506. d = nc.create_decimal(prevdec)
  507. self.assertEqual(str(d), '5.00E+8')
  508. @requires_unicode
  509. def test_unicode_digits(self):
  510. test_values = {
  511. u(r'\uff11'): '1',
  512. u(r'\u0660.\u0660\u0663\u0667\u0662e-\u0663') : '0.0000372',
  513. u(r'-nan\u0c68\u0c6a\u0c66\u0c66') : '-NaN2400',
  514. }
  515. for input, expected in test_values.items():
  516. self.assertEqual(str(Decimal(input)), expected)
  517. class DecimalImplicitConstructionTest(unittest.TestCase):
  518. '''Unit tests for Implicit Construction cases of Decimal.'''
  519. def test_implicit_from_None(self):
  520. self.assertRaises(TypeError, eval, 'Decimal(5) + None', globals())
  521. def test_implicit_from_int(self):
  522. #normal
  523. self.assertEqual(str(Decimal(5) + 45), '50')
  524. #exceeding precision
  525. self.assertEqual(Decimal(5) + 123456789000, Decimal(123456789000))
  526. def test_implicit_from_string(self):
  527. self.assertRaises(TypeError, eval, 'Decimal(5) + "3"', globals())
  528. def test_implicit_from_float(self):
  529. self.assertRaises(TypeError, eval, 'Decimal(5) + 2.2', globals())
  530. def test_implicit_from_Decimal(self):
  531. self.assertEqual(Decimal(5) + Decimal(45), Decimal(50))
  532. def test_rop(self):
  533. # Allow other classes to be trained to interact with Decimals
  534. class E:
  535. def __divmod__(self, other):
  536. return 'divmod ' + str(other)
  537. def __rdivmod__(self, other):
  538. return str(other) + ' rdivmod'
  539. def __lt__(self, other):
  540. return 'lt ' + str(other)
  541. def __gt__(self, other):
  542. return 'gt ' + str(other)
  543. def __le__(self, other):
  544. return 'le ' + str(other)
  545. def __ge__(self, other):
  546. return 'ge ' + str(other)
  547. def __eq__(self, other):
  548. return 'eq ' + str(other)
  549. def __ne__(self, other):
  550. return 'ne ' + str(other)
  551. self.assertEqual(divmod(E(), Decimal(10)), 'divmod 10')
  552. self.assertEqual(divmod(Decimal(10), E()), '10 rdivmod')
  553. self.assertEqual(eval('Decimal(10) < E()'), 'gt 10')
  554. self.assertEqual(eval('Decimal(10) > E()'), 'lt 10')
  555. self.assertEqual(eval('Decimal(10) <= E()'), 'ge 10')
  556. self.assertEqual(eval('Decimal(10) >= E()'), 'le 10')
  557. self.assertEqual(eval('Decimal(10) == E()'), 'eq 10')
  558. self.assertEqual(eval('Decimal(10) != E()'), 'ne 10')
  559. # insert operator methods and then exercise them
  560. oplist = [
  561. ('+', '__add__', '__radd__'),
  562. ('-', '__sub__', '__rsub__'),
  563. ('*', '__mul__', '__rmul__'),
  564. ('%', '__mod__', '__rmod__'),
  565. ('//', '__floordiv__', '__rfloordiv__'),
  566. ('**', '__pow__', '__rpow__')
  567. ]
  568. with check_py3k_warnings():
  569. if 1 / 2 == 0:
  570. # testing with classic division, so add __div__
  571. oplist.append(('/', '__div__', '__rdiv__'))
  572. else:
  573. # testing with -Qnew, so add __truediv__
  574. oplist.append(('/', '__truediv__', '__rtruediv__'))
  575. for sym, lop, rop in oplist:
  576. setattr(E, lop, lambda self, other: 'str' + lop + str(other))
  577. setattr(E, rop, lambda self, other: str(other) + rop + 'str')
  578. self.assertEqual(eval('E()' + sym + 'Decimal(10)'),
  579. 'str' + lop + '10')
  580. self.assertEqual(eval('Decimal(10)' + sym + 'E()'),
  581. '10' + rop + 'str')
  582. class DecimalFormatTest(unittest.TestCase):
  583. '''Unit tests for the format function.'''
  584. def test_formatting(self):
  585. # triples giving a format, a Decimal, and the expected result
  586. test_values = [
  587. ('e', '0E-15', '0e-15'),
  588. ('e', '2.3E-15', '2.3e-15'),
  589. ('e', '2.30E+2', '2.30e+2'), # preserve significant zeros
  590. ('e', '2.30000E-15', '2.30000e-15'),
  591. ('e', '1.23456789123456789e40', '1.23456789123456789e+40'),
  592. ('e', '1.5', '1.5e+0'),
  593. ('e', '0.15', '1.5e-1'),
  594. ('e', '0.015', '1.5e-2'),
  595. ('e', '0.0000000000015', '1.5e-12'),
  596. ('e', '15.0', '1.50e+1'),
  597. ('e', '-15', '-1.5e+1'),
  598. ('e', '0', '0e+0'),
  599. ('e', '0E1', '0e+1'),
  600. ('e', '0.0', '0e-1'),
  601. ('e', '0.00', '0e-2'),
  602. ('.6e', '0E-15', '0.000000e-9'),
  603. ('.6e', '0', '0.000000e+6'),
  604. ('.6e', '9.999999', '9.999999e+0'),
  605. ('.6e', '9.9999999', '1.000000e+1'),
  606. ('.6e', '-1.23e5', '-1.230000e+5'),
  607. ('.6e', '1.23456789e-3', '1.234568e-3'),
  608. ('f', '0', '0'),
  609. ('f', '0.0', '0.0'),
  610. ('f', '0E-2', '0.00'),
  611. ('f', '0.00E-8', '0.0000000000'),
  612. ('f', '0E1', '0'), # loses exponent information
  613. ('f', '3.2E1', '32'),
  614. ('f', '3.2E2', '320'),
  615. ('f', '3.20E2', '320'),
  616. ('f', '3.200E2', '320.0'),
  617. ('f', '3.2E-6', '0.0000032'),
  618. ('.6f', '0E-15', '0.000000'), # all zeros treated equally
  619. ('.6f', '0E1', '0.000000'),
  620. ('.6f', '0', '0.000000'),
  621. ('.0f', '0', '0'), # no decimal point
  622. ('.0f', '0e-2', '0'),
  623. ('.0f', '3.14159265', '3'),
  624. ('.1f', '3.14159265', '3.1'),
  625. ('.4f', '3.14159265', '3.1416'),
  626. ('.6f', '3.14159265', '3.141593'),
  627. ('.7f', '3.14159265', '3.1415926'), # round-half-even!
  628. ('.8f', '3.14159265', '3.14159265'),
  629. ('.9f', '3.14159265', '3.141592650'),
  630. ('g', '0', '0'),
  631. ('g', '0.0', '0.0'),
  632. ('g', '0E1', '0e+1'),
  633. ('G', '0E1', '0E+1'),
  634. ('g', '0E-5', '0.00000'),
  635. ('g', '0E-6', '0.000000'),
  636. ('g', '0E-7', '0e-7'),
  637. ('g', '-0E2', '-0e+2'),
  638. ('.0g', '3.14159265', '3'), # 0 sig fig -> 1 sig fig
  639. ('.1g', '3.14159265', '3'),
  640. ('.2g', '3.14159265', '3.1'),
  641. ('.5g', '3.14159265', '3.1416'),
  642. ('.7g', '3.14159265', '3.141593'),
  643. ('.8g', '3.14159265', '3.1415926'), # round-half-even!
  644. ('.9g', '3.14159265', '3.14159265'),
  645. ('.10g', '3.14159265', '3.14159265'), # don't pad
  646. ('%', '0E1', '0%'),
  647. ('%', '0E0', '0%'),
  648. ('%', '0E-1', '0%'),
  649. ('%', '0E-2', '0%'),
  650. ('%', '0E-3', '0.0%'),
  651. ('%', '0E-4', '0.00%'),
  652. ('.3%', '0', '0.000%'), # all zeros treated equally
  653. ('.3%', '0E10', '0.000%'),
  654. ('.3%', '0E-10', '0.000%'),
  655. ('.3%', '2.34', '234.000%'),
  656. ('.3%', '1.234567', '123.457%'),
  657. ('.0%', '1.23', '123%'),
  658. ('e', 'NaN', 'NaN'),
  659. ('f', '-NaN123', '-NaN123'),
  660. ('+g', 'NaN456', '+NaN456'),
  661. ('.3e', 'Inf', 'Infinity'),
  662. ('.16f', '-Inf', '-Infinity'),
  663. ('.0g', '-sNaN', '-sNaN'),
  664. ('', '1.00', '1.00'),
  665. # test alignment and padding
  666. ('6', '123', ' 123'),
  667. ('<6', '123', '123 '),
  668. ('>6', '123', ' 123'),
  669. ('^6', '123', ' 123 '),
  670. ('=+6', '123', '+ 123'),
  671. ('#<10', 'NaN', 'NaN#######'),
  672. ('#<10', '-4.3', '-4.3######'),
  673. ('#<+10', '0.0130', '+0.0130###'),
  674. ('#< 10', '0.0130', ' 0.0130###'),
  675. ('@>10', '-Inf', '@-Infinity'),
  676. ('#>5', '-Inf', '-Infinity'),
  677. ('?^5', '123', '?123?'),
  678. ('%^6', '123', '%123%%'),
  679. (' ^6', '-45.6', '-45.6 '),
  680. ('/=10', '-45.6', '-/////45.6'),
  681. ('/=+10', '45.6', '+/////45.6'),
  682. ('/= 10', '45.6', ' /////45.6'),
  683. # thousands separator
  684. (',', '1234567', '1,234,567'),
  685. (',', '123456', '123,456'),
  686. (',', '12345', '12,345'),
  687. (',', '1234', '1,234'),
  688. (',', '123', '123'),
  689. (',', '12', '12'),
  690. (',', '1', '1'),
  691. (',', '0', '0'),
  692. (',', '-1234567', '-1,234,567'),
  693. (',', '-123456', '-123,456'),
  694. ('7,', '123456', '123,456'),
  695. ('8,', '123456', ' 123,456'),
  696. ('08,', '123456', '0,123,456'), # special case: extra 0 needed
  697. ('+08,', '123456', '+123,456'), # but not if there's a sign
  698. (' 08,', '123456', ' 123,456'),
  699. ('08,', '-123456', '-123,456'),
  700. ('+09,', '123456', '+0,123,456'),
  701. # ... with fractional part...
  702. ('07,', '1234.56', '1,234.56'),
  703. ('08,', '1234.56', '1,234.56'),
  704. ('09,', '1234.56', '01,234.56'),
  705. ('010,', '1234.56', '001,234.56'),
  706. ('011,', '1234.56', '0,001,234.56'),
  707. ('012,', '1234.56', '0,001,234.56'),
  708. ('08,.1f', '1234.5', '01,234.5'),
  709. # no thousands separators in fraction part
  710. (',', '1.23456789', '1.23456789'),
  711. (',%', '123.456789', '12,345.6789%'),
  712. (',e', '123456', '1.23456e+5'),
  713. (',E', '123456', '1.23456E+5'),
  714. # issue 6850
  715. ('a=-7.0', '0.12345', 'aaaa0.1'),
  716. # issue 22090
  717. ('<^+15.20%', 'inf', '<<+Infinity%<<<'),
  718. ('\x07>,%', 'sNaN1234567', 'sNaN1234567%'),
  719. ('=10.10%', 'NaN123', ' NaN123%'),
  720. ]
  721. for fmt, d, result in test_values:
  722. self.assertEqual(format(Decimal(d), fmt), result)
  723. def test_n_format(self):
  724. try:
  725. from locale import CHAR_MAX
  726. except ImportError:
  727. self.skipTest('locale.CHAR_MAX not available')
  728. # Set up some localeconv-like dictionaries
  729. en_US = {
  730. 'decimal_point' : '.',
  731. 'grouping' : [3, 3, 0],
  732. 'thousands_sep': ','
  733. }
  734. fr_FR = {
  735. 'decimal_point' : ',',
  736. 'grouping' : [CHAR_MAX],
  737. 'thousands_sep' : ''
  738. }
  739. ru_RU = {
  740. 'decimal_point' : ',',
  741. 'grouping' : [3, 3, 0],
  742. 'thousands_sep' : ' '
  743. }
  744. crazy = {
  745. 'decimal_point' : '&',
  746. 'grouping' : [1, 4, 2, CHAR_MAX],
  747. 'thousands_sep' : '-'
  748. }
  749. def get_fmt(x, locale, fmt='n'):
  750. return Decimal.__format__(Decimal(x), fmt, _localeconv=locale)
  751. self.assertEqual(get_fmt(Decimal('12.7'), en_US), '12.7')
  752. self.assertEqual(get_fmt(Decimal('12.7'), fr_FR), '12,7')
  753. self.assertEqual(get_fmt(Decimal('12.7'), ru_RU), '12,7')
  754. self.assertEqual(get_fmt(Decimal('12.7'), crazy), '1-2&7')
  755. self.assertEqual(get_fmt(123456789, en_US), '123,456,789')
  756. self.assertEqual(get_fmt(123456789, fr_FR), '123456789')
  757. self.assertEqual(get_fmt(123456789, ru_RU), '123 456 789')
  758. self.assertEqual(get_fmt(1234567890123, crazy), '123456-78-9012-3')
  759. self.assertEqual(get_fmt(123456789, en_US, '.6n'), '1.23457e+8')
  760. self.assertEqual(get_fmt(123456789, fr_FR, '.6n'), '1,23457e+8')
  761. self.assertEqual(get_fmt(123456789, ru_RU, '.6n'), '1,23457e+8')
  762. self.assertEqual(get_fmt(123456789, crazy, '.6n'), '1&23457e+8')
  763. # zero padding
  764. self.assertEqual(get_fmt(1234, fr_FR, '03n'), '1234')
  765. self.assertEqual(get_fmt(1234, fr_FR, '04n'), '1234')
  766. self.assertEqual(get_fmt(1234, fr_FR, '05n'), '01234')
  767. self.assertEqual(get_fmt(1234, fr_FR, '06n'), '001234')
  768. self.assertEqual(get_fmt(12345, en_US, '05n'), '12,345')
  769. self.assertEqual(get_fmt(12345, en_US, '06n'), '12,345')
  770. self.assertEqual(get_fmt(12345, en_US, '07n'), '012,345')
  771. self.assertEqual(get_fmt(12345, en_US, '08n'), '0,012,345')
  772. self.assertEqual(get_fmt(12345, en_US, '09n'), '0,012,345')
  773. self.assertEqual(get_fmt(12345, en_US, '010n'), '00,012,345')
  774. self.assertEqual(get_fmt(123456, crazy, '06n'), '1-2345-6')
  775. self.assertEqual(get_fmt(123456, crazy, '07n'), '1-2345-6')
  776. self.assertEqual(get_fmt(123456, crazy, '08n'), '1-2345-6')
  777. self.assertEqual(get_fmt(123456, crazy, '09n'), '01-2345-6')
  778. self.assertEqual(get_fmt(123456, crazy, '010n'), '0-01-2345-6')
  779. self.assertEqual(get_fmt(123456, crazy, '011n'), '0-01-2345-6')
  780. self.assertEqual(get_fmt(123456, crazy, '012n'), '00-01-2345-6')
  781. self.assertEqual(get_fmt(123456, crazy, '013n'), '000-01-2345-6')
  782. @run_with_locale('LC_ALL', 'ps_AF.UTF-8')
  783. def test_wide_char_separator_decimal_point(self):
  784. # locale with wide char separator and decimal point
  785. import locale
  786. decimal_point = locale.localeconv()['decimal_point']
  787. thousands_sep = locale.localeconv()['thousands_sep']
  788. if decimal_point != '\xd9\xab':
  789. self.skipTest('inappropriate decimal point separator'
  790. '({!r} not {!r})'.format(decimal_point, '\xd9\xab'))
  791. if thousands_sep != '\xd9\xac':
  792. self.skipTest('inappropriate thousands separator'
  793. '({!r} not {!r})'.format(thousands_sep, '\xd9\xac'))
  794. self.assertEqual(format(Decimal('100000000.123'), 'n'),
  795. '100\xd9\xac000\xd9\xac000\xd9\xab123')
  796. class DecimalArithmeticOperatorsTest(unittest.TestCase):
  797. '''Unit tests for all arithmetic operators, binary and unary.'''
  798. def test_addition(self):
  799. d1 = Decimal('-11.1')
  800. d2 = Decimal('22.2')
  801. #two Decimals
  802. self.assertEqual(d1+d2, Decimal('11.1'))
  803. self.assertEqual(d2+d1, Decimal('11.1'))
  804. #with other type, left
  805. c = d1 + 5
  806. self.assertEqual(c, Decimal('-6.1'))
  807. self.assertEqual(type(c), type(d1))
  808. #with other type, right
  809. c = 5 + d1
  810. self.assertEqual(c, Decimal('-6.1'))
  811. self.assertEqual(type(c), type(d1))
  812. #inline with decimal
  813. d1 += d2
  814. self.assertEqual(d1, Decimal('11.1'))
  815. #inline with other type
  816. d1 += 5
  817. self.assertEqual(d1, Decimal('16.1'))
  818. def test_subtraction(self):
  819. d1 = Decimal('-11.1')
  820. d2 = Decimal('22.2')
  821. #two Decimals
  822. self.assertEqual(d1-d2, Decimal('-33.3'))
  823. self.assertEqual(d2-d1, Decimal('33.3'))
  824. #with other type, left
  825. c = d1 - 5
  826. self.assertEqual(c, Decimal('-16.1'))
  827. self.assertEqual(type(c), type(d1))
  828. #with other type, right
  829. c = 5 - d1
  830. self.assertEqual(c, Decimal('16.1'))
  831. self.assertEqual(type(c), type(d1))
  832. #inline with decimal
  833. d1 -= d2
  834. self.assertEqual(d1, Decimal('-33.3'))
  835. #inline with other type
  836. d1 -= 5
  837. self.assertEqual(d1, Decimal('-38.3'))
  838. def test_multiplication(self):
  839. d1 = Decimal('-5')
  840. d2 = Decimal('3')
  841. #two Decimals
  842. self.assertEqual(d1*d2, Decimal('-15'))
  843. self.assertEqual(d2*d1, Decimal('-15'))
  844. #with other type, left
  845. c = d1 * 5
  846. self.assertEqual(c, Decimal('-25'))
  847. self.assertEqual(type(c), type(d1))
  848. #with other type, right
  849. c = 5 * d1
  850. self.assertEqual(c, Decimal('-25'))
  851. self.assertEqual(type(c), type(d1))
  852. #inline with decimal
  853. d1 *= d2
  854. self.assertEqual(d1, Decimal('-15'))
  855. #inline with other type
  856. d1 *= 5
  857. self.assertEqual(d1, Decimal('-75'))
  858. def test_division(self):
  859. d1 = Decimal('-5')
  860. d2 = Decimal('2')
  861. #two Decimals
  862. self.assertEqual(d1/d2, Decimal('-2.5'))
  863. self.assertEqual(d2/d1, Decimal('-0.4'))
  864. #with other type, left
  865. c = d1 / 4
  866. self.assertEqual(c, Decimal('-1.25'))
  867. self.assertEqual(type(c), type(d1))
  868. #with other type, right
  869. c = 4 / d1
  870. self.assertEqual(c, Decimal('-0.8'))
  871. self.assertEqual(type(c), type(d1))
  872. #inline with decimal
  873. d1 /= d2
  874. self.assertEqual(d1, Decimal('-2.5'))
  875. #inline with other type
  876. d1 /= 4
  877. self.assertEqual(d1, Decimal('-0.625'))
  878. def test_floor_division(self):
  879. d1 = Decimal('5')
  880. d2 = Decimal('2')
  881. #two Decimals
  882. self.assertEqual(d1//d2, Decimal('2'))
  883. self.assertEqual(d2//d1, Decimal('0'))
  884. #with other type, left
  885. c = d1 // 4
  886. self.assertEqual(c, Decimal('1'))
  887. self.assertEqual(type(c), type(d1))
  888. #with other type, right
  889. c = 7 // d1
  890. self.assertEqual(c, Decimal('1'))
  891. self.assertEqual(type(c), type(d1))
  892. #inline with decimal
  893. d1 //= d2
  894. self.assertEqual(d1, Decimal('2'))
  895. #inline with other type
  896. d1 //= 2
  897. self.assertEqual(d1, Decimal('1'))
  898. def test_powering(self):
  899. d1 = Decimal('5')
  900. d2 = Decimal('2')
  901. #two Decimals
  902. self.assertEqual(d1**d2, Decimal('25'))
  903. self.assertEqual(d2**d1, Decimal('32'))
  904. #with other type, left
  905. c = d1 ** 4
  906. self.assertEqual(c, Decimal('625'))
  907. self.assertEqual(type(c), type(d1))
  908. #with other type, right
  909. c = 7 ** d1
  910. self.assertEqual(c, Decimal('16807'))
  911. self.assertEqual(type(c), type(d1))
  912. #inline with decimal
  913. d1 **= d2
  914. self.assertEqual(d1, Decimal('25'))
  915. #inline with other type
  916. d1 **= 4
  917. self.assertEqual(d1, Decimal('390625'))
  918. def test_module(self):
  919. d1 = Decimal('5')
  920. d2 = Decimal('2')
  921. #two Decimals
  922. self.assertEqual(d1%d2, Decimal('1'))
  923. self.assertEqual(d2%d1, Decimal('2'))
  924. #with other type, left
  925. c = d1 % 4
  926. self.assertEqual(c, Decimal('1'))
  927. self.assertEqual(type(c), type(d1))
  928. #with other type, right
  929. c = 7 % d1
  930. self.assertEqual(c, Decimal('2'))
  931. self.assertEqual(type(c), type(d1))
  932. #inline with decimal
  933. d1 %= d2
  934. self.assertEqual(d1, Decimal('1'))
  935. #inline with other type
  936. d1 %= 4
  937. self.assertEqual(d1, Decimal('1'))
  938. def test_floor_div_module(self):
  939. d1 = Decimal('5')
  940. d2 = Decimal('2')
  941. #two Decimals
  942. (p, q) = divmod(d1, d2)
  943. self.assertEqual(p, Decimal('2'))
  944. self.assertEqual(q, Decimal('1'))
  945. self.assertEqual(type(p), type(d1))
  946. self.assertEqual(type(q), type(d1))
  947. #with other type, left
  948. (p, q) = divmod(d1, 4)
  949. self.assertEqual(p, Decimal('1'))
  950. self.assertEqual(q, Decimal('1'))
  951. self.assertEqual(type(p), type(d1))
  952. self.assertEqual(type(q), type(d1))
  953. #with other type, right
  954. (p, q) = divmod(7, d1)
  955. self.assertEqual(p, Decimal('1'))
  956. self.assertEqual(q, Decimal('2'))
  957. self.assertEqual(type(p), type(d1))
  958. self.assertEqual(type(q), type(d1))
  959. def test_unary_operators(self):
  960. self.assertEqual(+Decimal(45), Decimal(+45)) # +
  961. self.assertEqual(-Decimal(45), Decimal(-45)) # -
  962. self.assertEqual(abs(Decimal(45)), abs(Decimal(-45))) # abs
  963. def test_nan_comparisons(self):
  964. # comparisons involving signaling nans signal InvalidOperation
  965. # order comparisons (<, <=, >, >=) involving only quiet nans
  966. # also signal InvalidOperation
  967. # equality comparisons (==, !=) involving only quiet nans
  968. # don't signal, but return False or True respectively.
  969. n = Decimal('NaN')
  970. s = Decimal('sNaN')
  971. i = Decimal('Inf')
  972. f = Decimal('2')
  973. qnan_pairs = (n, n), (n, i), (i, n), (n, f), (f, n)
  974. snan_pairs = (s, n), (n, s), (s, i), (i, s), (s, f), (f, s), (s, s)
  975. order_ops = operator.lt, operator.le, operator.gt, operator.ge
  976. equality_ops = operator.eq, operator.ne
  977. # results when InvalidOperation is not trapped
  978. for x, y in qnan_pairs + snan_pairs:
  979. for op in order_ops + equality_ops:
  980. got = op(x, y)
  981. expected = True if op is operator.ne else False
  982. self.assertIs(expected, got,
  983. "expected {0!r} for operator.{1}({2!r}, {3!r}); "
  984. "got {4!r}".format(
  985. expected, op.__name__, x, y, got))
  986. # repeat the above, but this time trap the InvalidOperation
  987. with localcontext() as ctx:
  988. ctx.traps[InvalidOperation] = 1
  989. for x, y in qnan_pairs:
  990. for op in equality_ops:
  991. got = op(x, y)
  992. expected = True if op is operator.ne else False
  993. self.assertIs(expected, got,
  994. "expected {0!r} for "
  995. "operator.{1}({2!r}, {3!r}); "
  996. "got {4!r}".format(
  997. expected, op.__name__, x, y, got))
  998. for x, y in snan_pairs:
  999. for op in equality_ops:
  1000. self.assertRaises(InvalidOperation, operator.eq, x, y)
  1001. self.assertRaises(InvalidOperation, operator.ne, x, y)
  1002. for x, y in qnan_pairs + snan_pairs:
  1003. for op in order_ops:
  1004. self.assertRaises(InvalidOperation, op, x, y)
  1005. def test_copy_sign(self):
  1006. d = Decimal(1).copy_sign(Decimal(-2))
  1007. self.assertEqual(Decimal(1).copy_sign(-2), d)
  1008. self.assertRaises(TypeError, Decimal(1).copy_sign, '-2')
  1009. # The following are two functions used to test threading in the next class
  1010. def thfunc1(cls):
  1011. d1 = Decimal(1)
  1012. d3 = Decimal(3)
  1013. test1 = d1/d3
  1014. cls.synchro.wait()
  1015. test2 = d1/d3
  1016. cls.finish1.set()
  1017. cls.assertEqual(test1, Decimal('0.3333333333333333333333333333'))
  1018. cls.assertEqual(test2, Decimal('0.3333333333333333333333333333'))
  1019. def thfunc2(cls):
  1020. d1 = Decimal(1)
  1021. d3 = Decimal(3)
  1022. test1 = d1/d3
  1023. thiscontext = getcontext()
  1024. thiscontext.prec = 18
  1025. test2 = d1/d3
  1026. cls.synchro.set()
  1027. cls.finish2.set()
  1028. cls.assertEqual(test1, Decimal('0.3333333333333333333333333333'))
  1029. cls.assertEqual(test2, Decimal('0.333333333333333333'))
  1030. @unittest.skipUnless(threading, 'threading required')
  1031. class DecimalUseOfContextTest(unittest.TestCase):
  1032. '''Unit tests for Use of Context cases in Decimal.'''
  1033. # Take care executing this test from IDLE, there's an issue in threading
  1034. # that hangs IDLE and I couldn't find it
  1035. def test_threading(self):
  1036. #Test the "threading isolation" of a Context.
  1037. self.synchro = threading.Event()
  1038. self.finish1 = threading.Event()
  1039. self.finish2 = threading.Event()
  1040. th1 = threading.Thread(target=thfunc1, args=(self,))
  1041. th2 = threading.Thread(target=thfunc2, args=(self,))
  1042. th1.start()
  1043. th2.start()
  1044. self.finish1.wait()
  1045. self.finish2.wait()
  1046. class DecimalUsabilityTest(unittest.TestCase):
  1047. '''Unit tests for Usability cases of Decimal.'''
  1048. def test_comparison_operators(self):
  1049. da = Decimal('23.42')
  1050. db = Decimal('23.42')
  1051. dc = Decimal('45')
  1052. #two Decimals
  1053. self.assertGreater(dc, da)
  1054. self.assertGreaterEqual(dc, da)
  1055. self.assertLess(da, dc)
  1056. self.assertLessEqual(da, dc)
  1057. self.assertEqual(da, db)
  1058. self.assertNotEqual(da, dc)
  1059. self.assertLessEqual(da, db)
  1060. self.assertGreaterEqual(da, db)
  1061. self.assertEqual(cmp(dc,da), 1)
  1062. self.assertEqual(cmp(da,dc), -1)
  1063. self.assertEqual(cmp(da,db), 0)
  1064. #a Decimal and an int
  1065. self.assertGreater(dc, 23)
  1066. self.assertLess(23, dc)
  1067. self.assertEqual(dc, 45)
  1068. self.assertEqual(cmp(dc,23), 1)
  1069. self.assertEqual(cmp(23,dc), -1)
  1070. self.assertEqual(cmp(dc,45), 0)
  1071. #a Decimal and uncomparable
  1072. self.assertNotEqual(da, 'ugly')
  1073. self.assertNotEqual(da, 32.7)
  1074. self.assertNotEqual(da, object())
  1075. self.assertNotEqual(da, object)
  1076. # sortable
  1077. a = map(Decimal, xrange(100))
  1078. b = a[:]
  1079. random.shuffle(a)
  1080. a.sort()
  1081. self.assertEqual(a, b)
  1082. # with None
  1083. with check_py3k_warnings():
  1084. self.assertFalse(Decimal(1) < None)
  1085. self.assertTrue(Decimal(1) > None)
  1086. def test_decimal_float_comparison(self):
  1087. da = Decimal('0.25')
  1088. db = Decimal('3.0')
  1089. self.assertLess(da, 3.0)
  1090. self.assertLessEqual(da, 3.0)
  1091. self.assertGreater(db, 0.25)
  1092. self.assertGreaterEqual(db, 0.25)
  1093. self.assertNotEqual(da, 1.5)
  1094. self.assertEqual(da, 0.25)
  1095. self.assertGreater(3.0, da)
  1096. self.assertGreaterEqual(3.0, da)
  1097. self.assertLess(0.25, db)
  1098. self.assertLessEqual(0.25, db)
  1099. self.assertNotEqual(0.25, db)
  1100. self.assertEqual(3.0, db)
  1101. self.assertNotEqual(0.1, Decimal('0.1'))
  1102. def test_copy_and_deepcopy_methods(self):
  1103. d = Decimal('43.24')
  1104. c = copy.copy(d)
  1105. self.assertEqual(id(c), id(d))
  1106. dc = copy.deepcopy(d)
  1107. self.assertEqual(id(dc), id(d))
  1108. def test_hash_method(self):
  1109. #just that it's hashable
  1110. hash(Decimal(23))
  1111. hash(Decimal('Infinity'))
  1112. hash(Decimal('-Infinity'))
  1113. hash(Decimal('nan123'))
  1114. hash(Decimal('-NaN'))
  1115. test_values = [Decimal(sign*(2**m + n))
  1116. for m in [0, 14, 15, 16, 17, 30, 31,
  1117. 32, 33, 62, 63, 64, 65, 66]
  1118. for n in range(-10, 10)
  1119. for sign in [-1, 1]]
  1120. test_values.extend([
  1121. Decimal("-0"), # zeros
  1122. Decimal("0.00"),
  1123. Decimal("-0.000"),
  1124. Decimal("0E10"),
  1125. Decimal("-0E12"),
  1126. Decimal("10.0"), # negative exponent
  1127. Decimal("-23.00000"),
  1128. Decimal("1230E100"), # positive exponent
  1129. Decimal("-4.5678E50"),
  1130. # a value for which hash(n) != hash(n % (2**64-1))
  1131. # in Python pre-2.6
  1132. Decimal(2**64 + 2**32 - 1),
  1133. # selection of values which fail with the old (before
  1134. # version 2.6) long.__hash__
  1135. Decimal("1.634E100"),
  1136. Decimal("90.697E100"),
  1137. Decimal("188.83E100"),
  1138. Decimal("1652.9E100"),
  1139. Decimal("56531E100"),
  1140. ])
  1141. # check that hash(d) == hash(int(d)) for integral values
  1142. for value in test_values:
  1143. self.assertEqual(hash(value), hash(int(value)))
  1144. #the same hash that to an int
  1145. self.assertEqual(hash(Decimal(23)), hash(23))
  1146. self.assertRaises(TypeError, hash, Decimal('sNaN'))
  1147. self.assertTrue(hash(Decimal('Inf')))
  1148. self.assertTrue(hash(Decimal('-Inf')))
  1149. # check that the hashes of a Decimal float match when they
  1150. # represent exactly the same values
  1151. test_strings = ['inf', '-Inf', '0.0', '-.0e1',
  1152. '34.0', '2.5', '112390.625', '-0.515625']
  1153. for s in test_strings:
  1154. f = float(s)
  1155. d = Decimal(s)
  1156. self.assertEqual(hash(f), hash(d))
  1157. # check that the value of the hash doesn't depend on the
  1158. # current context (issue #1757)
  1159. c = getcontext()
  1160. old_precision = c.prec
  1161. x = Decimal("123456789.1")
  1162. c.prec = 6
  1163. h1 = hash(x)
  1164. c.prec = 10
  1165. h2 = hash(x)
  1166. c.prec = 16
  1167. h3 = hash(x)
  1168. self.assertEqual(h1, h2)
  1169. self.assertEqual(h1, h3)
  1170. c.prec = old_precision
  1171. def test_min_and_max_methods(self):
  1172. d1 = Decimal('15.32')
  1173. d2 = Decimal('28.5')
  1174. l1 = 15
  1175. l2 = 28
  1176. #between Decimals
  1177. self.assertIs(min(d1,d2), d1)
  1178. self.assertIs(min(d2,d1), d1)
  1179. self.assertIs(max(d1,d2), d2)
  1180. self.assertIs(max(d2,d1), d2)
  1181. #between Decimal and long
  1182. self.assertIs(min(d1,l2), d1)
  1183. self.assertIs(min(l2,d1), d1)
  1184. self.assertIs(max(l1,d2), d2)
  1185. self.assertIs(max(d2,l1), d2)
  1186. def test_as_nonzero(self):
  1187. #as false
  1188. self.assertFalse(Decimal(0))
  1189. #as true
  1190. self.assertTrue(Decimal('0.372'))
  1191. def test_tostring_methods(self):
  1192. #Test str and repr methods.
  1193. d = Decimal('15.32')
  1194. self.assertEqual(str(d), '15.32') # str
  1195. self.assertEqual(repr(d), "Decimal('15.32')") # repr
  1196. # result type of string methods should be str, not unicode
  1197. unicode_inputs = [u'123.4', u'0.5E2', u'Infinity', u'sNaN',
  1198. u'-0.0E100', u'-NaN001', u'-Inf']
  1199. for u in unicode_inputs:
  1200. d = Decimal(u)
  1201. self.assertEqual(type(str(d)), str)
  1202. self.assertEqual(type(repr(d)), str)
  1203. self.assertEqual(type(d.to_eng_string()), str)
  1204. def test_tonum_methods(self):
  1205. #Test float, int and long methods.
  1206. d1 = Decimal('66')
  1207. d2 = Decimal('15.32')
  1208. #int
  1209. self.assertEqual(int(d1), 66)
  1210. self.assertEqual(int(d2), 15)
  1211. #long
  1212. self.assertEqual(long(d1), 66)
  1213. self.assertEqual(long(d2), 15)
  1214. #float
  1215. self.assertEqual(float(d1), 66)
  1216. self.assertEqual(float(d2), 15.32)
  1217. def test_nan_to_float(self):
  1218. # Test conversions of decimal NANs to float.
  1219. # See http://bugs.python.org/issue15544
  1220. for s in ('nan', 'nan1234', '-nan', '-nan2468'):
  1221. f = float(Decimal(s))
  1222. self.assertTrue(math.isnan(f))
  1223. def test_snan_to_float(self):
  1224. for s in ('snan', '-snan', 'snan1357', '-snan1234'):
  1225. d = Decimal(s)
  1226. self.assertRaises(ValueError, float, d)
  1227. def test_eval_round_trip(self):
  1228. #with zero
  1229. d = Decimal( (0, (0,), 0) )
  1230. self.assertEqual(d, eval(repr(d)))
  1231. #int
  1232. d = Decimal( (1, (4, 5), 0) )
  1233. self.assertEqual(d, eval(repr(d)))
  1234. #float
  1235. d = Decimal( (0, (4, 5, 3, 4), -2) )
  1236. self.assertEqual(d, eval(repr(d)))
  1237. #weird
  1238. d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
  1239. self.assertEqual(d, eval(repr(d)))
  1240. def test_as_tuple(self):
  1241. #with zero
  1242. d = Decimal(0)
  1243. self.assertEqual(d.as_tuple(), (0, (0,), 0) )
  1244. #int
  1245. d = Decimal(-45)
  1246. self.assertEqual(d.as_tuple(), (1, (4, 5), 0) )
  1247. #complicated string
  1248. d = Decimal("-4.34913534E-17")
  1249. self.assertEqual(d.as_tuple(), (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) )
  1250. #inf
  1251. d = Decimal("Infinity")
  1252. self.assertEqual(d.as_tuple(), (0, (0,), 'F') )
  1253. #leading zeros in coefficient should be stripped
  1254. d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), -2) )
  1255. self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), -2) )
  1256. d = Decimal( (1, (0, 0, 0), 37) )
  1257. self.assertEqual(d.as_tuple(), (1, (0,), 37))
  1258. d = Decimal( (1, (), 37) )
  1259. self.assertEqual(d.as_tuple(), (1, (0,), 37))
  1260. #leading zeros in NaN diagnostic info should be stripped
  1261. d = Decimal( (0, (0, 0, 4, 0, 5, 3, 4), 'n') )
  1262. self.assertEqual(d.as_tuple(), (0, (4, 0, 5, 3, 4), 'n') )
  1263. d = Decimal( (1, (0, 0, 0), 'N') )
  1264. self.assertEqual(d.as_tuple(), (1, (), 'N') )
  1265. d = Decimal( (1, (), 'n') )
  1266. self.assertEqual(d.as_tuple(), (1, (), 'n') )
  1267. #coefficient in infinity should be ignored
  1268. d = Decimal( (0, (4, 5, 3, 4), 'F') )
  1269. self.assertEqual(d.as_tuple(), (0, (0,), 'F'))
  1270. d = Decimal( (1, (0, 2, 7, 1), 'F') )
  1271. self.assertEqual(d.as_tuple(), (1, (0,), 'F'))
  1272. def test_immutability_operations(self):
  1273. # Do operations and check that it didn't change change internal objects.
  1274. d1 = Decimal('-25e55')
  1275. b1 = Decimal('-25e55')
  1276. d2 = Decimal('33e+33')
  1277. b2 = Decimal('33e+33')
  1278. def checkSameDec(operation, useOther=False):
  1279. if useOther:
  1280. eval("d1." + operation + "(d2)")
  1281. self.assertEqual(d1._sign, b1._sign)
  1282. self.assertEqual(d1._int, b1._int)
  1283. self.assertEqual(d1._exp, b1._exp)
  1284. self.assertEqual(d2._sign, b2._sign)
  1285. self.assertEqual(d2._int, b2._int)
  1286. self.assertEqual(d2._exp, b2._exp)
  1287. else:
  1288. eval("d1." + operation + "()")
  1289. self.assertEqual(d1._sign, b1._sign)
  1290. self.assertEqual(d1._int, b1._int)
  1291. self.assertEqual(d1._exp, b1._exp)
  1292. Decimal(d1)
  1293. self.assertEqual(d1._sign, b1._sign)
  1294. self.assertEqual(d1._int, b1._int)
  1295. self.assertEqual(d1._exp, b1._exp)
  1296. checkSameDec("__abs__")
  1297. checkSameDec("__add__", True)
  1298. checkSameDec("__div__", True)
  1299. checkSameDec("__divmod__", True)
  1300. checkSameDec("__eq__", True)
  1301. checkSameDec("__ne__", True)
  1302. checkSameDec("__le__", True)
  1303. checkSameDec("__lt__", True)
  1304. checkSameDec("__ge__", True)
  1305. checkSameDec("__gt__", True)
  1306. checkSameDec("__float__")
  1307. checkSameDec("__floordiv__", True)
  1308. checkSameDec("__hash__")
  1309. checkSameDec("__int__")
  1310. checkSameDec("__trunc__")
  1311. checkSameDec("__long__")
  1312. checkSameDec("__mod__", True)
  1313. checkSameDec("__mul__", True)
  1314. checkSameDec("__neg__")
  1315. checkSameDec("__nonzero__")
  1316. checkSameDec("__pos__")
  1317. checkSameDec("__pow__", True)
  1318. checkSameDec("__radd__", True)
  1319. checkSameDec("__rdiv__", True)
  1320. checkSameDec("__rdivmod__", True)
  1321. checkSameDec("__repr__")
  1322. checkSameDec("__rfloordiv__", True)
  1323. checkSameDec("__rmod__", True)
  1324. checkSameDec("__rmul__", True)
  1325. checkSameDec("__rpow__", True)
  1326. checkSameDec("__rsub__", True)
  1327. checkSameDec("__str__")
  1328. checkSameDec("__sub__", True)
  1329. checkSameDec("__truediv__", True)
  1330. checkSameDec("adjusted")
  1331. checkSameDec("as_tuple")
  1332. checkSameDec("compare", True)
  1333. checkSameDec("max", True)
  1334. checkSameDec("min", True)
  1335. checkSameDec("normalize")
  1336. checkSameDec("quantize", True)
  1337. checkSameDec("remainder_near", True)
  1338. checkSameDec("same_quantum", True)
  1339. checkSameDec("sqrt")
  1340. checkSameDec("to_eng_string")
  1341. checkSameDec("to_integral")
  1342. def test_subclassing(self):
  1343. # Different behaviours when subclassing Decimal
  1344. class MyDecimal(Decimal):
  1345. pass
  1346. d1 = MyDecimal(1)
  1347. d2 = MyDecimal(2)
  1348. d = d1 + d2
  1349. self.assertIs(type(d), Decimal)
  1350. d = d1.max(d2)
  1351. self.assertIs(type(d), Decimal)
  1352. def test_implicit_context(self):
  1353. # Check results when context given implicitly. (Issue 2478)
  1354. c = getcontext()
  1355. self.assertEqual(str(Decimal(0).sqrt()),
  1356. str(c.sqrt(Decimal(0))))
  1357. def test_conversions_from_int(self):
  1358. # Check that methods taking a second Decimal argument will
  1359. # always accept an integer in place of a Decimal.
  1360. self.assertEqual(Decimal(4).compare(3),
  1361. Decimal(4).compare(Decimal(3)))
  1362. self.assertEqual(Decimal(4).compare_signal(3),
  1363. Decimal(4).compare_signal(Decimal(3)))
  1364. self.assertEqual(Decimal(4).compare_total(3),
  1365. Decimal(4).compare_total(Decimal(3)))
  1366. self.assertEqual(Decimal(4).compare_total_mag(3),
  1367. Decimal(4).compare_total_mag(Decimal(3)))
  1368. self.assertEqual(Decimal(10101).logical_and(1001),
  1369. Decimal(10101).logical_and(Decimal(1001)))
  1370. self.assertEqual(Decimal(10101).logical_or(1001),
  1371. Decimal(10101).logical_or(Decimal(1001)))
  1372. self.assertEqual(Decimal(10101).logical_xor(1001),
  1373. Decimal(10101).logical_xor(Decimal(1001)))
  1374. self.assertEqual(Decimal(567).max(123),
  1375. Decimal(567).max(Decimal(123)))
  1376. self.assertEqual(Decimal(567).max_mag(123),
  1377. Decimal(567).max_mag(Decimal(123)))
  1378. self.assertEqual(Decimal(567).min(123),
  1379. Decimal(567).min(Decimal(123)))
  1380. self.assertEqual(Decimal(567).min_mag(123),
  1381. Decimal(567).min_mag(Decimal(123)))
  1382. self.assertEqual(Decimal(567).next_toward(123),
  1383. Decimal(567).next_toward(Decimal(123)))
  1384. self.assertEqual(Decimal(1234).quantize(100),
  1385. Decimal(1234).quantize(Decimal(100)))
  1386. self.assertEqual(Decimal(768).remainder_near(1234),
  1387. Decimal(768).remainder_near(Decimal(1234)))
  1388. self.assertEqual(Decimal(123).rotate(1),
  1389. Decimal(123).rotate(Decimal(1)))
  1390. self.assertEqual(Decimal(1234).same_quantum(1000),
  1391. Decimal(1234).same_quantum(Decimal(1000)))
  1392. self.assertEqual(Decimal('9.123').scaleb(-100),
  1393. Decimal('9.123').scaleb(Decimal(-100)))
  1394. self.assertEqual(Decimal(456).shift(-1),
  1395. Decimal(456).shift(Decimal(-1)))
  1396. self.assertEqual(Decimal(-12).fma(Decimal(45), 67),
  1397. Decimal(-12).fma(Decimal(45), Decimal(67)))
  1398. self.assertEqual(Decimal(-12).fma(45, 67),
  1399. Decimal(-12).fma(Decimal(45), Decimal(67)))
  1400. self.assertEqual(Decimal(-12).fma(45, Decimal(67)),
  1401. Decimal(-12).fma(Decimal(45), Decimal(67)))
  1402. class DecimalPythonAPItests(unittest.TestCase):
  1403. def test_abc(self):
  1404. self.assertTrue(issubclass(Decimal, numbers.Number))
  1405. self.assertFalse(issubclass(Decimal, numbers.Real))
  1406. self.assertIsInstance(Decimal(0), numbers.Number)
  1407. self.assertNotIsInstance(Decimal(0), numbers.Real)
  1408. def test_pickle(self):
  1409. d = Decimal('-3.141590000')
  1410. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  1411. p = pickle.dumps(d, proto)
  1412. e = pickle.loads(p)
  1413. self.assertEqual(d, e)
  1414. def test_int(self):
  1415. for x in range(-250, 250):
  1416. s = '%0.2f' % (x / 100.0)
  1417. # should work the same as for floats
  1418. self.assertEqual(int(Decimal(s)), int(float(s)))
  1419. # should work the same as to_integral in the ROUND_DOWN mode
  1420. d = Decimal(s)
  1421. r = d.to_integral(ROUND_DOWN)
  1422. self.assertEqual(Decimal(int(d)), r)
  1423. self.assertRaises(ValueError, int, Decimal('-nan'))
  1424. self.assertRaises(ValueError, int, Decimal('snan'))
  1425. self.assertRaises(OverflowError, int, Decimal('inf'))
  1426. self.assertRaises(OverflowError, int, Decimal('-inf'))
  1427. self.assertRaises(ValueError, long, Decimal('-nan'))
  1428. self.assertRaises(ValueError, long, Decimal('snan'))
  1429. self.assertRaises(OverflowError, long, Decimal('inf'))
  1430. self.assertRaises(OverflowError, long, Decimal('-inf'))
  1431. def test_trunc(self):
  1432. for x in range(-250, 250):
  1433. s = '%0.2f' % (x / 100.0)
  1434. # should work the same as for floats
  1435. self.assertEqual(int(Decimal(s)), int(float(s)))
  1436. # should work the same as to_integral in the ROUND_DOWN mode
  1437. d = Decimal(s)
  1438. r = d.to_integral(ROUND_DOWN)
  1439. self.assertEqual(Decimal(math.trunc(d)), r)
  1440. def test_from_float(self):
  1441. class MyDecimal(Decimal):
  1442. pass
  1443. r = MyDecimal.from_float(0.1)
  1444. self.assertEqual(type(r), MyDecimal)
  1445. self.assertEqual(str(r),
  1446. '0.1000000000000000055511151231257827021181583404541015625')
  1447. bigint = 12345678901234567890123456789
  1448. self.assertEqual(MyDecimal.from_float(bigint), MyDecimal(bigint))
  1449. self.assertTrue(MyDecimal.from_float(float('nan')).is_qnan())
  1450. self.assertTrue(MyDecimal.from_float(float('inf')).is_infinite())
  1451. self.assertTrue(MyDecimal.from_float(float('-inf')).is_infinite())
  1452. self.assertEqual(str(MyDecimal.from_float(float('nan'))),
  1453. str(Decimal('NaN')))
  1454. self.assertEqual(str(MyDecimal.from_float(float('inf'))),
  1455. str(Decimal('Infinity')))
  1456. self.assertEqual(str(MyDecimal.from_float(float('-inf'))),
  1457. str(Decimal('-Infinity')))
  1458. self.assertRaises(TypeError, MyDecimal.from_float, 'abc')
  1459. for i in range(200):
  1460. x = random.expovariate(0.01) * (random.random() * 2.0 - 1.0)
  1461. self.assertEqual(x, float(MyDecimal.from_float(x))) # roundtrip
  1462. def test_create_decimal_from_float(self):
  1463. context = Context(prec=5, rounding=ROUND_DOWN)
  1464. self.assertEqual(
  1465. context.create_decimal_from_float(math.pi),
  1466. Decimal('3.1415')
  1467. )
  1468. context = Context(prec=5, rounding=ROUND_UP)
  1469. self.assertEqual(
  1470. context.create_decimal_from_float(math.pi),
  1471. Decimal('3.1416')
  1472. )
  1473. context = Context(prec=5, traps=[Inexact])
  1474. self.assertRaises(
  1475. Inexact,
  1476. context.create_decimal_from_float,
  1477. math.pi
  1478. )
  1479. self.assertEqual(repr(context.create_decimal_from_float(-0.0)),
  1480. "Decimal('-0')")
  1481. self.assertEqual(repr(context.create_decimal_from_float(1.0)),
  1482. "Decimal('1')")
  1483. self.assertEqual(repr(context.create_decimal_from_float(10)),
  1484. "Decimal('10')")
  1485. class ContextAPItests(unittest.TestCase):
  1486. def test_pickle(self):
  1487. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  1488. c = Context()
  1489. e = pickle.loads(pickle.dumps(c, proto))
  1490. for k in vars(c):
  1491. v1 = vars(c)[k]
  1492. v2 = vars(e)[k]
  1493. self.assertEqual(v1, v2)
  1494. def test_equality_with_other_types(self):
  1495. self.assertIn(Decimal(10), ['a', 1.0, Decimal(10), (1,2), {}])
  1496. self.assertNotIn(Decimal(10), ['a', 1.0, (1,2), {}])
  1497. def test_copy(self):
  1498. # All copies should be deep
  1499. c = Context()
  1500. d = c.copy()
  1501. self.assertNotEqual(id(c), id(d))
  1502. self.assertNotEqual(id(c.flags), id(d.flags))
  1503. self.assertNotEqual(id(c.traps), id(d.traps))
  1504. def test_abs(self):
  1505. c = Context()
  1506. d = c.abs(Decimal(-1))
  1507. self.assertEqual(c.abs(-1), d)
  1508. self.assertRaises(TypeError, c.abs, '-1')
  1509. def test_add(self):
  1510. c = Context()
  1511. d = c.add(Decimal(1), Decimal(1))
  1512. self.assertEqual(c.add(1, 1), d)
  1513. self.assertEqual(c.add(Decimal(1), 1), d)
  1514. self.assertEqual(c.add(1, Decimal(1)), d)
  1515. self.assertRaises(TypeError, c.add, '1', 1)
  1516. self.assertRaises(TypeError, c.add, 1, '1')
  1517. def test_compare(self):
  1518. c = Context()
  1519. d = c.compare(Decimal(1), Decimal(1))
  1520. self.assertEqual(c.compare(1, 1), d)
  1521. self.assertEqual(c.compare(Decimal(1), 1), d)
  1522. self.assertEqual(c.compare(1, Decimal(1)), d)
  1523. self.assertRaises(TypeError, c.compare, '1', 1)
  1524. self.assertRaises(TypeError, c.compare, 1, '1')
  1525. def test_compare_signal(self):
  1526. c = Context()
  1527. d = c.compare_signal(Decimal(1), Decimal(1))
  1528. self.assertEqual(c.compare_signal(1, 1), d)
  1529. self.assertEqual(c.compare_signal(Decimal(1), 1), d)
  1530. self.assertEqual(c.compare_signal(1, Decimal(1)), d)
  1531. self.assertRaises(TypeError, c.compare_signal, '1', 1)
  1532. self.assertRaises(TypeError, c.compare_signal, 1, '1')
  1533. def test_compare_total(self):
  1534. c = Context()
  1535. d = c.compare_total(Decimal(1), Decimal(1))
  1536. self.assertEqual(c.compare_total(1, 1), d)
  1537. self.assertEqual(c.compare_total(Decimal(1), 1), d)
  1538. self.assertEqual(c.compare_total(1, Decimal(1)), d)
  1539. self.assertRaises(TypeError, c.compare_total, '1', 1)
  1540. self.assertRaises(TypeError, c.compare_total, 1, '1')
  1541. def test_compare_total_mag(self):
  1542. c = Context()
  1543. d = c.compare_total_mag(Decimal(1), Decimal(1))
  1544. self.assertEqual(c.compare_total_mag(1, 1), d)
  1545. self.assertEqual(c.compare_total_mag(Decimal(1), 1), d)
  1546. self.assertEqual(c.compare_total_mag(1, Decimal(1)), d)
  1547. self.assertRaises(TypeError, c.compare_total_mag, '1', 1)
  1548. self.assertRaises(TypeError, c.compare_total_mag, 1, '1')
  1549. def test_copy_abs(self):
  1550. c = Context()
  1551. d = c.copy_abs(Decimal(-1))
  1552. self.assertEqual(c.copy_abs(-1), d)
  1553. self.assertRaises(TypeError, c.copy_abs, '-1')
  1554. def test_copy_decimal(self):
  1555. c = Context()
  1556. d = c.copy_decimal(Decimal(-1))
  1557. self.assertEqual(c.copy_decimal(-1), d)
  1558. self.assertRaises(TypeError, c.copy_decimal, '-1')
  1559. def test_copy_negate(self):
  1560. c = Context()
  1561. d = c.copy_negate(Decimal(-1))
  1562. self.assertEqual(c.copy_negate(-1), d)
  1563. self.assertRaises(TypeError, c.copy_negate, '-1')
  1564. def test_copy_sign(self):
  1565. c = Context()
  1566. d = c.copy_sign(Decimal(1), Decimal(-2))
  1567. self.assertEqual(c.copy_sign(1, -2), d)
  1568. self.assertEqual(c.copy_sign(Decimal(1), -2), d)
  1569. self.assertEqual(c.copy_sign(1, Decimal(-2)), d)
  1570. self.assertRaises(TypeError, c.copy_sign, '1', -2)
  1571. self.assertRaises(TypeError, c.copy_sign, 1, '-2')
  1572. def test_divide(self):
  1573. c = Context()
  1574. d = c.divide(Decimal(1), Decimal(2))
  1575. self.assertEqual(c.divide(1, 2), d)
  1576. self.assertEqual(c.divide(Decimal(1), 2), d)
  1577. self.assertEqual(c.divide(1, Decimal(2)), d)
  1578. self.assertRaises(TypeError, c.divide, '1', 2)
  1579. self.assertRaises(TypeError, c.divide, 1, '2')
  1580. def test_divide_int(self):
  1581. c = Context()
  1582. d = c.divide_int(Decimal(1), Decimal(2))
  1583. self.assertEqual(c.divide_int(1, 2), d)
  1584. self.assertEqual(c.divide_int(Decimal(1), 2), d)
  1585. self.assertEqual(c.divide_int(1, Decimal(2)), d)
  1586. self.assertRaises(TypeError, c.divide_int, '1', 2)
  1587. self.assertRaises(TypeError, c.divide_int, 1, '2')
  1588. def test_divmod(self):
  1589. c = Context()
  1590. d = c.divmod(Decimal(1), Decimal(2))
  1591. self.assertEqual(c.divmod(1, 2), d)
  1592. self.assertEqual(c.divmod(Decimal(1), 2), d)
  1593. self.assertEqual(c.divmod(1, Decimal(2)), d)
  1594. self.assertRaises(TypeError, c.divmod, '1', 2)
  1595. self.assertRaises(TypeError, c.divmod, 1, '2')
  1596. def test_exp(self):
  1597. c = Context()
  1598. d = c.exp(Decimal(10))
  1599. self.assertEqual(c.exp(10), d)
  1600. self.assertRaises(TypeError, c.exp, '10')
  1601. def test_fma(self):
  1602. c = Context()
  1603. d = c.fma(Decimal(2), Decimal(3), Decimal(4))
  1604. self.assertEqual(c.fma(2, 3, 4), d)
  1605. self.assertEqual(c.fma(Decimal(2), 3, 4), d)
  1606. self.assertEqual(c.fma(2, Decimal(3), 4), d)
  1607. self.assertEqual(c.fma(2, 3, Decimal(4)), d)
  1608. self.assertEqual(c.fma(Decimal(2), Decimal(3), 4), d)
  1609. self.assertRaises(TypeError, c.fma, '2', 3, 4)
  1610. self.assertRaises(TypeError, c.fma, 2, '3', 4)
  1611. self.assertRaises(TypeError, c.fma, 2, 3, '4')
  1612. def test_is_finite(self):
  1613. c = Context()
  1614. d = c.is_finite(Decimal(10))
  1615. self.assertEqual(c.is_finite(10), d)
  1616. self.assertRaises(TypeError, c.is_finite, '10')
  1617. def test_is_infinite(self):
  1618. c = Context()
  1619. d = c.is_infinite(Decimal(10))
  1620. self.assertEqual(c.is_infinite(10), d)
  1621. self.assertRaises(TypeError, c.is_infinite, '10')
  1622. def test_is_nan(self):
  1623. c = Context()
  1624. d = c.is_nan(Decimal(10))
  1625. self.assertEqual(c.is_nan(10), d)
  1626. self.assertRaises(TypeError, c.is_nan, '10')
  1627. def test_is_normal(self):
  1628. c = Context()
  1629. d = c.is_normal(Decimal(10))
  1630. self.assertEqual(c.is_normal(10), d)
  1631. self.assertRaises(TypeError, c.is_normal, '10')
  1632. def test_is_qnan(self):
  1633. c = Context()
  1634. d = c.is_qnan(Decimal(10))
  1635. self.assertEqual(c.is_qnan(10), d)
  1636. self.assertRaises(TypeError, c.is_qnan, '10')
  1637. def test_is_signed(self):
  1638. c = Context()
  1639. d = c.is_signed(Decimal(10))
  1640. self.assertEqual(c.is_signed(10), d)
  1641. self.assertRaises(TypeError, c.is_signed, '10')
  1642. def test_is_snan(self):
  1643. c = Context()
  1644. d = c.is_snan(Decimal(10))
  1645. self.assertEqual(c.is_snan(10), d)
  1646. self.assertRaises(TypeError, c.is_snan, '10')
  1647. def test_is_subnormal(self):
  1648. c = Context()
  1649. d = c.is_subnormal(Decimal(10))
  1650. self.assertEqual(c.is_subnormal(10), d)
  1651. self.assertRaises(TypeError, c.is_subnormal, '10')
  1652. def test_is_zero(self):
  1653. c = Context()
  1654. d = c.is_zero(Decimal(10))
  1655. self.assertEqual(c.is_zero(10), d)
  1656. self.assertRaises(TypeError, c.is_zero, '10')
  1657. def test_ln(self):
  1658. c = Context()
  1659. d = c.ln(Decimal(10))
  1660. self.assertEqual(c.ln(10), d)
  1661. self.assertRaises(TypeError, c.ln, '10')
  1662. def test_log10(self):
  1663. c = Context()
  1664. d = c.log10(Decimal(10))
  1665. self.assertEqual(c.log10(10), d)
  1666. self.assertRaises(TypeError, c.log10, '10')
  1667. def test_logb(self):
  1668. c = Context()
  1669. d = c.logb(Decimal(10))
  1670. self.assertEqual(c.logb(10), d)
  1671. self.assertRaises(TypeError, c.logb, '10')
  1672. def test_logical_and(self):
  1673. c = Context()
  1674. d = c.logical_and(Decimal(1), Decimal(1))
  1675. self.assertEqual(c.logical_and(1, 1), d)
  1676. self.assertEqual(c.logical_and(Decimal(1), 1), d)
  1677. self.assertEqual(c.logical_and(1, Decimal(1)), d)
  1678. self.assertRaises(TypeError, c.logical_and, '1', 1)
  1679. self.assertRaises(TypeError, c.logical_and, 1, '1')
  1680. def test_logical_invert(self):
  1681. c = Context()
  1682. d = c.logical_invert(Decimal(1000))
  1683. self.assertEqual(c.logical_invert(1000), d)
  1684. self.assertRaises(TypeError, c.logical_invert, '1000')
  1685. def test_logical_or(self):
  1686. c = Context()
  1687. d = c.logical_or(Decimal(1), Decimal(1))
  1688. self.assertEqual(c.logical_or(1, 1), d)
  1689. self.assertEqual(c.logical_or(Decimal(1), 1), d)
  1690. self.assertEqual(c.logical_or(1, Decimal(1)), d)
  1691. self.assertRaises(TypeError, c.logical_or, '1', 1)
  1692. self.assertRaises(TypeError, c.logical_or, 1, '1')
  1693. def test_logical_xor(self):
  1694. c = Context()
  1695. d = c.logical_xor(Decimal(1), Decimal(1))
  1696. self.assertEqual(c.logical_xor(1, 1), d)
  1697. self.assertEqual(c.logical_xor(Decimal(1), 1), d)
  1698. self.assertEqual(c.logical_xor(1, Decimal(1)), d)
  1699. self.assertRaises(TypeError, c.logical_xor, '1', 1)
  1700. self.assertRaises(TypeError, c.logical_xor, 1, '1')
  1701. def test_max(self):
  1702. c = Context()
  1703. d = c.max(Decimal(1), Decimal(2))
  1704. self.assertEqual(c.max(1, 2), d)
  1705. self.assertEqual(c.max(Decimal(1), 2), d)
  1706. self.assertEqual(c.max(1, Decimal(2)), d)
  1707. self.assertRaises(TypeError, c.max, '1', 2)
  1708. self.assertRaises(TypeError, c.max, 1, '2')
  1709. def test_max_mag(self):
  1710. c = Context()
  1711. d = c.max_mag(Decimal(1), Decimal(2))
  1712. self.assertEqual(c.max_mag(1, 2), d)
  1713. self.assertEqual(c.max_mag(Decimal(1), 2), d)
  1714. self.assertEqual(c.max_mag(1, Decimal(2)), d)
  1715. self.assertRaises(TypeError, c.max_mag, '1', 2)
  1716. self.assertRaises(TypeError, c.max_mag, 1, '2')
  1717. def test_min(self):
  1718. c = Context()
  1719. d = c.min(Decimal(1), Decimal(2))
  1720. self.assertEqual(c.min(1, 2), d)
  1721. self.assertEqual(c.min(Decimal(1), 2), d)
  1722. self.assertEqual(c.min(1, Decimal(2)), d)
  1723. self.assertRaises(TypeError, c.min, '1', 2)
  1724. self.assertRaises(TypeError, c.min, 1, '2')
  1725. def test_min_mag(self):
  1726. c = Context()
  1727. d = c.min_mag(Decimal(1), Decimal(2))
  1728. self.assertEqual(c.min_mag(1, 2), d)
  1729. self.assertEqual(c.min_mag(Decimal(1), 2), d)
  1730. self.assertEqual(c.min_mag(1, Decimal(2)), d)
  1731. self.assertRaises(TypeError, c.min_mag, '1', 2)
  1732. self.assertRaises(TypeError, c.min_mag, 1, '2')
  1733. def test_minus(self):
  1734. c = Context()
  1735. d = c.minus(Decimal(10))
  1736. self.assertEqual(c.minus(10), d)
  1737. self.assertRaises(TypeError, c.minus, '10')
  1738. def test_multiply(self):
  1739. c = Context()
  1740. d = c.multiply(Decimal(1), Decimal(2))
  1741. self.assertEqual(c.multiply(1, 2), d)
  1742. self.assertEqual(c.multiply(Decimal(1), 2), d)
  1743. self.assertEqual(c.multiply(1, Decimal(2)), d)
  1744. self.assertRaises(TypeError, c.multiply, '1', 2)
  1745. self.assertRaises(TypeError, c.multiply, 1, '2')
  1746. def test_next_minus(self):
  1747. c = Context()
  1748. d = c.next_minus(Decimal(10))
  1749. self.assertEqual(c.next_minus(10), d)
  1750. self.assertRaises(TypeError, c.next_minus, '10')
  1751. def test_next_plus(self):
  1752. c = Context()
  1753. d = c.next_plus(Decimal(10))
  1754. self.assertEqual(c.next_plus(10), d)
  1755. self.assertRaises(TypeError, c.next_plus, '10')
  1756. def test_next_toward(self):
  1757. c = Context()
  1758. d = c.next_toward(Decimal(1), Decimal(2))
  1759. self.assertEqual(c.next_toward(1, 2), d)
  1760. self.assertEqual(c.next_toward(Decimal(1), 2), d)
  1761. self.assertEqual(c.next_toward(1, Decimal(2)), d)
  1762. self.assertRaises(TypeError, c.next_toward, '1', 2)
  1763. self.assertRaises(TypeError, c.next_toward, 1, '2')
  1764. def test_normalize(self):
  1765. c = Context()
  1766. d = c.normalize(Decimal(10))
  1767. self.assertEqual(c.normalize(10), d)
  1768. self.assertRaises(TypeError, c.normalize, '10')
  1769. def test_number_class(self):
  1770. c = Context()
  1771. self.assertEqual(c.number_class(123), c.number_class(Decimal(123)))
  1772. self.assertEqual(c.number_class(0), c.number_class(Decimal(0)))
  1773. self.assertEqual(c.number_class(-45), c.number_class(Decimal(-45)))
  1774. def test_power(self):
  1775. c = Context()
  1776. d = c.power(Decimal(1), Decimal(4), Decimal(2))
  1777. self.assertEqual(c.power(1, 4, 2), d)
  1778. self.assertEqual(c.power(Decimal(1), 4, 2), d)
  1779. self.assertEqual(c.power(1, Decimal(4), 2), d)
  1780. self.assertEqual(c.power(1, 4, Decimal(2)), d)
  1781. self.assertEqual(c.power(Decimal(1), Decimal(4), 2), d)
  1782. self.assertRaises(TypeError, c.power, '1', 4, 2)
  1783. self.assertRaises(TypeError, c.power, 1, '4', 2)
  1784. self.assertRaises(TypeError, c.power, 1, 4, '2')
  1785. def test_plus(self):
  1786. c = Context()
  1787. d = c.plus(Decimal(10))
  1788. self.assertEqual(c.plus(10), d)
  1789. self.assertRaises(TypeError, c.plus, '10')
  1790. def test_quantize(self):
  1791. c = Context()
  1792. d = c.quantize(Decimal(1), Decimal(2))
  1793. self.assertEqual(c.quantize(1, 2), d)
  1794. self.assertEqual(c.quantize(Decimal(1), 2), d)
  1795. self.assertEqual(c.quantize(1, Decimal(2)), d)
  1796. self.assertRaises(TypeError, c.quantize, '1', 2)
  1797. self.assertRaises(TypeError, c.quantize, 1, '2')
  1798. def test_remainder(self):
  1799. c = Context()
  1800. d = c.remainder(Decimal(1), Decimal(2))
  1801. self.assertEqual(c.remainder(1, 2), d)
  1802. self.assertEqual(c.remainder(Decimal(1), 2), d)
  1803. self.assertEqual(c.remainder(1, Decimal(2)), d)
  1804. self.assertRaises(TypeError, c.remainder, '1', 2)
  1805. self.assertRaises(TypeError, c.remainder, 1, '2')
  1806. def test_remainder_near(self):
  1807. c = Context()
  1808. d = c.remainder_near(Decimal(1), Decimal(2))
  1809. self.assertEqual(c.remainder_near(1, 2), d)
  1810. self.assertEqual(c.remainder_near(Decimal(1), 2), d)
  1811. self.assertEqual(c.remainder_near(1, Decimal(2)), d)
  1812. self.assertRaises(TypeError, c.remainder_near, '1', 2)
  1813. self.assertRaises(TypeError, c.remainder_near, 1, '2')
  1814. def test_rotate(self):
  1815. c = Context()
  1816. d = c.rotate(Decimal(1), Decimal(2))
  1817. self.assertEqual(c.rotate(1, 2), d)
  1818. self.assertEqual(c.rotate(Decimal(1), 2), d)
  1819. self.assertEqual(c.rotate(1, Decimal(2)), d)
  1820. self.assertRaises(TypeError, c.rotate, '1', 2)
  1821. self.assertRaises(TypeError, c.rotate, 1, '2')
  1822. def test_sqrt(self):
  1823. c = Context()
  1824. d = c.sqrt(Decimal(10))
  1825. self.assertEqual(c.sqrt(10), d)
  1826. self.assertRaises(TypeError, c.sqrt, '10')
  1827. def test_same_quantum(self):
  1828. c = Context()
  1829. d = c.same_quantum(Decimal(1), Decimal(2))
  1830. self.assertEqual(c.same_quantum(1, 2), d)
  1831. self.assertEqual(c.same_quantum(Decimal(1), 2), d)
  1832. self.assertEqual(c.same_quantum(1, Decimal(2)), d)
  1833. self.assertRaises(TypeError, c.same_quantum, '1', 2)
  1834. self.assertRaises(TypeError, c.same_quantum, 1, '2')
  1835. def test_scaleb(self):
  1836. c = Context()
  1837. d = c.scaleb(Decimal(1), Decimal(2))
  1838. self.assertEqual(c.scaleb(1, 2), d)
  1839. self.assertEqual(c.scaleb(Decimal(1), 2), d)
  1840. self.assertEqual(c.scaleb(1, Decimal(2)), d)
  1841. self.assertRaises(TypeError, c.scaleb, '1', 2)
  1842. self.assertRaises(TypeError, c.scaleb, 1, '2')
  1843. def test_shift(self):
  1844. c = Context()
  1845. d = c.shift(Decimal(1), Decimal(2))
  1846. self.assertEqual(c.shift(1, 2), d)
  1847. self.assertEqual(c.shift(Decimal(1), 2), d)
  1848. self.assertEqual(c.shift(1, Decimal(2)), d)
  1849. self.assertRaises(TypeError, c.shift, '1', 2)
  1850. self.assertRaises(TypeError, c.shift, 1, '2')
  1851. def test_subtract(self):
  1852. c = Context()
  1853. d = c.subtract(Decimal(1), Decimal(2))
  1854. self.assertEqual(c.subtract(1, 2), d)
  1855. self.assertEqual(c.subtract(Decimal(1), 2), d)
  1856. self.assertEqual(c.subtract(1, Decimal(2)), d)
  1857. self.assertRaises(TypeError, c.subtract, '1', 2)
  1858. self.assertRaises(TypeError, c.subtract, 1, '2')
  1859. def test_to_eng_string(self):
  1860. c = Context()
  1861. d = c.to_eng_string(Decimal(10))
  1862. self.assertEqual(c.to_eng_string(10), d)
  1863. self.assertRaises(TypeError, c.to_eng_string, '10')
  1864. def test_to_sci_string(self):
  1865. c = Context()
  1866. d = c.to_sci_string(Decimal(10))
  1867. self.assertEqual(c.to_sci_string(10), d)
  1868. self.assertRaises(TypeError, c.to_sci_string, '10')
  1869. def test_to_integral_exact(self):
  1870. c = Context()
  1871. d = c.to_integral_exact(Decimal(10))
  1872. self.assertEqual(c.to_integral_exact(10), d)
  1873. self.assertRaises(TypeError, c.to_integral_exact, '10')
  1874. def test_to_integral_value(self):
  1875. c = Context()
  1876. d = c.to_integral_value(Decimal(10))
  1877. self.assertEqual(c.to_integral_value(10), d)
  1878. self.assertRaises(TypeError, c.to_integral_value, '10')
  1879. class WithStatementTest(unittest.TestCase):
  1880. # Can't do these as docstrings until Python 2.6
  1881. # as doctest can't handle __future__ statements
  1882. def test_localcontext(self):
  1883. # Use a copy of the current context in the block
  1884. orig_ctx = getcontext()
  1885. with localcontext() as enter_ctx:
  1886. set_ctx = getcontext()
  1887. final_ctx = getcontext()
  1888. self.assertIs(orig_ctx, final_ctx, 'did not restore context correctly')
  1889. self.assertIsNot(orig_ctx, set_ctx, 'did not copy the context')
  1890. self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context')
  1891. def test_localcontextarg(self):
  1892. # Use a copy of the supplied context in the block
  1893. orig_ctx = getcontext()
  1894. new_ctx = Context(prec=42)
  1895. with localcontext(new_ctx) as enter_ctx:
  1896. set_ctx = getcontext()
  1897. final_ctx = getcontext()
  1898. self.assertIs(orig_ctx, final_ctx, 'did not restore context correctly')
  1899. self.assertEqual(set_ctx.prec, new_ctx.prec, 'did not set correct context')
  1900. self.assertIsNot(new_ctx, set_ctx, 'did not copy the context')
  1901. self.assertIs(set_ctx, enter_ctx, '__enter__ returned wrong context')
  1902. class ContextFlags(unittest.TestCase):
  1903. def test_flags_irrelevant(self):
  1904. # check that the result (numeric result + flags raised) of an
  1905. # arithmetic operation doesn't depend on the current flags
  1906. context = Context(prec=9, Emin = -999999999, Emax = 999999999,
  1907. rounding=ROUND_HALF_EVEN, traps=[], flags=[])
  1908. # operations that raise various flags, in the form (function, arglist)
  1909. operations = [
  1910. (context._apply, [Decimal("100E-1000000009")]),
  1911. (context.sqrt, [Decimal(2)]),
  1912. (context.add, [Decimal("1.23456789"), Decimal("9.87654321")]),
  1913. (context.multiply, [Decimal("1.23456789"), Decimal("9.87654321")]),
  1914. (context.subtract, [Decimal("1.23456789"), Decimal("9.87654321")]),
  1915. ]
  1916. # try various flags individually, then a whole lot at once
  1917. flagsets = [[Inexact], [Rounded], [Underflow], [Clamped], [Subnormal],
  1918. [Inexact, Rounded, Underflow, Clamped, Subnormal]]
  1919. for fn, args in operations:
  1920. # find answer and flags raised using a clean context
  1921. context.clear_flags()
  1922. ans = fn(*args)
  1923. flags = [k for k, v in context.flags.items() if v]
  1924. for extra_flags in flagsets:
  1925. # set flags, before calling operation
  1926. context.clear_flags()
  1927. for flag in extra_flags:
  1928. context._raise_error(flag)
  1929. new_ans = fn(*args)
  1930. # flags that we expect to be set after the operation
  1931. expected_flags = list(flags)
  1932. for flag in extra_flags:
  1933. if flag not in expected_flags:
  1934. expected_flags.append(flag)
  1935. # flags we actually got
  1936. new_flags = [k for k,v in context.flags.items() if v]
  1937. self.assertEqual(ans, new_ans,
  1938. "operation produces different answers depending on flags set: " +
  1939. "expected %s, got %s." % (ans, new_ans))
  1940. self.assertItemsEqual(new_flags, expected_flags,
  1941. "operation raises different flags depending on flags set: " +
  1942. "expected %s, got %s" % (expected_flags, new_flags))
  1943. def test_main(arith=None, verbose=None, todo_tests=None, debug=None):
  1944. """ Execute the tests.
  1945. Runs all arithmetic tests if arith is True or if the "decimal" resource
  1946. is enabled in regrtest.py
  1947. """
  1948. init()
  1949. global TEST_ALL, DEBUG
  1950. TEST_ALL = arith if arith is not None else is_resource_enabled('decimal')
  1951. DEBUG = debug
  1952. if todo_tests is None:
  1953. test_classes = [
  1954. DecimalExplicitConstructionTest,
  1955. DecimalImplicitConstructionTest,
  1956. DecimalArithmeticOperatorsTest,
  1957. DecimalFormatTest,
  1958. DecimalUseOfContextTest,
  1959. DecimalUsabilityTest,
  1960. DecimalPythonAPItests,
  1961. ContextAPItests,
  1962. DecimalTest,
  1963. WithStatementTest,
  1964. ContextFlags
  1965. ]
  1966. else:
  1967. test_classes = [DecimalTest]
  1968. # Dynamically build custom test definition for each file in the test
  1969. # directory and add the definitions to the DecimalTest class. This
  1970. # procedure insures that new files do not get skipped.
  1971. for filename in os.listdir(directory):
  1972. if '.decTest' not in filename or filename.startswith("."):
  1973. continue
  1974. head, tail = filename.split('.')
  1975. if todo_tests is not None and head not in todo_tests:
  1976. continue
  1977. tester = lambda self, f=filename: self.eval_file(directory + f)
  1978. setattr(DecimalTest, 'test_' + head, tester)
  1979. del filename, head, tail, tester
  1980. try:
  1981. run_unittest(*test_classes)
  1982. if todo_tests is None:
  1983. import decimal as DecimalModule
  1984. run_doctest(DecimalModule, verbose)
  1985. finally:
  1986. setcontext(ORIGINAL_CONTEXT)
  1987. if __name__ == '__main__':
  1988. import optparse
  1989. p = optparse.OptionParser("test_decimal.py [--debug] [{--skip | test1 [test2 [...]]}]")
  1990. p.add_option('--debug', '-d', action='store_true', help='shows the test number and context before each test')
  1991. p.add_option('--skip', '-s', action='store_true', help='skip over 90% of the arithmetic tests')
  1992. (opt, args) = p.parse_args()
  1993. if opt.skip:
  1994. test_main(arith=False, verbose=True)
  1995. elif args:
  1996. test_main(arith=True, verbose=True, todo_tests=args, debug=opt.debug)
  1997. else:
  1998. test_main(arith=True, verbose=True)