mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Issue 1780: Allow leading and trailing whitespace in Decimal constructor,
when constructing from a string. Disallow trailing newlines in Context.create_decimal.
This commit is contained in:
		
							parent
							
								
									bed4dd459d
								
							
						
					
					
						commit
						59bc20bb27
					
				
					 4 changed files with 37 additions and 6 deletions
				
			
		|  | @ -281,9 +281,10 @@ Decimal objects | ||||||
| 
 | 
 | ||||||
|    Construct a new :class:`Decimal` object based from *value*. |    Construct a new :class:`Decimal` object based from *value*. | ||||||
| 
 | 
 | ||||||
|    *value* can be an integer, string, tuple, or another :class:`Decimal` object. If |    *value* can be an integer, string, tuple, or another :class:`Decimal` | ||||||
|    no *value* is given, returns ``Decimal("0")``.  If *value* is a string, it |    object. If no *value* is given, returns ``Decimal("0")``.  If *value* is a | ||||||
|    should conform to the decimal numeric string syntax:: |    string, it should conform to the decimal numeric string syntax after leading | ||||||
|  |    and trailing whitespace characters are removed:: | ||||||
| 
 | 
 | ||||||
|       sign           ::=  '+' | '-' |       sign           ::=  '+' | '-' | ||||||
|       digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |       digit          ::=  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | ||||||
|  | @ -313,6 +314,10 @@ Decimal objects | ||||||
| 
 | 
 | ||||||
|    Once constructed, :class:`Decimal` objects are immutable. |    Once constructed, :class:`Decimal` objects are immutable. | ||||||
| 
 | 
 | ||||||
|  |    .. versionchanged:: 2.6 | ||||||
|  |       leading and trailing whitespace characters are permitted when | ||||||
|  |       creating a Decimal instance from a string. | ||||||
|  | 
 | ||||||
| Decimal floating point objects share many properties with the other built-in | Decimal floating point objects share many properties with the other built-in | ||||||
| numeric types such as :class:`float` and :class:`int`.  All of the usual math | numeric types such as :class:`float` and :class:`int`.  All of the usual math | ||||||
| operations and special methods apply.  Likewise, decimal objects can be copied, | operations and special methods apply.  Likewise, decimal objects can be copied, | ||||||
|  | @ -973,6 +978,9 @@ method.  For example, ``C.exp(x)`` is equivalent to | ||||||
|       >>> Decimal("3.4445") + Decimal(0) + Decimal("1.0023") |       >>> Decimal("3.4445") + Decimal(0) + Decimal("1.0023") | ||||||
|       Decimal("4.44") |       Decimal("4.44") | ||||||
| 
 | 
 | ||||||
|  |    This method implements the to-number operation of the IBM | ||||||
|  |    specification.  If the argument is a string, no leading or trailing | ||||||
|  |    whitespace is permitted. | ||||||
| 
 | 
 | ||||||
| .. method:: Context.Etiny() | .. method:: Context.Etiny() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -523,6 +523,8 @@ def __new__(cls, value="0", context=None): | ||||||
|         Decimal("314") |         Decimal("314") | ||||||
|         >>> Decimal(Decimal(314))        # another decimal instance |         >>> Decimal(Decimal(314))        # another decimal instance | ||||||
|         Decimal("314") |         Decimal("314") | ||||||
|  |         >>> Decimal('  3.14  \\n')        # leading and trailing whitespace okay | ||||||
|  |         Decimal("3.14") | ||||||
|         """ |         """ | ||||||
| 
 | 
 | ||||||
|         # Note that the coefficient, self._int, is actually stored as |         # Note that the coefficient, self._int, is actually stored as | ||||||
|  | @ -538,7 +540,7 @@ def __new__(cls, value="0", context=None): | ||||||
|         # From a string |         # From a string | ||||||
|         # REs insist on real strings, so we can too. |         # REs insist on real strings, so we can too. | ||||||
|         if isinstance(value, basestring): |         if isinstance(value, basestring): | ||||||
|             m = _parser(value) |             m = _parser(value.strip()) | ||||||
|             if m is None: |             if m is None: | ||||||
|                 if context is None: |                 if context is None: | ||||||
|                     context = getcontext() |                     context = getcontext() | ||||||
|  | @ -3533,7 +3535,16 @@ def _set_rounding(self, type): | ||||||
|         return rounding |         return rounding | ||||||
| 
 | 
 | ||||||
