diff options
author | Brett Cannon <bcannon@gmail.com> | 2005-04-26 03:45:26 (GMT) |
---|---|---|
committer | Brett Cannon <bcannon@gmail.com> | 2005-04-26 03:45:26 (GMT) |
commit | c3647ac93e2a38762de8a23b1d94a6380e9ad468 (patch) | |
tree | a7e00a7e8f70ee226fdeb3d229b9734d5b17a344 /Lib | |
parent | d7c795e72966f7c72b94b919f3539be66495e6c3 (diff) | |
download | cpython-c3647ac93e2a38762de8a23b1d94a6380e9ad468.zip cpython-c3647ac93e2a38762de8a23b1d94a6380e9ad468.tar.gz cpython-c3647ac93e2a38762de8a23b1d94a6380e9ad468.tar.bz2 |
Make subclasses of int, long, complex, float, and unicode perform type
conversion using the proper magic slot (e.g., __int__()). Also move conversion
code out of PyNumber_*() functions in the C API into the nb_* function.
Applied patch #1109424. Thanks Walter Doewald.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_builtin.py | 97 | ||||
-rw-r--r-- | Lib/test/test_complex.py | 22 | ||||
-rw-r--r-- | Lib/test/test_str.py | 63 | ||||
-rw-r--r-- | Lib/test/test_unicode.py | 64 |
4 files changed, 245 insertions, 1 deletions
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 4e8ffe5..103d1a3 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -545,6 +545,37 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(float(unicode(" 3.14 ")), 3.14) self.assertEqual(float(unicode(" \u0663.\u0661\u0664 ",'raw-unicode-escape')), 3.14) + def test_floatconversion(self): + # Make sure that calls to __float__() work properly + class Foo0: + def __float__(self): + return 42. + + class Foo1(object): + def __float__(self): + return 42. + + class Foo2(float): + def __float__(self): + return 42. + + class Foo3(float): + def __new__(cls, value=0.): + return float.__new__(cls, 2*value) + + def __float__(self): + return self + + class Foo4(float): + def __float__(self): + return 42 + + self.assertAlmostEqual(float(Foo0()), 42.) + self.assertAlmostEqual(float(Foo1()), 42.) + self.assertAlmostEqual(float(Foo2()), 42.) + self.assertAlmostEqual(float(Foo3(21)), 42.) + self.assertRaises(TypeError, float, Foo4(42)) + def test_getattr(self): import sys self.assert_(getattr(sys, 'stdout') is sys.stdout) @@ -650,6 +681,39 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(int('0123', 0), 83) + def test_intconversion(self): + # Test __int__() + class Foo0: + def __int__(self): + return 42 + + class Foo1(object): + def __int__(self): + return 42 + + class Foo2(int): + def __int__(self): + return 42 + + class Foo3(int): + def __int__(self): + return self + + class Foo4(int): + def __int__(self): + return 42L + + class Foo5(int): + def __int__(self): + return 42. + + self.assertEqual(int(Foo0()), 42) + self.assertEqual(int(Foo1()), 42) + self.assertEqual(int(Foo2()), 42) + self.assertEqual(int(Foo3()), 0) + self.assertEqual(int(Foo4()), 42L) + self.assertRaises(TypeError, int, Foo5()) + def test_intern(self): self.assertRaises(TypeError, intern) s = "never interned before" @@ -810,6 +874,39 @@ class BuiltinTest(unittest.TestCase): self.assertRaises(ValueError, long, '53', 40) self.assertRaises(TypeError, long, 1, 12) + def test_longconversion(self): + # Test __long__() + class Foo0: + def __long__(self): + return 42L + + class Foo1(object): + def __long__(self): + return 42L + + class Foo2(long): + def __long__(self): + return 42L + + class Foo3(long): + def __long__(self): + return self + + class Foo4(long): + def __long__(self): + return 42 + + class Foo5(long): + def __long__(self): + return 42. + + self.assertEqual(long(Foo0()), 42L) + self.assertEqual(long(Foo1()), 42L) + self.assertEqual(long(Foo2()), 42L) + self.assertEqual(long(Foo3()), 0) + self.assertEqual(long(Foo4()), 42) + self.assertRaises(TypeError, long, Foo5()) + def test_map(self): self.assertEqual( map(None, 'hello world'), diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 15f4b65..70e91c1 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -273,6 +273,28 @@ class ComplexTest(unittest.TestCase): self.assertAlmostEqual(complex(real=float2(17.), imag=float2(23.)), 17+23j) self.assertRaises(TypeError, complex, float2(None)) + class complex0(complex): + """Test usage of __complex__() when inheriting from 'complex'""" + def __complex__(self): + return 42j + + class complex1(complex): + """Test usage of __complex__() with a __new__() method""" + def __new__(self, value=0j): + return complex.__new__(self, 2*value) + def __complex__(self): + return self + + class complex2(complex): + """Make sure that __complex__() calls fail if anything other than a + complex is returned""" + def __complex__(self): + return None + + self.assertAlmostEqual(complex(complex0(1j)), 42j) + self.assertAlmostEqual(complex(complex1(1j)), 2j) + self.assertRaises(TypeError, complex, complex2(1j)) + def test_hash(self): for x in xrange(-30, 30): self.assertEqual(hash(x), hash(complex(x, 0))) diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py index 82632f1..45942a6 100644 --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -19,6 +19,69 @@ class StrTest( string_tests.MixinStrUnicodeUserStringTest.test_formatting(self) self.assertRaises(OverflowError, '%c'.__mod__, 0x1234) + def test_conversion(self): + # Make sure __str__() behaves properly + class Foo0: + def __unicode__(self): + return u"foo" + + class Foo1: + def __str__(self): + return "foo" + + class Foo2(object): + def __str__(self): + return "foo" + + class Foo3(object): + def __str__(self): + return u"foo" + + class Foo4(unicode): + def __str__(self): + return u"foo" + + class Foo5(str): + def __str__(self): + return u"foo" + + class Foo6(str): + def __str__(self): + return "foos" + + def __unicode__(self): + return u"foou" + + class Foo7(unicode): + def __str__(self): + return "foos" + def __unicode__(self): + return u"foou" + + class Foo8(str): + def __new__(cls, content=""): + return str.__new__(cls, 2*content) + def __str__(self): + return self + + class Foo9(str): + def __str__(self): + return "string" + def __unicode__(self): + return "not unicode" + + self.assert_(str(Foo0()).startswith("<")) # this is different from __unicode__ + self.assertEqual(str(Foo1()), "foo") + self.assertEqual(str(Foo2()), "foo") + self.assertEqual(str(Foo3()), "foo") + self.assertEqual(str(Foo4("bar")), "foo") + self.assertEqual(str(Foo5("bar")), "foo") + self.assertEqual(str(Foo6("bar")), "foos") + self.assertEqual(str(Foo7("bar")), "foos") + self.assertEqual(str(Foo8("foo")), "foofoo") + self.assertEqual(str(Foo9("foo")), "string") + self.assertEqual(unicode(Foo9("foo")), u"not unicode") + def test_main(): test_support.run_unittest(StrTest) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 69244f0..80242d5 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -389,7 +389,6 @@ class UnicodeTest( self.assertEqual('%i%s %*.*s' % (10, 3, 5, 3, u'abc',), u'103 abc') self.assertEqual('%c' % u'a', u'a') - def test_constructor(self): # unicode(obj) tests (this maps to PyObject_Unicode() at C level) @@ -725,6 +724,69 @@ class UnicodeTest( y = x.encode("raw-unicode-escape").decode("raw-unicode-escape") self.assertEqual(x, y) + def test_conversion(self): + # Make sure __unicode__() works properly + class Foo0: + def __str__(self): + return "foo" + + class Foo1: + def __unicode__(self): + return u"foo" + + class Foo2(object): + def __unicode__(self): + return u"foo" + + class Foo3(object): + def __unicode__(self): + return "foo" + + class Foo4(str): + def __unicode__(self): + return "foo" + + class Foo5(unicode): + def __unicode__(self): + return "foo" + + class Foo6(str): + def __str__(self): + return "foos" + + def __unicode__(self): + return u"foou" + + class Foo7(unicode): + def __str__(self): + return "foos" + def __unicode__(self): + return u"foou" + + class Foo8(unicode): + def __new__(cls, content=""): + return unicode.__new__(cls, 2*content) + def __unicode__(self): + return self + + class Foo9(unicode): + def __str__(self): + return "string" + def __unicode__(self): + return "not unicode" + + self.assertEqual(unicode(Foo0()), u"foo") + self.assertEqual(unicode(Foo1()), u"foo") + self.assertEqual(unicode(Foo2()), u"foo") + self.assertEqual(unicode(Foo3()), u"foo") + self.assertEqual(unicode(Foo4("bar")), u"foo") + self.assertEqual(unicode(Foo5("bar")), u"foo") + self.assertEqual(unicode(Foo6("bar")), u"foou") + self.assertEqual(unicode(Foo7("bar")), u"foou") + self.assertEqual(unicode(Foo8("foo")), u"foofoo") + self.assertEqual(str(Foo9("foo")), "string") + self.assertEqual(unicode(Foo9("foo")), u"not unicode") + def test_main(): test_support.run_unittest(UnicodeTest) |