Make int() and long() fall back to __trunc__(). See issue 2002.
diff --git a/Objects/classobject.c b/Objects/classobject.c
index b4b17f9..9f364e2 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -1798,7 +1798,29 @@
UNARY(instance_invert, "__invert__")
-UNARY(instance_int, "__int__")
+UNARY(_instance_trunc, "__trunc__")
+
+static PyObject *
+instance_int(PyInstanceObject *self)
+{
+ PyObject *truncated;
+ static PyObject *int_name;
+ if (int_name == NULL) {
+ int_name = PyString_InternFromString("__int__");
+ if (int_name == NULL)
+ return NULL;
+ }
+ if (PyObject_HasAttr((PyObject*)self, int_name))
+ return generic_unary_op(self, int_name);
+
+ truncated = _instance_trunc(self);
+ /* __trunc__ is specified to return an Integral type, but
+ int() needs to return an int. */
+ return _PyNumber_ConvertIntegralToInt(
+ truncated,
+ "__trunc__ returned non-Integral (type %.200s)");
+}
+
UNARY_FB(instance_long, "__long__", instance_int)
UNARY(instance_float, "__float__")
UNARY(instance_oct, "__oct__")