|     def create_decimal(self, num='0'): |     def create_decimal(self, num='0'): | ||||||
|         """Creates a new Decimal instance but using self as context.""" |         """Creates a new Decimal instance but using self as context. | ||||||
|  | 
 | ||||||
|  |         This method implements the to-number operation of the | ||||||
|  |         IBM Decimal specification.""" | ||||||
|  | 
 | ||||||
|  |         if isinstance(num, basestring) and num != num.strip(): | ||||||
|  |             return self._raise_error(ConversionSyntax, | ||||||
|  |                                      "no trailing or leading whitespace is " | ||||||
|  |                                      "permitted.") | ||||||
|  | 
 | ||||||
|         d = Decimal(num, context=self) |         d = Decimal(num, context=self) | ||||||
|         if d._isnan() and len(d._int) > self.prec - self._clamp: |         if d._isnan() and len(d._int) > self.prec - self._clamp: | ||||||
|             return self._raise_error(ConversionSyntax, |             return self._raise_error(ConversionSyntax, | ||||||
|  | @ -5148,7 +5159,7 @@ def _convert_other(other, raiseit=False): | ||||||
|         (?P<diag>\d*)         # with (possibly empty) diagnostic information. |         (?P<diag>\d*)         # with (possibly empty) diagnostic information. | ||||||
|     ) |     ) | ||||||
| #    \s* | #    \s* | ||||||
|     $ |     \Z | ||||||
| """, re.VERBOSE | re.IGNORECASE).match | """, re.VERBOSE | re.IGNORECASE).match | ||||||
| 
 | 
 | ||||||
| _all_zeros = re.compile('0*$').match | _all_zeros = re.compile('0*$').match | ||||||
|  |  | ||||||
|  | @ -429,6 +429,10 @@ def test_explicit_from_string(self): | ||||||
|         #just not a number |         #just not a number | ||||||
|         self.assertEqual(str(Decimal('ugly')), 'NaN') |         self.assertEqual(str(Decimal('ugly')), 'NaN') | ||||||
| 
 | 
 | ||||||
|  |         #leading and trailing whitespace permitted | ||||||
|  |         self.assertEqual(str(Decimal('1.3E4 \n')), '1.3E+4') | ||||||
|  |         self.assertEqual(str(Decimal('  -7.89')), '-7.89') | ||||||
|  | 
 | ||||||
|     def test_explicit_from_tuples(self): |     def test_explicit_from_tuples(self): | ||||||
| 
 | 
 | ||||||
|         #zero |         #zero | ||||||
|  | @ -517,6 +521,10 @@ def test_explicit_context_create_decimal(self): | ||||||
|         self.assertEqual(str(d), '456789') |         self.assertEqual(str(d), '456789') | ||||||
|         d = nc.create_decimal('456789') |         d = nc.create_decimal('456789') | ||||||
|         self.assertEqual(str(d), '4.57E+5') |         self.assertEqual(str(d), '4.57E+5') | ||||||
|  |         # leading and trailing whitespace should result in a NaN; | ||||||
|  |         # spaces are already checked in Cowlishaw's test-suite, so | ||||||
|  |         # here we just check that a trailing newline results in a NaN | ||||||
|  |         self.assertEqual(str(nc.create_decimal('3.14\n')), 'NaN') | ||||||
| 
 | 
 | ||||||
|         # from tuples |         # from tuples | ||||||
|         d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) ) |         d = Decimal( (1, (4, 3, 4, 9, 1, 3, 5, 3, 4), -25) ) | ||||||
|  |  | ||||||
|  | @ -351,6 +351,10 @@ Core and builtins | ||||||
| Library | Library | ||||||
| ------- | ------- | ||||||
| 
 | 
 | ||||||
|  | - Issue #1780: The Decimal constructor now accepts arbitrary leading | ||||||
|  |   and trailing whitespace when constructing from a string. | ||||||
|  |   Context.create_decimal no longer accepts trailing newlines. | ||||||
|  | 
 | ||||||
| - Decimal.as_tuple(), difflib.find_longest_match() and inspect functions | - Decimal.as_tuple(), difflib.find_longest_match() and inspect functions | ||||||
|   that returned a tuple now return a named tuple. |   that returned a tuple now return a named tuple. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Mark Dickinson
						Mark Dickinson