From 6d1dece06d13a7d40637e07b2c79f34aab368766 Mon Sep 17 00:00:00 2001 From: Andrew Nester Date: Tue, 14 Feb 2017 21:22:55 +0300 Subject: [PATCH] Fixed #29534 - _decimal difference with _pydecimal (#65) --- Lib/_pydecimal.py | 27 ++++++++++++++++----------- Lib/test/test_decimal.py | 10 ++++++++++ Misc/NEWS | 2 ++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index 0b40928ff8..0fa152c2a6 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 59a17af278..48360d1bae 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 8786f19e47..e6df0144b1 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]. -- 2.40.0