Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(12442)

Delta Between Two Patch Sets: Lib/decimal.py

Issue 7652: Merge C version of decimal into py3k.
Left Patch Set: Created 7 years, 9 months ago
Right Patch Set: Created 7 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Include/longintrepr.h ('k') | Lib/test/support.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 # Copyright (c) 2004 Python Software Foundation. 1 # Copyright (c) 2004 Python Software Foundation.
2 # All rights reserved. 2 # All rights reserved.
3 3
4 # Written by Eric Price <eprice at tjhsst.edu> 4 # Written by Eric Price <eprice at tjhsst.edu>
5 # and Facundo Batista <facundo at taniquetil.com.ar> 5 # and Facundo Batista <facundo at taniquetil.com.ar>
6 # and Raymond Hettinger <python at rcn.com> 6 # and Raymond Hettinger <python at rcn.com>
7 # and Aahz <aahz at pobox.com> 7 # and Aahz <aahz at pobox.com>
8 # and Tim Peters 8 # and Tim Peters
9 9
10 # This module should be kept in sync with the latest updates of the 10 # This module should be kept in sync with the latest updates of the
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 121
122 # Exceptions 122 # Exceptions
123 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', 123 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
124 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', 124 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
125 125
126 # Constants for use in setting up contexts 126 # Constants for use in setting up contexts
127 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', 127 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
128 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', 128 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP',
129 129
130 # Functions for manipulating contexts 130 # Functions for manipulating contexts
131 'setcontext', 'getcontext', 'localcontext' 131 'setcontext', 'getcontext', 'localcontext',
132
133 # Limits for the C version for compatibility
134 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY',
135
136 # C version: compile time choice that enables the thread local context
137 'HAVE_THREADS'
132 ] 138 ]
133 139
134 __version__ = '1.70' # Highest version of the spec this complies with 140 __version__ = '1.70' # Highest version of the spec this complies with
135 # See http://speleotrove.com/decimal/ 141 # See http://speleotrove.com/decimal/
136 142
137 import copy as _copy 143 import copy as _copy
138 import math as _math 144 import math as _math
139 import numbers as _numbers 145 import numbers as _numbers
146 import sys
140 147
141 try: 148 try:
142 from collections import namedtuple as _namedtuple 149 from collections import namedtuple as _namedtuple
143 DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') 150 DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent')
144 except ImportError: 151 except ImportError:
145 DecimalTuple = lambda *args: args 152 DecimalTuple = lambda *args: args
146 153
147 # Rounding 154 # Rounding
148 ROUND_DOWN = 'ROUND_DOWN' 155 ROUND_DOWN = 'ROUND_DOWN'
149 ROUND_HALF_UP = 'ROUND_HALF_UP' 156 ROUND_HALF_UP = 'ROUND_HALF_UP'
150 ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' 157 ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
151 ROUND_CEILING = 'ROUND_CEILING' 158 ROUND_CEILING = 'ROUND_CEILING'
152 ROUND_FLOOR = 'ROUND_FLOOR' 159 ROUND_FLOOR = 'ROUND_FLOOR'
153 ROUND_UP = 'ROUND_UP' 160 ROUND_UP = 'ROUND_UP'
154 ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' 161 ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
155 ROUND_05UP = 'ROUND_05UP' 162 ROUND_05UP = 'ROUND_05UP'
163
164 # Compatibility with the C version
165 HAVE_THREADS = True
166 if sys.maxsize == 2**63-1:
167 MAX_PREC = 999999999999999999
168 MAX_EMAX = 999999999999999999
169 MIN_EMIN = -999999999999999999
170 else:
171 MAX_PREC = 425000000
172 MAX_EMAX = 425000000
173 MIN_EMIN = -425000000
174
175 MIN_ETINY = MIN_EMIN - (MAX_PREC-1)
156 176
157 # Errors 177 # Errors
158 178
159 class DecimalException(ArithmeticError): 179 class DecimalException(ArithmeticError):
160 """Base exception class. 180 """Base exception class.
161 181
162 Used exceptions derive from this. 182 Used exceptions derive from this.
163 If an exception derives from another exception besides this (such as 183 If an exception derives from another exception besides this (such as
164 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only 184 Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
165 called if the others are present. This isn't actually used for 185 called if the others are present. This isn't actually used for
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 # The getcontext() and setcontext() function manage access to a thread-local 409 # The getcontext() and setcontext() function manage access to a thread-local
390 # current context. Py2.4 offers direct support for thread locals. If that 410 # current context. Py2.4 offers direct support for thread locals. If that
391 # is not available, use threading.current_thread() which is slower but will 411 # is not available, use threading.current_thread() which is slower but will
392 # work for older Pythons. If threads are not part of the build, create a 412 # work for older Pythons. If threads are not part of the build, create a
393 # mock threading object with threading.local() returning the module namespace. 413 # mock threading object with threading.local() returning the module namespace.
394 414
395 try: 415 try:
396 import threading 416 import threading
397 except ImportError: 417 except ImportError:
398 # Python was compiled without threads; create a mock object instead 418 # Python was compiled without threads; create a mock object instead
399 import sys
400 class MockThreading(object): 419 class MockThreading(object):
401 def local(self, sys=sys): 420 def local(self, sys=sys):
402 return sys.modules[__name__] 421 return sys.modules[__name__]
403 threading = MockThreading() 422 threading = MockThreading()
404 del sys, MockThreading 423 del MockThreading
405 424
406 try: 425 try:
407 threading.local 426 threading.local
408 427
409 except AttributeError: 428 except AttributeError:
410 429
411 # To fix reloading, force it to create a new context 430 # To fix reloading, force it to create a new context
412 # Old contexts have different exceptions in their dicts, making problems. 431 # Old contexts have different exceptions in their dicts, making problems.
413 if hasattr(threading.current_thread(), '__decimal_context__'): 432 if hasattr(threading.current_thread(), '__decimal_context__'):
414 del threading.current_thread().__decimal_context__ 433 del threading.current_thread().__decimal_context__
(...skipping 1490 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 else: 1924 else:
1906 product = _dec_from_triple(self._sign ^ other._sign, 1925 product = _dec_from_triple(self._sign ^ other._sign,
1907 str(int(self._int) * int(other._int)), 1926 str(int(self._int) * int(other._int)),
1908 self._exp + other._exp) 1927 self._exp + other._exp)
1909 1928
1910 return product.__add__(third, context) 1929 return product.__add__(third, context)
1911 1930
1912 def _power_modulo(self, other, modulo, context=None): 1931 def _power_modulo(self, other, modulo, context=None):
1913 """Three argument version of __pow__""" 1932 """Three argument version of __pow__"""
1914 1933
1915 # if can't convert other and modulo to Decimal, raise 1934 other = _convert_other(other)
1916 # TypeError; there's no point returning NotImplemented (no 1935 if other is NotImplemented:
1917 # equivalent of __rpow__ for three argument pow) 1936 return other
1918 other = _convert_other(other, raiseit=True) 1937 modulo = _convert_other(modulo)
1919 modulo = _convert_other(modulo, raiseit=True) 1938 if modulo is NotImplemented:
1939 return modulo
1920 1940
1921 if context is None: 1941 if context is None:
1922 context = getcontext() 1942 context = getcontext()
1923 1943
1924 # deal with NaNs: if there are any sNaNs then first one wins, 1944 # deal with NaNs: if there are any sNaNs then first one wins,
1925 # (i.e. behaviour for NaNs is identical to that of fma) 1945 # (i.e. behaviour for NaNs is identical to that of fma)
1926 self_is_nan = self._isnan() 1946 self_is_nan = self._isnan()
1927 other_is_nan = other._isnan() 1947 other_is_nan = other._isnan()
1928 modulo_is_nan = modulo._isnan() 1948 modulo_is_nan = modulo._isnan()
1929 if self_is_nan or other_is_nan or modulo_is_nan: 1949 if self_is_nan or other_is_nan or modulo_is_nan:
(...skipping 1956 matching lines...) Expand 10 before | Expand all | Expand 10 after
3886 else: 3906 else:
3887 if value < vmin or value > vmax: 3907 if value < vmin or value > vmax:
3888 raise ValueError("%s must be in [%d, %d]. got %s" % (name, vmin, vmax, value)) 3908 raise ValueError("%s must be in [%d, %d]. got %s" % (name, vmin, vmax, value))
3889 return object.__setattr__(self, name, value) 3909 return object.__setattr__(self, name, value)
3890 3910
3891 def _set_signal_dict(self, name, d): 3911 def _set_signal_dict(self, name, d):
3892 if not isinstance(d, dict): 3912 if not isinstance(d, dict):
3893 raise TypeError("%s must be a signal dict" % d) 3913 raise TypeError("%s must be a signal dict" % d)
3894 for key in d: 3914 for key in d:
3895 if not key in _signals: 3915 if not key in _signals:
3896 raise TypeError("%s is not a valid signal dict" % d) 3916 raise KeyError("%s is not a valid signal dict" % d)
3897 for key in _signals: 3917 for key in _signals:
3898 if not key in d: 3918 if not key in d:
3899 raise TypeError("%s is not a valid signal dict" % d) 3919 raise KeyError("%s is not a valid signal dict" % d)
3900 return object.__setattr__(self, name, d) 3920 return object.__setattr__(self, name, d)
3901 3921
3902 def __setattr__(self, name, value): 3922 def __setattr__(self, name, value):
3903 if name == 'prec': 3923 if name == 'prec':
3904 return self._set_integer_check(name, value, 1, 'inf') 3924 return self._set_integer_check(name, value, 1, 'inf')
3905 elif name == 'Emin': 3925 elif name == 'Emin':
3906 return self._set_integer_check(name, value, '-inf', 0) 3926 return self._set_integer_check(name, value, '-inf', 0)
3907 elif name == 'Emax': 3927 elif name == 'Emax':
3908 return self._set_integer_check(name, value, 0, 'inf') 3928 return self._set_integer_check(name, value, 0, 'inf')
3909 elif name == 'capitals': 3929 elif name == 'capitals':
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3945 names = [f.__name__ for f, v in self.flags.items() if v] 3965 names = [f.__name__ for f, v in self.flags.items() if v]
3946 s.append('flags=[' + ', '.join(names) + ']') 3966 s.append('flags=[' + ', '.join(names) + ']')
3947 names = [t.__name__ for t, v in self.traps.items() if v] 3967 names = [t.__name__ for t, v in self.traps.items() if v]
3948 s.append('traps=[' + ', '.join(names) + ']') 3968 s.append('traps=[' + ', '.join(names) + ']')
3949 return ', '.join(s) + ')' 3969 return ', '.join(s) + ')'
3950 3970
3951 def clear_flags(self): 3971 def clear_flags(self):
3952 """Reset all flags to zero""" 3972 """Reset all flags to zero"""
3953 for flag in self.flags: 3973 for flag in self.flags:
3954 self.flags[flag] = 0 3974 self.flags[flag] = 0
3975
3976 def clear_traps(self):
3977 """Reset all traps to zero"""
3978 for flag in self.traps:
3979 self.traps[flag] = 0
3955 3980
3956 def _shallow_copy(self): 3981 def _shallow_copy(self):
3957 """Returns a shallow copy from self.""" 3982 """Returns a shallow copy from self."""
3958 nc = Context(self.prec, self.rounding, self.Emin, self.Emax, 3983 nc = Context(self.prec, self.rounding, self.Emin, self.Emax,
3959 self.capitals, self.clamp, self.flags, self.traps, 3984 self.capitals, self.clamp, self.flags, self.traps,
3960 self._ignored_flags) 3985 self._ignored_flags)
3961 return nc 3986 return nc
3962 3987
3963 def copy(self): 3988 def copy(self):
3964 """Returns a deep copy from self.""" 3989 """Returns a deep copy from self."""
(...skipping 2178 matching lines...) Expand 10 before | Expand all | Expand 10 after
6143 format_dict['sign'] = '-' 6168 format_dict['sign'] = '-'
6144 6169
6145 # minimumwidth defaults to 0; precision remains None if not given 6170 # minimumwidth defaults to 0; precision remains None if not given
6146 format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') 6171 format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0')
6147 if format_dict['precision'] is not None: 6172 if format_dict['precision'] is not None:
6148 format_dict['precision'] = int(format_dict['precision']) 6173 format_dict['precision'] = int(format_dict['precision'])
6149 6174
6150 # if format type is 'g' or 'G' then a precision of 0 makes little 6175 # if format type is 'g' or 'G' then a precision of 0 makes little
6151 # sense; convert it to 1. Same if format type is unspecified. 6176 # sense; convert it to 1. Same if format type is unspecified.
6152 if format_dict['precision'] == 0: 6177 if format_dict['precision'] == 0:
6153 if format_dict['type'] is None or format_dict['type'] in 'gG': 6178 if format_dict['type'] is None or format_dict['type'] in 'gGn':
6154 format_dict['precision'] = 1 6179 format_dict['precision'] = 1
6155 6180
6156 # determine thousands separator, grouping, and decimal separator, and 6181 # determine thousands separator, grouping, and decimal separator, and
6157 # add appropriate entries to format_dict 6182 # add appropriate entries to format_dict
6158 if format_dict['type'] == 'n': 6183 if format_dict['type'] == 'n':
6159 # apart from separators, 'n' behaves just like 'g' 6184 # apart from separators, 'n' behaves just like 'g'
6160 format_dict['type'] = 'g' 6185 format_dict['type'] = 'g'
6161 if _localeconv is None: 6186 if _localeconv is None:
6162 _localeconv = _locale.localeconv() 6187 _localeconv = _locale.localeconv()
6163 if format_dict['thousands_sep'] is not None: 6188 if format_dict['thousands_sep'] is not None:
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
6317 _NaN = Decimal('NaN') 6342 _NaN = Decimal('NaN')
6318 _Zero = Decimal(0) 6343 _Zero = Decimal(0)
6319 _One = Decimal(1) 6344 _One = Decimal(1)
6320 _NegativeOne = Decimal(-1) 6345 _NegativeOne = Decimal(-1)
6321 6346
6322 # _SignedInfinity[sign] is infinity w/ that sign 6347 # _SignedInfinity[sign] is infinity w/ that sign
6323 _SignedInfinity = (_Infinity, _NegativeInfinity) 6348 _SignedInfinity = (_Infinity, _NegativeInfinity)
6324 6349
6325 # Constants related to the hash implementation; hash(x) is based 6350 # Constants related to the hash implementation; hash(x) is based
6326 # on the reduction of x modulo _PyHASH_MODULUS 6351 # on the reduction of x modulo _PyHASH_MODULUS
6327 import sys
6328 _PyHASH_MODULUS = sys.hash_info.modulus 6352 _PyHASH_MODULUS = sys.hash_info.modulus
6329 # hash values to use for positive and negative infinities, and nans 6353 # hash values to use for positive and negative infinities, and nans
6330 _PyHASH_INF = sys.hash_info.inf 6354 _PyHASH_INF = sys.hash_info.inf
6331 _PyHASH_NAN = sys.hash_info.nan 6355 _PyHASH_NAN = sys.hash_info.nan
6332 6356
6333 # _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS 6357 # _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS
6334 _PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS) 6358 _PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)
6335 6359 del sys
6336 if not '_decimal' in sys.modules: 6360
6337 try: 6361 try:
6338 import _decimal 6362 import _decimal
6339 s1 = set(dir()) 6363 except ImportError:
6340 s2 = set(dir(_decimal)) 6364 pass
6341 for name in s1 - s2: 6365 else:
6342 del globals()[name] 6366 s1 = set(dir())
6343 del s1, s2, name 6367 s2 = set(dir(_decimal))
6344 from _decimal import * 6368 for name in s1 - s2:
6345 except: 6369 del globals()[name]
6346 del sys 6370 del s1, s2, name
6371 from _decimal import *
6347 6372
6348 if __name__ == '__main__': 6373 if __name__ == '__main__':
6349 import doctest, decimal 6374 import doctest, decimal
6350 doctest.testmod(decimal) 6375 doctest.testmod(decimal)
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+