summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-11-25 13:55:54 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-11-25 13:55:54 (GMT)
commit8d30ad7c8ad5df59be8a65c8f8dab0d13be00dab (patch)
tree65436ba5d34417e9e89804d3b1c2c324edfb2f4e /Lib
parent80767a38c74318acbd6fc4bfe228a1d0c0556221 (diff)
downloadcpython-8d30ad7c8ad5df59be8a65c8f8dab0d13be00dab.zip
cpython-8d30ad7c8ad5df59be8a65c8f8dab0d13be00dab.tar.gz
cpython-8d30ad7c8ad5df59be8a65c8f8dab0d13be00dab.tar.bz2
Issue #24731: Fixed crash on converting objects with special methods
__str__, __trunc__, and __float__ returning instances of subclasses of str, long, and float to subclasses of str, long, and float correspondingly.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_float.py15
-rw-r--r--Lib/test/test_int.py15
-rw-r--r--Lib/test/test_long.py17
-rw-r--r--Lib/test/test_str.py6
-rw-r--r--Lib/test/test_unicode.py9
5 files changed, 59 insertions, 3 deletions
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index 4224306..4ec894c 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -27,6 +27,12 @@ requires_IEEE_754 = unittest.skipUnless(have_getformat and
test_dir = os.path.dirname(__file__) or os.curdir
format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt')
+class FloatSubclass(float):
+ pass
+
+class OtherFloatSubclass(float):
+ pass
+
class GeneralFloatCases(unittest.TestCase):
def test_float(self):
@@ -200,6 +206,15 @@ class GeneralFloatCases(unittest.TestCase):
return ""
self.assertRaises(TypeError, time.sleep, Foo5())
+ # Issue #24731
+ class F:
+ def __float__(self):
+ return OtherFloatSubclass(42.)
+ self.assertAlmostEqual(float(F()), 42.)
+ self.assertIs(type(float(F())), OtherFloatSubclass)
+ self.assertAlmostEqual(FloatSubclass(F()), 42.)
+ self.assertIs(type(FloatSubclass(F())), FloatSubclass)
+
def test_is_integer(self):
self.assertFalse((1.1).is_integer())
self.assertTrue((1.).is_integer())
diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py
index 2ca6cf2..0dd8efc 100644
--- a/Lib/test/test_int.py
+++ b/Lib/test/test_int.py
@@ -45,6 +45,9 @@ if have_unicode:
(unichr(0x200), ValueError),
]
+class IntSubclass(int):
+ pass
+
class IntLongCommonTests(object):
"""Mixin of test cases to share between both test_int and test_long."""
@@ -477,6 +480,18 @@ class IntTestCases(IntLongCommonTests, unittest.TestCase):
self.fail("Failed to raise TypeError with %s" %
((base, trunc_result_base),))
+ class TruncReturnsIntSubclass(base):
+ def __trunc__(self):
+ return True
+ good_int = TruncReturnsIntSubclass()
+ n = int(good_int)
+ self.assertEqual(n, 1)
+ self.assertIs(type(n), bool)
+ n = IntSubclass(good_int)
+ self.assertEqual(n, 1)
+ self.assertIs(type(n), IntSubclass)
+
+
def test_main():
run_unittest(IntTestCases)
diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py
index ffa4774..b65d24c 100644
--- a/Lib/test/test_long.py
+++ b/Lib/test/test_long.py
@@ -79,6 +79,12 @@ if test_support.have_unicode:
(unichr(0x200), ValueError),
]
+class LongSubclass(long):
+ pass
+
+class OtherLongSubclass(long):
+ pass
+
class LongTest(test_int.IntLongCommonTests, unittest.TestCase):
ntype = long
@@ -539,6 +545,17 @@ class LongTest(test_int.IntLongCommonTests, unittest.TestCase):
self.fail("Failed to raise TypeError with %s" %
((base, trunc_result_base),))
+ class TruncReturnsLongSubclass(base):
+ def __long__(self):
+ return OtherLongSubclass(42L)
+ good_int = TruncReturnsLongSubclass()
+ n = long(good_int)
+ self.assertEqual(n, 42L)
+ self.assertIs(type(n), OtherLongSubclass)
+ n = LongSubclass(good_int)
+ self.assertEqual(n, 42L)
+ self.assertIs(type(n), LongSubclass)
+
def test_misc(self):
# check the extremes in int<->long conversion
diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py
index 774c634..5bb9f48 100644
--- a/Lib/test/test_str.py
+++ b/Lib/test/test_str.py
@@ -4,6 +4,9 @@ import sys
from test import test_support, string_tests
+class StrSubclass(str):
+ pass
+
class StrTest(
string_tests.CommonTest,
string_tests.MixinStrUnicodeUserStringTest,
@@ -107,6 +110,9 @@ class StrTest(
self.assertEqual(str(Foo6("bar")), "foos")
self.assertEqual(str(Foo7("bar")), "foos")
self.assertEqual(str(Foo8("foo")), "foofoo")
+ self.assertIs(type(str(Foo8("foo"))), Foo8)
+ self.assertEqual(StrSubclass(Foo8("foo")), "foofoo")
+ self.assertIs(type(StrSubclass(Foo8("foo"))), StrSubclass)
self.assertEqual(str(Foo9("foo")), "string")
self.assertEqual(unicode(Foo9("foo")), u"not unicode")
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index be8f89b..b12f982 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -33,6 +33,9 @@ def search_function(encoding):
return None
codecs.register(search_function)
+class UnicodeSubclass(unicode):
+ pass
+
class UnicodeTest(
string_tests.CommonTest,
string_tests.MixinStrUnicodeUserStringTest,
@@ -685,9 +688,6 @@ class UnicodeTest(
u'unicode remains unicode'
)
- class UnicodeSubclass(unicode):
- pass
-
self.assertEqual(
unicode(UnicodeSubclass('unicode subclass becomes unicode')),
u'unicode subclass becomes unicode'
@@ -1269,6 +1269,9 @@ class UnicodeTest(
self.assertEqual(unicode(Foo6("bar")), u"foou")
self.assertEqual(unicode(Foo7("bar")), u"foou")
self.assertEqual(unicode(Foo8("foo")), u"foofoo")
+ self.assertIs(type(unicode(Foo8("foo"))), Foo8)
+ self.assertEqual(UnicodeSubclass(Foo8("foo")), u"foofoo")
+ self.assertIs(type(UnicodeSubclass(Foo8("foo"))), UnicodeSubclass)
self.assertEqual(str(Foo9("foo")), "string")
self.assertEqual(unicode(Foo9("foo")), u"not unicode")