boost::python , dispatching in python
Arnaldur Gylfason
arnaldur at decode.is
Wed Jan 9 18:18:38 CET 2002
I've been looking at the python interpreter
(parsetok,pythonrun,tokenizer,ceval,compile,...).
It's a lot of code!
In ceval the operation is selected on the opcode that the tokenizer or
something similar sets.
I didn't see the place where the opcode is selected on the symbol.
However the following in ceval handle, a + b and a[i]:
case BINARY_ADD:
w = POP();
v = POP();
if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
/* INLINE: int + int */
register long a, b, i;
a = PyInt_AS_LONG(v);
b = PyInt_AS_LONG(w);
i = a + b;
if ((i^a) < 0 && (i^b) < 0)
goto slow_add;
x = PyInt_FromLong(i);
}
else {
slow_add:
x = PyNumber_Add(v, w);
}
Py_DECREF(v);
Py_DECREF(w);
PUSH(x);
if (x != NULL) continue;
break;
case BINARY_SUBSCR:
w = POP();
v = POP();
if (PyList_CheckExact(v) && PyInt_CheckExact(w)) {
/* INLINE: list[int] */
long i = PyInt_AsLong(w);
if (i < 0)
i += PyList_GET_SIZE(v);
if (i < 0 ||
i >= PyList_GET_SIZE(v)) {
PyErr_SetString(PyExc_IndexError,
"list index out of range");
x = NULL;
}
else {
x = PyList_GET_ITEM(v, i);
Py_INCREF(x);
}
}
else
x = PyObject_GetItem(v, w);
Py_DECREF(v);
Py_DECREF(w);
PUSH(x);
if (x != NULL) continue;
break;
We can see that BINARY_SUBSCR tries list access first but key access
otherwise (PyObject_GetItem).
sequence access thus should probably have precedence over key access if key
is an integer (when an object has both sequence and mapping interfaces)
BINARY_ADD calls PyNumber_Add.
PyNumber_Add is :
PyObject *
PyNumber_Add(PyObject *v, PyObject *w)
{
PyObject *result = binary_op1(v, w, NB_SLOT(nb_add));
if (result == Py_NotImplemented) {
PySequenceMethods *m = v->ob_type->tp_as_sequence;
Py_DECREF(Py_NotImplemented);
if (m && m->sq_concat) {
result = (*m->sq_concat)(v, w);
}
else {
PyErr_Format(
PyExc_TypeError,
"unsupported operand types for +: '%s' and '%s'",
v->ob_type->tp_name,
w->ob_type->tp_name);
result = NULL;
}
}
return result;
}
It tries nb_add but sequence concat if it fails.
> > Yes. I'll take a look at the python source.
> > In some cases we know how to handle things like o[i]: sequence access
if i
> > is integral, mapping access otherwise.
>
> Not neccessarily:
>
> x = { 1 : 'one', 2 : 'two' }
> x[1]
x is a dictionary so it only supports the mapping interface. No conflict
with the sequence interface in this case.
More information about the Cplusplus-sig
mailing list