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 /Objects | |
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 'Objects')
-rw-r--r-- | Objects/abstract.c | 84 | ||||
-rw-r--r-- | Objects/floatobject.c | 5 | ||||
-rw-r--r-- | Objects/intobject.c | 5 | ||||
-rw-r--r-- | Objects/longobject.c | 5 | ||||
-rw-r--r-- | Objects/object.c | 49 |
5 files changed, 73 insertions, 75 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 875c880..d28006a 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -951,7 +951,19 @@ PyNumber_Int(PyObject *o) Py_INCREF(o); return o; } - if (PyInt_Check(o)) { + m = o->ob_type->tp_as_number; + if (m && m->nb_int) { /* This should include subclasses of int */ + PyObject *res = m->nb_int(o); + if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; + } + if (PyInt_Check(o)) { /* A int subclass without nb_int */ PyIntObject *io = (PyIntObject*)o; return PyInt_FromLong(io->ob_ival); } @@ -964,18 +976,6 @@ PyNumber_Int(PyObject *o) PyUnicode_GET_SIZE(o), 10); #endif - m = o->ob_type->tp_as_number; - if (m && m->nb_int) { - PyObject *res = m->nb_int(o); - if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { - PyErr_Format(PyExc_TypeError, - "__int__ returned non-int (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; - } if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) return int_from_string((char*)buffer, buffer_len); @@ -1010,11 +1010,19 @@ PyNumber_Long(PyObject *o) if (o == NULL) return null_error(); - if (PyLong_CheckExact(o)) { - Py_INCREF(o); - return o; + m = o->ob_type->tp_as_number; + if (m && m->nb_long) { /* This should include subclasses of long */ + PyObject *res = m->nb_long(o); + if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { + PyErr_Format(PyExc_TypeError, + "__long__ returned non-long (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; } - if (PyLong_Check(o)) + if (PyLong_Check(o)) /* A long subclass without nb_long */ return _PyLong_Copy((PyLongObject *)o); if (PyString_Check(o)) /* need to do extra error checking that PyLong_FromString() @@ -1030,18 +1038,6 @@ PyNumber_Long(PyObject *o) PyUnicode_GET_SIZE(o), 10); #endif - m = o->ob_type->tp_as_number; - if (m && m->nb_long) { - PyObject *res = m->nb_long(o); - if (res && (!PyInt_Check(res) && !PyLong_Check(res))) { - PyErr_Format(PyExc_TypeError, - "__long__ returned non-long (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; - } if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) return long_from_string(buffer, buffer_len); @@ -1055,28 +1051,22 @@ PyNumber_Float(PyObject *o) if (o == NULL) return null_error(); - if (PyFloat_CheckExact(o)) { - Py_INCREF(o); - return o; + m = o->ob_type->tp_as_number; + if (m && m->nb_float) { /* This should include subclasses of float */ + PyObject *res = m->nb_float(o); + if (res && !PyFloat_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__float__ returned non-float (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; } - if (PyFloat_Check(o)) { + if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */ PyFloatObject *po = (PyFloatObject *)o; return PyFloat_FromDouble(po->ob_fval); } - if (!PyString_Check(o)) { - m = o->ob_type->tp_as_number; - if (m && m->nb_float) { - PyObject *res = m->nb_float(o); - if (res && !PyFloat_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__float__ returned non-float (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; - } - } return PyFloat_FromString(o, NULL); } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 539c4a9..55f43cb 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -926,7 +926,10 @@ float_int(PyObject *v) static PyObject * float_float(PyObject *v) { - Py_INCREF(v); + if (PyFloat_CheckExact(v)) + Py_INCREF(v); + else + v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); return v; } diff --git a/Objects/intobject.c b/Objects/intobject.c index 763ed53..0ead74b 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -826,7 +826,10 @@ int_coerce(PyObject **pv, PyObject **pw) static PyObject * int_int(PyIntObject *v) { - Py_INCREF(v); + if (PyInt_CheckExact(v)) + Py_INCREF(v); + else + v = (PyIntObject *)PyInt_FromLong(v->ob_ival); return (PyObject *)v; } diff --git a/Objects/longobject.c b/Objects/longobject.c index 11a7024..e4fc553 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -2861,7 +2861,10 @@ long_coerce(PyObject **pv, PyObject **pw) static PyObject * long_long(PyObject *v) { - Py_INCREF(v); + if (PyLong_CheckExact(v)) + Py_INCREF(v); + else + v = _PyLong_Copy((PyLongObject *)v); return v; } diff --git a/Objects/object.c b/Objects/object.c index d86d74f..975c967 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -373,6 +373,8 @@ PyObject * PyObject_Unicode(PyObject *v) { PyObject *res; + PyObject *func; + static PyObject *unicodestr; if (v == NULL) res = PyString_FromString("<NULL>"); @@ -380,35 +382,32 @@ PyObject_Unicode(PyObject *v) Py_INCREF(v); return v; } - if (PyUnicode_Check(v)) { - /* For a Unicode subtype that's not a Unicode object, - return a true Unicode object with the same data. */ - return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v), - PyUnicode_GET_SIZE(v)); + /* XXX As soon as we have a tp_unicode slot, we should + check this before trying the __unicode__ + method. */ + if (unicodestr == NULL) { + unicodestr= PyString_InternFromString("__unicode__"); + if (unicodestr == NULL) + return NULL; + } + func = PyObject_GetAttr(v, unicodestr); + if (func != NULL) { + res = PyEval_CallObject(func, (PyObject *)NULL); + Py_DECREF(func); } - if (PyString_Check(v)) { - Py_INCREF(v); - res = v; - } else { - PyObject *func; - static PyObject *unicodestr; - /* XXX As soon as we have a tp_unicode slot, we should - check this before trying the __unicode__ - method. */ - if (unicodestr == NULL) { - unicodestr= PyString_InternFromString( - "__unicode__"); - if (unicodestr == NULL) - return NULL; + PyErr_Clear(); + if (PyUnicode_Check(v)) { + /* For a Unicode subtype that's didn't overwrite __unicode__, + return a true Unicode object with the same data. */ + return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(v), + PyUnicode_GET_SIZE(v)); } - func = PyObject_GetAttr(v, unicodestr); - if (func != NULL) { - res = PyEval_CallObject(func, (PyObject *)NULL); - Py_DECREF(func); + if (PyString_CheckExact(v)) { + Py_INCREF(v); + res = v; } else { - PyErr_Clear(); if (v->ob_type->tp_str != NULL) res = (*v->ob_type->tp_str)(v); else @@ -424,7 +423,7 @@ PyObject_Unicode(PyObject *v) if (str) res = str; else - return NULL; + return NULL; } return res; } |