PyObject * PyNumber_Multiply(PyObject *v, PyObject *w) { PyTypeObject *tp = v->ob_type; PySequenceMethods *m; BINOP(v, w, "__mul__", "__rmul__", PyNumber_Multiply); if (tp->tp_as_number != NULL && w->ob_type->tp_as_sequence != NULL && !PyInstance_Check(v)) { /* number*sequence -- swap v and w */ PyObject *tmp = v; v = w; w = tmp; tp = v->ob_type; } if (tp->tp_as_number != NULL) { PyObject *x = NULL; PyObject * (*f)(PyObject *, PyObject *); if (PyInstance_Check(v)) { /* Instances of user-defined classes get their other argument uncoerced, so they may implement sequence*number as well as number*number. */ Py_INCREF(v); Py_INCREF(w); } else if (PyNumber_Coerce(&v, &w) != 0) return NULL; if ((f = v->ob_type->tp_as_number->nb_multiply) != NULL) x = (*f)(v, w); Py_DECREF(v); Py_DECREF(w); if (f != NULL) return x; } m = tp->tp_as_sequence; if (m && m->sq_repeat) { long mul_value; if (PyInt_Check(w)) { mul_value = PyInt_AsLong(w); } else if (PyLong_Check(w)) { mul_value = PyLong_AsLong(w); if (mul_value == -1 && PyErr_Occurred()) return NULL; } else { return type_error( "can't multiply sequence with non-int"); } return (*m->sq_repeat)(v, (int)mul_value); } return type_error("bad operand type(s) for *"); }
PyObject * PyNumber_Power(PyObject *v, PyObject *w, PyObject *z) { PyObject *res; PyObject *v1, *z1, *w2, *z2; PyObject * (*f)(PyObject *, PyObject *, PyObject *); if (z == Py_None) return do_pow(v, w); /* XXX The ternary version doesn't do class instance coercions */ if (PyInstance_Check(v)) return v->ob_type->tp_as_number->nb_power(v, w, z); if (v->ob_type->tp_as_number == NULL || z->ob_type->tp_as_number == NULL || w->ob_type->tp_as_number == NULL) { return type_error("pow(x, y, z) requires numeric arguments"); } if (PyNumber_Coerce(&v, &w) != 0) return NULL; res = NULL; v1 = v; z1 = z; if (PyNumber_Coerce(&v1, &z1) != 0) goto error2; w2 = w; z2 = z1; if (PyNumber_Coerce(&w2, &z2) != 0) goto error1; if ((f = v1->ob_type->tp_as_number->nb_power) != NULL) res = (*f)(v1, w2, z2); else res = type_error( "pow(x, y, z) not defined for these operands"); Py_DECREF(w2); Py_DECREF(z2); error1: Py_DECREF(v1); Py_DECREF(z1); error2: Py_DECREF(v); Py_DECREF(w); return res; }
inline std::pair<CObject, CObject> coerce(const CObject& a, const CObject& b) { PyObject* p1; PyObject* p2; p1 = a.Get(); p2 = b.Get(); if(PyNumber_Coerce(&p1, &p2) == -1) { throw CArithmeticError("PyNumber_Coerce"); } return std::pair<CObject, CObject>(CObject(p1, eTakeOwnership), CObject(p2, eTakeOwnership)); }
PyObject * PyNumber_Divmod(PyObject *v, PyObject *w) { BINOP(v, w, "__divmod__", "__rdivmod__", PyNumber_Divmod); if (v->ob_type->tp_as_number != NULL) { PyObject *x = NULL; PyObject * (*f)(PyObject *, PyObject *); if (PyNumber_Coerce(&v, &w) != 0) return NULL; if ((f = v->ob_type->tp_as_number->nb_divmod) != NULL) x = (*f)(v, w); Py_DECREF(v); Py_DECREF(w); if (f != NULL) return x; } return type_error("bad operand type(s) for divmod()"); }
static PyObject * do_pow(PyObject *v, PyObject *w) { PyObject *res; PyObject * (*f)(PyObject *, PyObject *, PyObject *); BINOP(v, w, "__pow__", "__rpow__", do_pow); if (v->ob_type->tp_as_number == NULL || w->ob_type->tp_as_number == NULL) { PyErr_SetString(PyExc_TypeError, "pow(x, y) requires numeric arguments"); return NULL; } if (PyNumber_Coerce(&v, &w) != 0) return NULL; if ((f = v->ob_type->tp_as_number->nb_power) != NULL) res = (*f)(v, w, Py_None); else res = type_error("pow(x, y) not defined for these operands"); Py_DECREF(v); Py_DECREF(w); return res; }
PyObject * PyNumber_Remainder(PyObject *v, PyObject *w) { if (PyString_Check(v)) return PyString_Format(v, w); else if (PyUnicode_Check(v)) return PyUnicode_Format(v, w); BINOP(v, w, "__mod__", "__rmod__", PyNumber_Remainder); if (v->ob_type->tp_as_number != NULL) { PyObject *x = NULL; PyObject * (*f)(PyObject *, PyObject *); if (PyNumber_Coerce(&v, &w) != 0) return NULL; if ((f = v->ob_type->tp_as_number->nb_remainder) != NULL) x = (*f)(v, w); Py_DECREF(v); Py_DECREF(w); if (f != NULL) return x; } return type_error("bad operand type(s) for %"); }
PyObject * PyNumber_Add(PyObject *v, PyObject *w) { PySequenceMethods *m; BINOP(v, w, "__add__", "__radd__", PyNumber_Add); m = v->ob_type->tp_as_sequence; if (m && m->sq_concat) return (*m->sq_concat)(v, w); else if (v->ob_type->tp_as_number != NULL) { PyObject *x = NULL; PyObject * (*f)(PyObject *, PyObject *); if (PyNumber_Coerce(&v, &w) != 0) return NULL; if ((f = v->ob_type->tp_as_number->nb_add) != NULL) x = (*f)(v, w); Py_DECREF(v); Py_DECREF(w); if (f != NULL) return x; } return type_error("bad operand type(s) for +"); }