Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22355/Objects Modified Files: classobject.c Log Message: Make instances a new style number type. See PEP 208 for details. Instance types no longer get special treatment from abstract.c so more number number methods have to be implemented. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.112 retrieving revision 2.113 diff -C2 -r2.112 -r2.113 *** classobject.c 2000/10/24 19:57:45 2.112 --- classobject.c 2001/01/04 01:43:46 2.113 *************** *** 5,8 **** --- 5,9 ---- #include "structmember.h" + /* Forward */ static PyObject *class_lookup(PyClassObject *, PyObject *, *************** *** 756,789 **** } - static PyObject * - instance_compare1(PyObject *inst, PyObject *other) - { - return PyInstance_DoBinOp(inst, other, "__cmp__", "__rcmp__", - instance_compare1); - } - - static int - instance_compare(PyObject *inst, PyObject *other) - { - PyObject *result; - long outcome; - result = instance_compare1(inst, other); - if (result == NULL) - return -1; - if (!PyInt_Check(result)) { - Py_DECREF(result); - PyErr_SetString(PyExc_TypeError, - "comparison did not return an int"); - return -1; - } - outcome = PyInt_AsLong(result); - Py_DECREF(result); - if (outcome < 0) - return -1; - else if (outcome > 0) - return 1; - return 0; - } - static long instance_hash(PyInstanceObject *inst) --- 757,760 ---- *************** *** 1185,1302 **** return res; } - ! /* Implement a binary operator involving at least one class instance. */ ! ! PyObject * ! PyInstance_DoBinOp(PyObject *v, PyObject *w, char *opname, char *ropname, ! PyObject * (*thisfunc)(PyObject *, PyObject *)) { ! char buf[256]; ! PyObject *result = NULL; ! ! if (PyInstance_HalfBinOp(v, w, opname, &result, thisfunc, 0) <= 0) ! return result; ! if (PyInstance_HalfBinOp(w, v, ropname, &result, thisfunc, 1) <= 0) ! return result; ! /* Sigh -- special case for comparisons */ ! if (strcmp(opname, "__cmp__") == 0) { ! Py_uintptr_t iv = (Py_uintptr_t)v; ! Py_uintptr_t iw = (Py_uintptr_t)w; ! long c = (iv < iw) ? -1 : (iv > iw) ? 1 : 0; ! return PyInt_FromLong(c); } ! sprintf(buf, "%s nor %s defined for these operands", opname, ropname); ! PyErr_SetString(PyExc_TypeError, buf); ! return NULL; } - /* Try one half of a binary operator involving a class instance. - Return value: - -1 if an exception is to be reported right away - 0 if we have a valid result - 1 if we could try another operation - */ - static PyObject *coerce_obj; ! int ! PyInstance_HalfBinOp(PyObject *v, PyObject *w, char *opname, PyObject **r_result, ! PyObject * (*thisfunc)(PyObject *, PyObject *), int swapped) { - PyObject *func; PyObject *args; PyObject *coercefunc; PyObject *coerced = NULL; PyObject *v1; ! if (!PyInstance_Check(v)) ! return 1; if (coerce_obj == NULL) { coerce_obj = PyString_InternFromString("__coerce__"); if (coerce_obj == NULL) ! return -1; } coercefunc = PyObject_GetAttr(v, coerce_obj); if (coercefunc == NULL) { PyErr_Clear(); } ! else { ! args = Py_BuildValue("(O)", w); ! if (args == NULL) { ! return -1; ! } ! coerced = PyEval_CallObject(coercefunc, args); ! Py_DECREF(args); ! Py_DECREF(coercefunc); ! if (coerced == NULL) { ! return -1; ! } ! if (coerced == Py_None) { ! Py_DECREF(coerced); ! return 1; ! } ! if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) { ! Py_DECREF(coerced); ! PyErr_SetString(PyExc_TypeError, ! "coercion should return None or 2-tuple"); ! return -1; ! } ! v1 = PyTuple_GetItem(coerced, 0); ! w = PyTuple_GetItem(coerced, 1); ! if (v1 != v) { ! v = v1; ! if (!PyInstance_Check(v) && !PyInstance_Check(w)) { ! if (swapped) ! *r_result = (*thisfunc)(w, v); ! else ! *r_result = (*thisfunc)(v, w); ! Py_DECREF(coerced); ! return *r_result == NULL ? -1 : 0; ! } ! } ! } ! func = PyObject_GetAttrString(v, opname); ! if (func == NULL) { ! Py_XDECREF(coerced); ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return -1; ! PyErr_Clear(); ! return 1; ! } args = Py_BuildValue("(O)", w); if (args == NULL) { ! Py_DECREF(func); ! Py_XDECREF(coerced); ! return -1; } ! *r_result = PyEval_CallObject(func, args); Py_DECREF(args); ! Py_DECREF(func); ! Py_XDECREF(coerced); ! return *r_result == NULL ? -1 : 0; } static int instance_coerce(PyObject **pv, PyObject **pw) --- 1156,1275 ---- return res; } ! static PyObject * ! generic_binary_op(PyObject *v, PyObject *w, char *opname) { ! PyObject *result; ! PyObject *args; ! PyObject *func = PyObject_GetAttrString(v, opname); ! if (func == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return NULL; ! PyErr_Clear(); ! Py_INCREF(Py_NotImplemented); ! return Py_NotImplemented; } ! args = Py_BuildValue("(O)", w); ! if (args == NULL) { ! Py_DECREF(func); ! return NULL; ! } ! result = PyEval_CallObject(func, args); ! Py_DECREF(args); ! Py_DECREF(func); ! return result; } static PyObject *coerce_obj; ! /* Try one half of a binary operator involving a class instance. */ ! static PyObject * ! half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc, ! int swapped) { PyObject *args; PyObject *coercefunc; PyObject *coerced = NULL; PyObject *v1; + PyObject *result; ! if (!PyInstance_Check(v)) { ! Py_INCREF(Py_NotImplemented); ! return Py_NotImplemented; ! } ! if (coerce_obj == NULL) { coerce_obj = PyString_InternFromString("__coerce__"); if (coerce_obj == NULL) ! return NULL; } coercefunc = PyObject_GetAttr(v, coerce_obj); if (coercefunc == NULL) { PyErr_Clear(); + return generic_binary_op(v, w, opname); } ! args = Py_BuildValue("(O)", w); if (args == NULL) { ! return NULL; } ! coerced = PyEval_CallObject(coercefunc, args); Py_DECREF(args); ! Py_DECREF(coercefunc); ! if (coerced == NULL) { ! return NULL; ! } ! if (coerced == Py_None || coerced == Py_NotImplemented) { ! Py_DECREF(coerced); ! return generic_binary_op(v, w, opname); ! } ! if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) { ! Py_DECREF(coerced); ! PyErr_SetString(PyExc_TypeError, ! "coercion should return None or 2-tuple"); ! return NULL; ! } ! v1 = PyTuple_GetItem(coerced, 0); ! w = PyTuple_GetItem(coerced, 1); ! if (v1 == v) { ! /* prevent recursion if __coerce__ returns self as the first ! * argument */ ! result = generic_binary_op(v, w, opname); ! } else { ! if (swapped) ! result = (thisfunc)(w, v1); ! else ! result = (thisfunc)(v1, w); ! } ! Py_DECREF(coerced); ! return result; ! } ! ! /* Implement a binary operator involving at least one class instance. */ ! static PyObject * ! do_binop(PyObject *v, PyObject *w, char *opname, char *ropname, ! binaryfunc thisfunc) ! { ! PyObject *result = half_binop(v, w, opname, thisfunc, 0); ! if (result == Py_NotImplemented) { ! Py_DECREF(Py_NotImplemented); ! result = half_binop(w, v, ropname, thisfunc, 1); ! } ! return result; } + static PyObject * + do_binop_inplace(PyObject *v, PyObject *w, char *iopname, char *opname, + char *ropname, binaryfunc thisfunc) + { + PyObject *result = half_binop(v, w, iopname, thisfunc, 0); + if (result == Py_NotImplemented) { + Py_DECREF(Py_NotImplemented); + result = do_binop(v, w, opname, ropname, thisfunc); + } + return result; + } + static int instance_coerce(PyObject **pv, PyObject **pw) *************** *** 1315,1323 **** coercefunc = PyObject_GetAttr(v, coerce_obj); if (coercefunc == NULL) { ! /* No __coerce__ method: always OK */ PyErr_Clear(); Py_INCREF(v); Py_INCREF(w); ! return 0; } /* Has __coerce__ method: call it */ --- 1288,1296 ---- coercefunc = PyObject_GetAttr(v, coerce_obj); if (coercefunc == NULL) { ! /* No __coerce__ method */ PyErr_Clear(); Py_INCREF(v); Py_INCREF(w); ! return 1; } /* Has __coerce__ method: call it */ *************** *** 1333,1337 **** return -1; } ! if (coerced == Py_None) { /* __coerce__ says "I can't do it" */ Py_DECREF(coerced); --- 1306,1310 ---- return -1; } ! if (coerced == Py_None || coerced == Py_NotImplemented) { /* __coerce__ says "I can't do it" */ Py_DECREF(coerced); *************** *** 1354,1358 **** } - #define UNARY(funcname, methodname) \ static PyObject *funcname(PyInstanceObject *self) { \ --- 1327,1330 ---- *************** *** 1362,1370 **** --- 1334,1434 ---- } + #define BINARY(f, m, n) \ + static PyObject *f(PyObject *v, PyObject *w) { \ + return do_binop(v, w, "__" m "__", "__r" m "__", n); \ + } + + #define BINARY_INPLACE(f, m, n) \ + static PyObject *f(PyObject *v, PyObject *w) { \ + return do_binop_inplace(v, w, "__i" m "__", "__" m "__", \ + "__r" m "__", n); \ + } + UNARY(instance_neg, "__neg__") UNARY(instance_pos, "__pos__") UNARY(instance_abs, "__abs__") + BINARY(instance_or, "or", PyNumber_Or) + BINARY(instance_and, "and", PyNumber_And) + BINARY(instance_xor, "xor", PyNumber_Xor) + BINARY(instance_lshift, "lshift", PyNumber_Lshift) + BINARY(instance_rshift, "rshift", PyNumber_Rshift) + BINARY(instance_add, "add", PyNumber_Add) + BINARY(instance_sub, "sub", PyNumber_Subtract) + BINARY(instance_mul, "mul", PyNumber_Multiply) + BINARY(instance_div, "div", PyNumber_Divide) + BINARY(instance_mod, "mod", PyNumber_Remainder) + BINARY(instance_divmod, "divmod", PyNumber_Divmod) + + BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr) + BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor) + BINARY_INPLACE(instance_iand, "and", PyNumber_InPlaceAnd) + BINARY_INPLACE(instance_ilshift, "lshift", PyNumber_InPlaceLshift) + BINARY_INPLACE(instance_irshift, "rshift", PyNumber_InPlaceRshift) + BINARY_INPLACE(instance_iadd, "add", PyNumber_InPlaceAdd) + BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract) + BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply) + BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide) + BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder) + + static PyObject * + do_cmp(PyObject *v, PyObject *w) + { + int cmp = PyObject_Compare(v, w); + if (PyErr_Occurred()) { + return NULL; + } + return PyInt_FromLong(cmp); + } + + static PyObject * + instance_cmp(PyObject *v, PyObject *w) + { + PyObject *result = half_binop(v, w, "__cmp__", do_cmp, 0); + if (result == Py_NotImplemented) { + Py_DECREF(Py_NotImplemented); + /* __rcmp__ is not called on instances, instead they + * automaticly reverse the arguments and return the negative of + * __cmp__ if it exists */ + result = half_binop(w, v, "__cmp__", do_cmp, 0); + + if (result != Py_NotImplemented && result != NULL) { + PyObject *r = PyNumber_Negative(result); + Py_DECREF(result); + result = r; + } + } + return result; + } + static int + instance_compare(PyObject *inst, PyObject *other) + { + PyObject *result; + long outcome; + result = instance_cmp(inst, other); + if (result == NULL) { + return -1; + } + if (result == Py_NotImplemented) { + Py_DECREF(result); + return -1; + } + if (!PyInt_Check(result)) { + Py_DECREF(result); + PyErr_SetString(PyExc_TypeError, + "comparison did not return an int"); + return -1; + } + outcome = PyInt_AsLong(result); + Py_DECREF(result); + if (outcome < 0) + return -1; + else if (outcome > 0) + return 1; + return 0; + } + + static int instance_nonzero(PyInstanceObject *self) { *************** *** 1413,1479 **** UNARY(instance_hex, "__hex__") /* This version is for ternary calls only (z != None) */ static PyObject * instance_pow(PyObject *v, PyObject *w, PyObject *z) ! { ! /* XXX Doesn't do coercions... */ ! PyObject *func; ! PyObject *args; ! PyObject *result; ! static PyObject *powstr; ! if (powstr == NULL) ! powstr = PyString_InternFromString("__pow__"); ! func = PyObject_GetAttr(v, powstr); ! if (func == NULL) ! return NULL; ! args = Py_BuildValue("(OO)", w, z); ! if (args == NULL) { Py_DECREF(func); ! return NULL; } - result = PyEval_CallObject(func, args); - Py_DECREF(func); - Py_DECREF(args); - return result; } static PyObject * ! instance_inplace_pow(PyObject *v, PyObject *w, PyObject *z) { ! /* XXX Doesn't do coercions... */ ! PyObject *func; ! PyObject *args; ! PyObject *result; ! static PyObject *ipowstr; ! if (ipowstr == NULL) ! ipowstr = PyString_InternFromString("__ipow__"); ! func = PyObject_GetAttr(v, ipowstr); ! if (func == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return NULL; ! PyErr_Clear(); ! return instance_pow(v, w, z); } ! args = Py_BuildValue("(OO)", w, z); ! if (args == NULL) { Py_DECREF(func); ! return NULL; } - result = PyEval_CallObject(func, args); - Py_DECREF(func); - Py_DECREF(args); - return result; } static PyNumberMethods instance_as_number = { ! 0, /*nb_add*/ ! 0, /*nb_subtract*/ ! 0, /*nb_multiply*/ ! 0, /*nb_divide*/ ! 0, /*nb_remainder*/ ! 0, /*nb_divmod*/ (ternaryfunc)instance_pow, /*nb_power*/ (unaryfunc)instance_neg, /*nb_negative*/ --- 1477,1562 ---- UNARY(instance_hex, "__hex__") + static PyObject * + bin_power(PyObject *v, PyObject *w) + { + return PyNumber_Power(v, w, Py_None); + } + /* This version is for ternary calls only (z != None) */ static PyObject * instance_pow(PyObject *v, PyObject *w, PyObject *z) ! { ! if (z == Py_None) { ! return do_binop(v, w, "__pow__", "__rpow__", bin_power); ! } ! else { ! PyObject *func; ! PyObject *args; ! PyObject *result; ! /* XXX Doesn't do coercions... */ ! func = PyObject_GetAttrString(v, "__pow__"); ! if (func == NULL) ! return NULL; ! args = Py_BuildValue("(OO)", w, z); ! if (args == NULL) { ! Py_DECREF(func); ! return NULL; ! } ! result = PyEval_CallObject(func, args); Py_DECREF(func); ! Py_DECREF(args); ! return result; } } static PyObject * ! bin_inplace_power(PyObject *v, PyObject *w) { ! return PyNumber_InPlacePower(v, w, Py_None); ! } ! ! static PyObject * ! instance_ipow(PyObject *v, PyObject *w, PyObject *z) ! { ! if (z == Py_None) { ! return do_binop_inplace(v, w, "__ipow__", "__pow__", ! "__rpow__", bin_inplace_power); } ! else { ! /* XXX Doesn't do coercions... */ ! PyObject *func; ! PyObject *args; ! PyObject *result; ! ! func = PyObject_GetAttrString(v, "__ipow__"); ! if (func == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return NULL; ! PyErr_Clear(); ! return instance_pow(v, w, z); ! } ! args = Py_BuildValue("(OO)", w, z); ! if (args == NULL) { ! Py_DECREF(func); ! return NULL; ! } ! result = PyEval_CallObject(func, args); Py_DECREF(func); ! Py_DECREF(args); ! return result; } } + static PyNumberMethods instance_as_number = { ! (binaryfunc)instance_add, /*nb_add*/ ! (binaryfunc)instance_sub, /*nb_subtract*/ ! (binaryfunc)instance_mul, /*nb_multiply*/ ! (binaryfunc)instance_div, /*nb_divide*/ ! (binaryfunc)instance_mod, /*nb_remainder*/ ! (binaryfunc)instance_divmod, /*nb_divmod*/ (ternaryfunc)instance_pow, /*nb_power*/ (unaryfunc)instance_neg, /*nb_negative*/ *************** *** 1482,1490 **** (inquiry)instance_nonzero, /*nb_nonzero*/ (unaryfunc)instance_invert, /*nb_invert*/ ! 0, /*nb_lshift*/ ! 0, /*nb_rshift*/ ! 0, /*nb_and*/ ! 0, /*nb_xor*/ ! 0, /*nb_or*/ (coercion)instance_coerce, /*nb_coerce*/ (unaryfunc)instance_int, /*nb_int*/ --- 1565,1573 ---- (inquiry)instance_nonzero, /*nb_nonzero*/ (unaryfunc)instance_invert, /*nb_invert*/ ! (binaryfunc)instance_lshift, /*nb_lshift*/ ! (binaryfunc)instance_rshift, /*nb_rshift*/ ! (binaryfunc)instance_and, /*nb_and*/ ! (binaryfunc)instance_xor, /*nb_xor*/ ! (binaryfunc)instance_or, /*nb_or*/ (coercion)instance_coerce, /*nb_coerce*/ (unaryfunc)instance_int, /*nb_int*/ *************** *** 1493,1507 **** (unaryfunc)instance_oct, /*nb_oct*/ (unaryfunc)instance_hex, /*nb_hex*/ ! 0, /*nb_inplace_add*/ ! 0, /*nb_inplace_subtract*/ ! 0, /*nb_inplace_multiply*/ ! 0, /*nb_inplace_divide*/ ! 0, /*nb_inplace_remainder*/ ! (ternaryfunc)instance_inplace_pow, /*nb_inplace_power*/ ! 0, /*nb_inplace_lshift*/ ! 0, /*nb_inplace_rshift*/ ! 0, /*nb_inplace_and*/ ! 0, /*nb_inplace_xor*/ ! 0, /*nb_inplace_or*/ }; --- 1576,1591 ---- (unaryfunc)instance_oct, /*nb_oct*/ (unaryfunc)instance_hex, /*nb_hex*/ ! (binaryfunc)instance_iadd, /*nb_inplace_add*/ ! (binaryfunc)instance_isub, /*nb_inplace_subtract*/ ! (binaryfunc)instance_imul, /*nb_inplace_multiply*/ ! (binaryfunc)instance_idiv, /*nb_inplace_divide*/ ! (binaryfunc)instance_imod, /*nb_inplace_remainder*/ ! (ternaryfunc)instance_ipow, /*nb_inplace_power*/ ! (binaryfunc)instance_ilshift, /*nb_inplace_lshift*/ ! (binaryfunc)instance_irshift, /*nb_inplace_rshift*/ ! (binaryfunc)instance_iand, /*nb_inplace_and*/ ! (binaryfunc)instance_ixor, /*nb_inplace_xor*/ ! (binaryfunc)instance_ior, /*nb_inplace_or*/ ! (binaryfunc)instance_cmp, /*nb_cmp*/ }; *************** *** 1526,1531 **** (getattrofunc)instance_getattr, /*tp_getattro*/ (setattrofunc)instance_setattr, /*tp_setattro*/ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/ 0, /* tp_doc */ (traverseproc)instance_traverse, /* tp_traverse */ --- 1610,1615 ---- (getattrofunc)instance_getattr, /*tp_getattro*/ (setattrofunc)instance_setattr, /*tp_setattro*/ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC | Py_TPFLAGS_NEWSTYLENUMBER, /*tp_flags*/ 0, /* tp_doc */ (traverseproc)instance_traverse, /* tp_traverse */
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4