From: Andrew Nester <andrew.nester.dev@gmail.com>
Date: Tue, 14 Feb 2017 18:22:55 +0000 (+0300)
Subject: Fixed #29534 - _decimal difference with _pydecimal (#65)
X-Git-Tag: v3.7.0a1~1344
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d1dece06d13a7d40637e07b2c79f34aab368766;p=python

Fixed #29534 - _decimal difference with _pydecimal (#65)
---

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].