diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index 0b40928ff8d109..0fa152c2a6f8ef 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -734,18 +734,23 @@ def from_float(cls, f): """ 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 59a17af278c052..48360d1baedb64 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -1185,6 +1185,16 @@ def test_wide_char_separator_decimal_point(self): 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 eb870b7d48b76b..f650e5c605dc31 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].
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: