summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Nester <andrew.nester.dev@gmail.com>2017-02-14 18:22:55 (GMT)
committerMark Dickinson <mdickinson@enthought.com>2017-02-14 18:22:55 (GMT)
commit6d1dece06d13a7d40637e07b2c79f34aab368766 (patch)
tree3ca2a345299134cb312b3f6fbd9962e8e8dcdbb7
parentc33ee85b6fbed7f9c68e9fd39cd0582af9237ef1 (diff)
downloadcpython-6d1dece06d13a7d40637e07b2c79f34aab368766.zip
cpython-6d1dece06d13a7d40637e07b2c79f34aab368766.tar.gz
cpython-6d1dece06d13a7d40637e07b2c79f34aab368766.tar.bz2
Fixed #29534 - _decimal difference with _pydecimal (#65)
-rw-r--r--Lib/_pydecimal.py27
-rw-r--r--Lib/test/test_decimal.py10
-rw-r--r--Misc/NEWS2
3 files changed, 28 insertions, 11 deletions
diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
index 0b40928..0fa152c 100644
--- a/Lib/_pydecimal.py
+++ b/Lib/_pydecimal.py
@@ -734,18 +734,23 @@ class Decimal(object):
"""
if isinstance(f, int): # handle integer inputs
- return cls(f)
- if not isinstance(f, float):
- raise TypeError("argument must be int or float.")
- if _math.isinf(f) or _math.isnan(f):
- return cls(repr(f))
- if _math.copysign(1.0, f) == 1.0:
- sign = 0
+ sign = 0 if f >= 0 else 1
+ k = 0
+ coeff = str(abs(f))
+ elif isinstance(f, float):
+ if _math.isinf(f) or _math.isnan(f):
+ return cls(repr(f))
+ if _math.copysign(1.0, f) == 1.0:
+ sign = 0
+ else:
+ sign = 1
+ n, d = abs(f).as_integer_ratio()
+ k = d.bit_length() - 1
+ coeff = str(n*5**k)
else:
- sign = 1
- n, d = abs(f).as_integer_ratio()
- k = d.bit_length() - 1
- result = _dec_from_triple(sign, str(n*5**k), -k)
+ raise TypeError("argument must be int or float.")
+
+ result = _dec_from_triple(sign, coeff, -k)
if cls is Decimal:
return result
else:
diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py
index 59a17af..48360d1 100644
--- a/Lib/test/test_decimal.py
+++ b/Lib/test/test_decimal.py
@@ -1185,6 +1185,16 @@ class FormatTest(unittest.TestCase):
self.assertEqual(format(Decimal('100000000.123'), 'n'),
'100\u066c000\u066c000\u066b123')
+ def test_decimal_from_float_argument_type(self):
+ class A(self.decimal.Decimal):
+ def __init__(self, a):
+ self.a_type = type(a)
+ a = A.from_float(42.5)
+ self.assertEqual(self.decimal.Decimal, a.a_type)
+
+ a = A.from_float(42)
+ self.assertEqual(self.decimal.Decimal, a.a_type)
+
class CFormatTest(FormatTest):
decimal = C
class PyFormatTest(FormatTest):
diff --git a/Misc/NEWS b/Misc/NEWS
index 8786f19..e6df014 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ What's New in Python 3.7.0 alpha 1?
Core and Builtins
-----------------
+- bpo-29534: Fixed different behaviour of Decimal.from_float() for _decimal and _pydecimal.
+
- bpo-29438: Fixed use-after-free problem in key sharing dict.
- Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0].