mirror of
https://github.com/python/cpython.git
synced 2025-08-28 12:45:07 +00:00
Merged revisions 74279 via svnmerge from
svn+ssh://pythondev@www.python.org/python/branches/py3k ........ r74279 | mark.dickinson | 2009-08-02 11:14:23 +0100 (Sun, 02 Aug 2009) | 1 line Issue #6595: Allow Decimal constructor to accept non-European decimal digits, as recommended by the specification. ........
This commit is contained in:
parent
e634d87315
commit
8d238293cd
4 changed files with 28 additions and 20 deletions
|
@ -324,6 +324,11 @@ Decimal objects
|
||||||
numeric-value ::= decimal-part [exponent-part] | infinity
|
numeric-value ::= decimal-part [exponent-part] | infinity
|
||||||
numeric-string ::= [sign] numeric-value | [sign] nan
|
numeric-string ::= [sign] numeric-value | [sign] nan
|
||||||
|
|
||||||
|
Other Unicode decimal digits are also permitted where ``digit``
|
||||||
|
appears above. These include decimal digits from various other
|
||||||
|
alphabets (for example, Arabic-Indic and Devanāgarī digits) along
|
||||||
|
with the fullwidth digits ``'\uff10'`` through ``'\uff19'``.
|
||||||
|
|
||||||
If *value* is a :class:`tuple`, it should have three components, a sign
|
If *value* is a :class:`tuple`, it should have three components, a sign
|
||||||
(:const:`0` for positive or :const:`1` for negative), a :class:`tuple` of
|
(:const:`0` for positive or :const:`1` for negative), a :class:`tuple` of
|
||||||
digits, and an integer exponent. For example, ``Decimal((0, (1, 4, 1, 4), -3))``
|
digits, and an integer exponent. For example, ``Decimal((0, (1, 4, 1, 4), -3))``
|
||||||
|
|
|
@ -554,20 +554,16 @@ class Decimal(object):
|
||||||
intpart = m.group('int')
|
intpart = m.group('int')
|
||||||
if intpart is not None:
|
if intpart is not None:
|
||||||
# finite number
|
# finite number
|
||||||
fracpart = m.group('frac')
|
fracpart = m.group('frac') or ''
|
||||||
exp = int(m.group('exp') or '0')
|
exp = int(m.group('exp') or '0')
|
||||||
if fracpart is not None:
|
self._int = str(int(intpart+fracpart))
|
||||||
self._int = (intpart+fracpart).lstrip('0') or '0'
|
|
||||||
self._exp = exp - len(fracpart)
|
self._exp = exp - len(fracpart)
|
||||||
else:
|
|
||||||
self._int = intpart.lstrip('0') or '0'
|
|
||||||
self._exp = exp
|
|
||||||
self._is_special = False
|
self._is_special = False
|
||||||
else:
|
else:
|
||||||
diag = m.group('diag')
|
diag = m.group('diag')
|
||||||
if diag is not None:
|
if diag is not None:
|
||||||
# NaN
|
# NaN
|
||||||
self._int = diag.lstrip('0')
|
self._int = str(int(diag or '0')).lstrip('0')
|
||||||
if m.group('signal'):
|
if m.group('signal'):
|
||||||
self._exp = 'N'
|
self._exp = 'N'
|
||||||
else:
|
else:
|
||||||
|
@ -5482,26 +5478,23 @@ ExtendedContext = Context(
|
||||||
# 2. For finite numbers (not infinities and NaNs) the body of the
|
# 2. For finite numbers (not infinities and NaNs) the body of the
|
||||||
# number between the optional sign and the optional exponent must have
|
# number between the optional sign and the optional exponent must have
|
||||||
# at least one decimal digit, possibly after the decimal point. The
|
# at least one decimal digit, possibly after the decimal point. The
|
||||||
# lookahead expression '(?=[0-9]|\.[0-9])' checks this.
|
# lookahead expression '(?=\d|\.\d)' checks this.
|
||||||
#
|
|
||||||
# As the flag UNICODE is not enabled here, we're explicitly avoiding any
|
|
||||||
# other meaning for \d than the numbers [0-9].
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
_parser = re.compile(r""" # A numeric string consists of:
|
_parser = re.compile(r""" # A numeric string consists of:
|
||||||
# \s*
|
# \s*
|
||||||
(?P<sign>[-+])? # an optional sign, followed by either...
|
(?P<sign>[-+])? # an optional sign, followed by either...
|
||||||
(
|
(
|
||||||
(?=[0-9]|\.[0-9]) # ...a number (with at least one digit)
|
(?=\d|\.\d) # ...a number (with at least one digit)
|
||||||
(?P<int>[0-9]*) # having a (possibly empty) integer part
|
(?P<int>\d*) # having a (possibly empty) integer part
|
||||||
(\.(?P<frac>[0-9]*))? # followed by an optional fractional part
|
(\.(?P<frac>\d*))? # followed by an optional fractional part
|
||||||
(E(?P<exp>[-+]?[0-9]+))? # followed by an optional exponent, or...
|
(E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or...
|
||||||
|
|
|
|
||||||
Inf(inity)? # ...an infinity, or...
|
Inf(inity)? # ...an infinity, or...
|
||||||
|
|
|
|
||||||
(?P<signal>s)? # ...an (optionally signaling)
|
(?P<signal>s)? # ...an (optionally signaling)
|
||||||
NaN # NaN
|
NaN # NaN
|
||||||
(?P<diag>[0-9]*) # with (possibly empty) diagnostic info.
|
(?P<diag>\d*) # with (possibly empty) diagnostic info.
|
||||||
)
|
)
|
||||||
# \s*
|
# \s*
|
||||||
\Z
|
\Z
|
||||||
|
|
|
@ -425,9 +425,6 @@ class DecimalExplicitConstructionTest(unittest.TestCase):
|
||||||
self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
|
self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4')
|
||||||
self.assertEqual(str(Decimal(' -7.89')), '-7.89')
|
self.assertEqual(str(Decimal(' -7.89')), '-7.89')
|
||||||
|
|
||||||
#but alternate unicode digits should not
|
|
||||||
self.assertEqual(str(Decimal('\uff11')), 'NaN')
|
|
||||||
|
|
||||||
def test_explicit_from_tuples(self):
|
def test_explicit_from_tuples(self):
|
||||||
|
|
||||||
#zero
|
#zero
|
||||||
|
@ -534,6 +531,15 @@ class DecimalExplicitConstructionTest(unittest.TestCase):
|
||||||
d = nc.create_decimal(prevdec)
|
d = nc.create_decimal(prevdec)
|
||||||
self.assertEqual(str(d), '5.00E+8')
|
self.assertEqual(str(d), '5.00E+8')
|
||||||
|
|
||||||
|
def test_unicode_digits(self):
|
||||||
|
test_values = {
|
||||||
|
'\uff11': '1',
|
||||||
|
'\u0660.\u0660\u0663\u0667\u0662e-\u0663' : '0.0000372',
|
||||||
|
'-nan\u0c68\u0c6a\u0c66\u0c66' : '-NaN2400',
|
||||||
|
}
|
||||||
|
for input, expected in test_values.items():
|
||||||
|
self.assertEqual(str(Decimal(input)), expected)
|
||||||
|
|
||||||
|
|
||||||
class DecimalImplicitConstructionTest(unittest.TestCase):
|
class DecimalImplicitConstructionTest(unittest.TestCase):
|
||||||
'''Unit tests for Implicit Construction cases of Decimal.'''
|
'''Unit tests for Implicit Construction cases of Decimal.'''
|
||||||
|
|
|
@ -42,6 +42,10 @@ C-API
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #6595: The Decimal constructor now allows arbitrary Unicode
|
||||||
|
decimal digits in input, as recommended by the standard. Previously
|
||||||
|
it was restricted to accepting [0-9].
|
||||||
|
|
||||||
- Issues #5155, #5313, #5331: multiprocessing.Process._bootstrap was
|
- Issues #5155, #5313, #5331: multiprocessing.Process._bootstrap was
|
||||||
unconditionally calling "os.close(sys.stdin.fileno())" resulting in file
|
unconditionally calling "os.close(sys.stdin.fileno())" resulting in file
|
||||||
descriptor errors
|
descriptor errors
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue