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.
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 @@
         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)