Skip to content

Instantly share code, notes, and snippets.

/patch.diff Secret

Created April 28, 2013 10:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/e48ef8e3cc7f67f4bf91 to your computer and use it in GitHub Desktop.
Save anonymous/e48ef8e3cc7f67f4bf91 to your computer and use it in GitHub Desktop.
diff --git a/Objects/abstract.c b/Objects/abstract.c
index ee744de..1cabd94 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1602,12 +1602,21 @@ PyNumber_Int(PyObject *o)
const char *buffer;
Py_ssize_t buffer_len;
+ static PyObject *int_name = NULL;
+ PyObject *int_func;
+
if (trunc_name == NULL) {
trunc_name = PyString_InternFromString("__trunc__");
if (trunc_name == NULL)
return NULL;
}
+ if (int_name == NULL) {
+ int_name = PyString_InternFromString("__int__");
+ if (int_name == NULL)
+ return NULL;
+ }
+
if (o == NULL)
return null_error();
if (PyInt_CheckExact(o)) {
@@ -1615,9 +1624,10 @@ PyNumber_Int(PyObject *o)
return o;
}
m = o->ob_type->tp_as_number;
- if (m && m->nb_int) { /* This should include subclasses of int */
+ int_func = PyObject_GetAttr(o, int_name);
+ if ((m && m->nb_int) || int_func) { /* This should include subclasses of int */
/* Classic classes always take this branch. */
- PyObject *res = m->nb_int(o);
+ PyObject *res = int_func? PyEval_CallObject(int_func, NULL) : m->nb_int(o);
if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
PyErr_Format(PyExc_TypeError,
"__int__ returned non-int (type %.200s)",
class Foo(object):
def __int__(self):
return 24
foo = Foo()
foo.__int__ = lambda: 42
print(int(foo))
# $ python test.py
# 24
# patched version
# $ ./python.exe test.py
# 42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment