Used operators from abstract.h where possible (arithmetic operators,
get/set/del item). This removes a pile of duplication. There's no abstract operator for 'not' but I removed the function call for it anyway -- it's a little faster in-line.
This commit is contained in:
parent
a1ebdbddb3
commit
fc49073cd0
448
Python/ceval.c
448
Python/ceval.c
|
@ -78,28 +78,11 @@ static void call_exc_trace Py_PROTO((PyObject **, PyObject**,
|
|||
PyFrameObject *));
|
||||
static int call_trace Py_PROTO((PyObject **, PyObject **,
|
||||
PyFrameObject *, char *, PyObject *));
|
||||
static PyObject *add Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *sub Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *powerop Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *mul Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *divide Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *mod Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *neg Py_PROTO((PyObject *));
|
||||
static PyObject *pos Py_PROTO((PyObject *));
|
||||
static PyObject *not Py_PROTO((PyObject *));
|
||||
static PyObject *invert Py_PROTO((PyObject *));
|
||||
static PyObject *lshift Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *rshift Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *and Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *xor Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *or Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *call_builtin Py_PROTO((PyObject *, PyObject *, PyObject *));
|
||||
static PyObject *call_function Py_PROTO((PyObject *, PyObject *, PyObject *));
|
||||
static PyObject *apply_subscript Py_PROTO((PyObject *, PyObject *));
|
||||
static PyObject *loop_subscript Py_PROTO((PyObject *, PyObject *));
|
||||
static int slice_index Py_PROTO((PyObject *, int *));
|
||||
static PyObject *apply_slice Py_PROTO((PyObject *, PyObject *, PyObject *));
|
||||
static int assign_subscript Py_PROTO((PyObject *, PyObject *, PyObject *));
|
||||
static int assign_slice Py_PROTO((PyObject *, PyObject *,
|
||||
PyObject *, PyObject *));
|
||||
static int cmp_exception Py_PROTO((PyObject *, PyObject *));
|
||||
|
@ -687,7 +670,7 @@ eval_code2(co, globals, locals,
|
|||
|
||||
case UNARY_POSITIVE:
|
||||
v = POP();
|
||||
x = pos(v);
|
||||
x = PyNumber_Positive(v);
|
||||
Py_DECREF(v);
|
||||
PUSH(x);
|
||||
if (x != NULL) continue;
|
||||
|
@ -695,7 +678,7 @@ eval_code2(co, globals, locals,
|
|||
|
||||
case UNARY_NEGATIVE:
|
||||
v = POP();
|
||||
x = neg(v);
|
||||
x = PyNumber_Negative(v);
|
||||
Py_DECREF(v);
|
||||
PUSH(x);
|
||||
if (x != NULL) continue;
|
||||
|
@ -703,10 +686,19 @@ eval_code2(co, globals, locals,
|
|||
|
||||
case UNARY_NOT:
|
||||
v = POP();
|
||||
x = not(v);
|
||||
err = PyObject_IsTrue(v);
|
||||
Py_DECREF(v);
|
||||
PUSH(x);
|
||||
if (x != NULL) continue;
|
||||
if (err == 0) {
|
||||
Py_INCREF(Py_True);
|
||||
PUSH(Py_True);
|
||||
continue;
|
||||
}
|
||||
else if (err > 0) {
|
||||
Py_INCREF(Py_False);
|
||||
PUSH(Py_False);
|
||||
err = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case UNARY_CONVERT:
|
||||
|
@ -719,7 +711,7 @@ eval_code2(co, globals, locals,
|
|||
|
||||
case UNARY_INVERT:
|
||||
v = POP();
|
||||
x = invert(v);
|
||||
x = PyNumber_Invert(v);
|
||||
Py_DECREF(v);
|
||||
PUSH(x);
|
||||
if (x != NULL) continue;
|
||||
|
@ -728,7 +720,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_POWER:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = powerop(v, w);
|
||||
x = PyNumber_Power(v, w, Py_None);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -738,7 +730,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_MULTIPLY:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = mul(v, w);
|
||||
x = PyNumber_Multiply(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -748,7 +740,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_DIVIDE:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = divide(v, w);
|
||||
x = PyNumber_Divide(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -758,7 +750,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_MODULO:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = mod(v, w);
|
||||
x = PyNumber_Remainder(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -768,7 +760,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_ADD:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = add(v, w);
|
||||
x = PyNumber_Add(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -778,7 +770,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_SUBTRACT:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = sub(v, w);
|
||||
x = PyNumber_Subtract(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -788,7 +780,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_SUBSCR:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = apply_subscript(v, w);
|
||||
x = PyObject_GetItem(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -798,7 +790,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_LSHIFT:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = lshift(v, w);
|
||||
x = PyNumber_Lshift(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -808,7 +800,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_RSHIFT:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = rshift(v, w);
|
||||
x = PyNumber_Rshift(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -818,7 +810,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_AND:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = and(v, w);
|
||||
x = PyNumber_And(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -828,7 +820,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_XOR:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = xor(v, w);
|
||||
x = PyNumber_Xor(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -838,7 +830,7 @@ eval_code2(co, globals, locals,
|
|||
case BINARY_OR:
|
||||
w = POP();
|
||||
v = POP();
|
||||
x = or(v, w);
|
||||
x = PyNumber_Or(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
PUSH(x);
|
||||
|
@ -914,7 +906,7 @@ eval_code2(co, globals, locals,
|
|||
v = POP();
|
||||
u = POP();
|
||||
/* v[w] = u */
|
||||
err = assign_subscript(v, w, u);
|
||||
err = PyObject_SetItem(v, w, u);
|
||||
Py_DECREF(u);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
|
@ -925,7 +917,7 @@ eval_code2(co, globals, locals,
|
|||
w = POP();
|
||||
v = POP();
|
||||
/* del v[w] */
|
||||
err = assign_subscript(v, w, (PyObject *)NULL);
|
||||
err = PyObject_DelItem(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
if (err == 0) continue;
|
||||
|
@ -2112,313 +2104,6 @@ Py_FlushLine()
|
|||
}
|
||||
|
||||
|
||||
/* XXX Many of the following operator implementations could be
|
||||
replaced by calls into the 'abstract' module. */
|
||||
|
||||
#define BINOP(opname, ropname, thisfunc) \
|
||||
if (!PyInstance_Check(v) && !PyInstance_Check(w)) \
|
||||
; \
|
||||
else \
|
||||
return PyInstance_DoBinOp(v, w, opname, ropname, thisfunc)
|
||||
|
||||
|
||||
static PyObject *
|
||||
or(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
BINOP("__or__", "__ror__", or);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x = NULL;
|
||||
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
if ((f = v->ob_type->tp_as_number->nb_or) != NULL)
|
||||
x = (*f)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
if (f != NULL)
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for |");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
xor(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
BINOP("__xor__", "__rxor__", xor);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x = NULL;
|
||||
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
if ((f = v->ob_type->tp_as_number->nb_xor) != NULL)
|
||||
x = (*f)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
if (f != NULL)
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for ^");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
and(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
BINOP("__and__", "__rand__", and);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x = NULL;
|
||||
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
if ((f = v->ob_type->tp_as_number->nb_and) != NULL)
|
||||
x = (*f)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
if (f != NULL)
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for &");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
lshift(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
BINOP("__lshift__", "__rlshift__", lshift);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x = NULL;
|
||||
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
if ((f = v->ob_type->tp_as_number->nb_lshift) != NULL)
|
||||
x = (*f)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
if (f != NULL)
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for <<");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
rshift(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
BINOP("__rshift__", "__rrshift__", rshift);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x = NULL;
|
||||
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
if ((f = v->ob_type->tp_as_number->nb_rshift) != NULL)
|
||||
x = (*f)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
if (f != NULL)
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for >>");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
add(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
BINOP("__add__", "__radd__", add);
|
||||
if (v->ob_type->tp_as_sequence != NULL)
|
||||
return (*v->ob_type->tp_as_sequence->sq_concat)(v, w);
|
||||
else if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x;
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
x = (*v->ob_type->tp_as_number->nb_add)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for +");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sub(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
BINOP("__sub__", "__rsub__", sub);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x;
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
x = (*v->ob_type->tp_as_number->nb_subtract)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for -");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
mul(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
PyTypeObject *tp;
|
||||
tp = v->ob_type;
|
||||
BINOP("__mul__", "__rmul__", mul);
|
||||
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;
|
||||
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;
|
||||
x = (*v->ob_type->tp_as_number->nb_multiply)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
return x;
|
||||
}
|
||||
if (tp->tp_as_sequence != NULL) {
|
||||
if (!PyInt_Check(w)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can't multiply sequence with non-int");
|
||||
return NULL;
|
||||
}
|
||||
return (*tp->tp_as_sequence->sq_repeat)
|
||||
(v, (int)PyInt_AsLong(w));
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for *");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
divide(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
BINOP("__div__", "__rdiv__", divide);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x;
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
x = (*v->ob_type->tp_as_number->nb_divide)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for /");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
mod(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
if (PyString_Check(v)) {
|
||||
return PyString_Format(v, w);
|
||||
}
|
||||
BINOP("__mod__", "__rmod__", mod);
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
PyObject *x;
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
x = (*v->ob_type->tp_as_number->nb_remainder)(v, w);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
return x;
|
||||
}
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for %");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
powerop(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
PyObject *res;
|
||||
BINOP("__pow__", "__rpow__", powerop);
|
||||
if (v->ob_type->tp_as_number == NULL ||
|
||||
w->ob_type->tp_as_number == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"pow() requires numeric arguments");
|
||||
return NULL;
|
||||
}
|
||||
if (PyNumber_Coerce(&v, &w) != 0)
|
||||
return NULL;
|
||||
res = (*v->ob_type->tp_as_number->nb_power)(v, w, Py_None);
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(w);
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
neg(v)
|
||||
PyObject *v;
|
||||
{
|
||||
if (v->ob_type->tp_as_number != NULL)
|
||||
return (*v->ob_type->tp_as_number->nb_negative)(v);
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for unary -");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pos(v)
|
||||
PyObject *v;
|
||||
{
|
||||
if (v->ob_type->tp_as_number != NULL)
|
||||
return (*v->ob_type->tp_as_number->nb_positive)(v);
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for unary +");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
invert(v)
|
||||
PyObject *v;
|
||||
{
|
||||
PyObject * (*f) Py_FPROTO((PyObject *));
|
||||
if (v->ob_type->tp_as_number != NULL &&
|
||||
(f = v->ob_type->tp_as_number->nb_invert) != NULL)
|
||||
return (*f)(v);
|
||||
PyErr_SetString(PyExc_TypeError, "bad operand type(s) for unary ~");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
not(v)
|
||||
PyObject *v;
|
||||
{
|
||||
int outcome = PyObject_IsTrue(v);
|
||||
PyObject *w;
|
||||
if (outcome < 0)
|
||||
return NULL;
|
||||
if (outcome == 0)
|
||||
w = Py_True;
|
||||
else
|
||||
w = Py_False;
|
||||
Py_INCREF(w);
|
||||
return w;
|
||||
}
|
||||
|
||||
|
||||
/* External interface to call any callable object.
|
||||
The arg must be a tuple or NULL. */
|
||||
|
||||
|
@ -2630,41 +2315,6 @@ call_function(func, arg, kw)
|
|||
#define SLICE_ERROR_MSG \
|
||||
"standard sequence type does not support step size other than one"
|
||||
|
||||
static PyObject *
|
||||
apply_subscript(v, w)
|
||||
PyObject *v, *w;
|
||||
{
|
||||
PyTypeObject *tp = v->ob_type;
|
||||
if (tp->tp_as_sequence == NULL && tp->tp_as_mapping == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "unsubscriptable object");
|
||||
return NULL;
|
||||
}
|
||||
if (tp->tp_as_mapping != NULL) {
|
||||
return (*tp->tp_as_mapping->mp_subscript)(v, w);
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
if (!PyInt_Check(w)) {
|
||||
if (PySlice_Check(w)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
SLICE_ERROR_MSG);
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"sequence subscript not int");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
i = PyInt_AsLong(w);
|
||||
if (i < 0) {
|
||||
int len = (*tp->tp_as_sequence->sq_length)(v);
|
||||
if (len < 0)
|
||||
return NULL;
|
||||
i += len;
|
||||
}
|
||||
return (*tp->tp_as_sequence->sq_item)(v, i);
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
loop_subscript(v, w)
|
||||
PyObject *v, *w;
|
||||
|
@ -2719,46 +2369,6 @@ apply_slice(u, v, w) /* return u[v:w] */
|
|||
return PySequence_GetSlice(u, ilow, ihigh);
|
||||
}
|
||||
|
||||
static int
|
||||
assign_subscript(w, key, v) /* w[key] = v */
|
||||
PyObject *w;
|
||||
PyObject *key;
|
||||
PyObject *v;
|
||||
{
|
||||
PyTypeObject *tp = w->ob_type;
|
||||
PySequenceMethods *sq;
|
||||
PyMappingMethods *mp;
|
||||
int (*func1)();
|
||||
int (*func2)();
|
||||
if ((mp = tp->tp_as_mapping) != NULL &&
|
||||
(func1 = mp->mp_ass_subscript) != NULL) {
|
||||
return (*func1)(w, key, v);
|
||||
}
|
||||
else if ((sq = tp->tp_as_sequence) != NULL &&
|
||||
(func2 = sq->sq_ass_item) != NULL) {
|
||||
if (!PyInt_Check(key)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"sequence subscript must be integer (assign or del)");
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
int i = PyInt_AsLong(key);
|
||||
if (i < 0) {
|
||||
int len = (*sq->sq_length)(w);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
i += len;
|
||||
}
|
||||
return (*func2)(w, i, v);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can't assign to this subscripted object");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
assign_slice(u, v, w, x) /* u[v:w] = x */
|
||||
PyObject *u, *v, *w, *x;
|
||||
|
|
Loading…
Reference in New Issue