From 427c84f13f7719e6014a21bd1b81efdc02a046fb Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Thu, 6 Feb 2020 06:54:05 -0800 Subject: bpo-39274: Ensure Fraction.__bool__() returns a bool (GH-18017) Some numerator types used (specifically NumPy) decides to not return a Python boolean for the "a != b" operation. Using the equivalent call to bool() guarantees a bool return also for such types. --- Lib/test/test_fractions.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'Lib/test/test_fractions.py') diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 7cf7899932..4649a34bcc 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -6,6 +6,7 @@ import math import numbers import operator import fractions +import functools import sys import unittest import warnings @@ -322,6 +323,42 @@ class FractionTest(unittest.TestCase): self.assertTypedEquals(0.1+0j, complex(F(1,10))) + def testBoolGuarateesBoolReturn(self): + # Ensure that __bool__ is used on numerator which guarantees a bool + # return. See also bpo-39274. + @functools.total_ordering + class CustomValue: + denominator = 1 + + def __init__(self, value): + self.value = value + + def __bool__(self): + return bool(self.value) + + @property + def numerator(self): + # required to preserve `self` during instantiation + return self + + def __eq__(self, other): + raise AssertionError("Avoid comparisons in Fraction.__bool__") + + __lt__ = __eq__ + + # We did not implement all abstract methods, so register: + numbers.Rational.register(CustomValue) + + numerator = CustomValue(1) + r = F(numerator) + # ensure the numerator was not lost during instantiation: + self.assertIs(r.numerator, numerator) + self.assertIs(bool(r), True) + + numerator = CustomValue(0) + r = F(numerator) + self.assertIs(bool(r), False) + def testRound(self): self.assertTypedEquals(F(-200), round(F(-150), -2)) self.assertTypedEquals(F(-200), round(F(-250), -2)) -- cgit v1.2.1