📄 abstract.c
字号:
slotz = *NB_TERNOP(v->ob_type->tp_as_number,
op_slot);
if (slotz)
x = slotz(v, w, z);
else
c = -1;
}
else
c = -1;
goto error2;
}
v1 = v;
z1 = z;
c = PyNumber_Coerce(&v1, &z1);
if (c != 0)
goto error2;
w2 = w;
z2 = z1;
c = PyNumber_Coerce(&w2, &z2);
if (c != 0)
goto error1;
if (v1->ob_type->tp_as_number != NULL) {
slotv = *NB_TERNOP(v1->ob_type->tp_as_number,
op_slot);
if (slotv)
x = slotv(v1, w2, z2);
else
c = -1;
}
else
c = -1;
Py_DECREF(w2);
Py_DECREF(z2);
error1:
Py_DECREF(v1);
Py_DECREF(z1);
error2:
Py_DECREF(v);
Py_DECREF(w);
error3:
if (c >= 0)
return x;
}
if (z == Py_None)
PyErr_Format(
PyExc_TypeError,
"unsupported operand type(s) for ** or pow(): "
"'%s' and '%s'",
v->ob_type->tp_name,
w->ob_type->tp_name);
else
PyErr_Format(
PyExc_TypeError,
"unsupported operand type(s) for pow(): "
"'%s', '%s', '%s'",
v->ob_type->tp_name,
w->ob_type->tp_name,
z->ob_type->tp_name);
return NULL;
}
#define BINARY_FUNC(func, op, op_name) \
DL_EXPORT(PyObject *) \
func(PyObject *v, PyObject *w) { \
return binary_op(v, w, NB_SLOT(op), op_name); \
}
BINARY_FUNC(PyNumber_Or, nb_or, "|")
BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
BINARY_FUNC(PyNumber_And, nb_and, "&")
BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
BINARY_FUNC(PyNumber_Multiply, nb_multiply, "*")
BINARY_FUNC(PyNumber_Divide, nb_divide, "/")
BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
DL_EXPORT(PyObject *)
PyNumber_Add(PyObject *v, PyObject *w)
{
PyObject *result = binary_op1(v, w, NB_SLOT(nb_add));
if (result == Py_NotImplemented) {
// XXX:CW32
PySequenceMethods *m = (PySequenceMethods *)v->ob_type->tp_as_sequence;
if (m && m->sq_concat) {
Py_DECREF(result);
result = (*m->sq_concat)(v, w);
}
if (result == Py_NotImplemented) {
Py_DECREF(result);
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;
}
DL_EXPORT(PyObject *)
PyNumber_FloorDivide(PyObject *v, PyObject *w)
{
/* XXX tp_flags test */
return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
}
DL_EXPORT(PyObject *)
PyNumber_TrueDivide(PyObject *v, PyObject *w)
{
/* XXX tp_flags test */
return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
}
DL_EXPORT(PyObject *)
PyNumber_Remainder(PyObject *v, PyObject *w)
{
if (PyString_Check(v))
return PyString_Format(v, w);
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(v))
return PyUnicode_Format(v, w);
#endif
return binary_op(v, w, NB_SLOT(nb_remainder), "%");
}
DL_EXPORT(PyObject *)
PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
{
return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
}
/* Binary in-place operators */
/* The in-place operators are defined to fall back to the 'normal',
non in-place operations, if the in-place methods are not in place.
- If the left hand object has the appropriate struct members, and
they are filled, call the appropriate function and return the
result. No coercion is done on the arguments; the left-hand object
is the one the operation is performed on, and it's up to the
function to deal with the right-hand object.
- Otherwise, in-place modification is not supported. Handle it exactly as
a non in-place operation of the same kind.
*/
#define HASINPLACE(t) PyType_HasFeature((t)->ob_type, Py_TPFLAGS_HAVE_INPLACEOPS)
static PyObject *
binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
const char *op_name)
{
// XXX:CW32
PyNumberMethods *mv = (PyNumberMethods *)v->ob_type->tp_as_number;
if (mv != NULL && HASINPLACE(v)) {
binaryfunc *slot = NB_BINOP(mv, iop_slot);
if (*slot) {
PyObject *x = (*slot)(v, w);
if (x != Py_NotImplemented) {
return x;
}
Py_DECREF(x);
}
}
return binary_op(v, w, op_slot, op_name);
}
#define INPLACE_BINOP(func, iop, op, op_name) \
DL_EXPORT(PyObject *) \
func(PyObject *v, PyObject *w) { \
return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \
}
INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=")
INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=")
INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=")
INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=")
INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=")
INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
INPLACE_BINOP(PyNumber_InPlaceDivide, nb_inplace_divide, nb_divide, "/=")
DL_EXPORT(PyObject *)
PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w)
{
/* XXX tp_flags test */
return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide),
NB_SLOT(nb_floor_divide), "//=");
}
DL_EXPORT(PyObject *)
PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w)
{
/* XXX tp_flags test */
return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide),
NB_SLOT(nb_true_divide), "/=");
}
DL_EXPORT(PyObject *)
PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
{
binaryfunc f = NULL;
if (v->ob_type->tp_as_sequence != NULL) {
if (HASINPLACE(v))
f = v->ob_type->tp_as_sequence->sq_inplace_concat;
if (f == NULL)
f = v->ob_type->tp_as_sequence->sq_concat;
if (f != NULL)
return (*f)(v, w);
}
return binary_iop(v, w, NB_SLOT(nb_inplace_add), NB_SLOT(nb_add), "+=");
}
DL_EXPORT(PyObject *)
PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
{
PyObject * (*g)(PyObject *, int) = NULL;
if (HASINPLACE(v) &&
v->ob_type->tp_as_sequence &&
(g = v->ob_type->tp_as_sequence->sq_inplace_repeat) &&
!(v->ob_type->tp_as_number &&
v->ob_type->tp_as_number->nb_inplace_multiply))
{
long n;
if (PyInt_Check(w)) {
n = PyInt_AsLong(w);
}
else if (PyLong_Check(w)) {
n = PyLong_AsLong(w);
if (n == -1 && PyErr_Occurred())
return NULL;
}
else {
return type_error("can't multiply sequence to non-int");
}
return (*g)(v, (int)n);
}
return binary_iop(v, w, NB_SLOT(nb_inplace_multiply),
NB_SLOT(nb_multiply), "*=");
}
DL_EXPORT(PyObject *)
PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
{
if (PyString_Check(v))
return PyString_Format(v, w);
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(v))
return PyUnicode_Format(v, w);
#endif
else
return binary_iop(v, w, NB_SLOT(nb_inplace_remainder),
NB_SLOT(nb_remainder), "%=");
}
DL_EXPORT(PyObject *)
PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
{
if (HASINPLACE(v) && v->ob_type->tp_as_number &&
v->ob_type->tp_as_number->nb_inplace_power != NULL) {
return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**=");
}
else {
return ternary_op(v, w, z, NB_SLOT(nb_power), "**=");
}
}
/* Unary operators and functions */
DL_EXPORT(PyObject *)
PyNumber_Negative(PyObject *o)
{
PyNumberMethods *m;
if (o == NULL)
return null_error();
// XXX:CW32
m = (PyNumberMethods *)o->ob_type->tp_as_number;
if (m && m->nb_negative)
return (*m->nb_negative)(o);
return type_error("bad operand type for unary -");
}
DL_EXPORT(PyObject *)
PyNumber_Positive(PyObject *o)
{
PyNumberMethods *m;
if (o == NULL)
return null_error();
// XXX:CW32
m = (PyNumberMethods *)o->ob_type->tp_as_number;
if (m && m->nb_positive)
return (*m->nb_positive)(o);
return type_error("bad operand type for unary +");
}
DL_EXPORT(PyObject *)
PyNumber_Invert(PyObject *o)
{
PyNumberMethods *m;
if (o == NULL)
return null_error();
// XXX:CW32
m = (PyNumberMethods *)o->ob_type->tp_as_number;
if (m && m->nb_invert)
return (*m->nb_invert)(o);
return type_error("bad operand type for unary ~");
}
DL_EXPORT(PyObject *)
PyNumber_Absolute(PyObject *o)
{
PyNumberMethods *m;
if (o == NULL)
return null_error();
// XXX:CW32
m = (PyNumberMethods *)o->ob_type->tp_as_number;
if (m && m->nb_absolute)
return m->nb_absolute(o);
return type_error("bad operand type for abs()");
}
/* Add a check for embedded NULL-bytes in the argument. */
static PyObject *
int_from_string(const char *s, int len)
{
char *end;
PyObject *x;
x = PyInt_FromString((char*)s, &end, 10);
if (x == NULL)
return NULL;
if (end != s + len) {
PyErr_SetString(PyExc_ValueError,
"null byte in argument for int()");
Py_DECREF(x);
return NULL;
}
return x;
}
DL_EXPORT(PyObject *)
PyNumber_Int(PyObject *o)
{
PyNumberMethods *m;
const char *buffer;
int buffer_len;
if (o == NULL)
return null_error();
if (PyInt_CheckExact(o)) {
Py_INCREF(o);
return o;
}
if (PyInt_Check(o)) {
PyIntObject *io = (PyIntObject*)o;
return PyInt_FromLong(io->ob_ival);
}
if (PyString_Check(o))
return int_from_string(PyString_AS_STRING(o),
PyString_GET_SIZE(o));
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(o))
return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o),
PyUnicode_GET_SIZE(o),
10);
#endif
// XXX:CW32
m = (PyNumberMethods *)o->ob_type->tp_as_number;
if (m && m->nb_int)
return m->nb_int(o);
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
return int_from_string((char*)buffer, buffer_len);
return type_error("int() argument must be a string or a number");
}
/* Add a check for embedded NULL-bytes in the argument. */
static PyObject *
long_from_string(const char *s, int len)
{
char *end;
PyObject *x;
x = PyLong_FromString((char*)s, &end, 10);
if (x == NULL)
return NULL;
if (end != s + len) {
PyErr_SetString(PyExc_ValueError,
"null byte in argument for long()");
Py_DECREF(x);
return NULL;
}
return x;
}
DL_EXPORT(PyObject *)
PyNumber_Long(PyObject *o)
{
PyNumberMethods *m;
const char *buffer;
int buffer_len;
if (o == NULL)
return null_error();
if (PyLong_CheckExact(o)) {
Py_INCREF(o);
return o;
}
if (PyLong_Check(o))
return _PyLong_Copy((PyLongObject *)o);
if (PyString_Check(o))
/* need to do extra error checking that PyLong_FromString()
* doesn't do. In particular long('9.5') must raise an
* exception, not truncate the float.
*/
return long_from_string(PyString_AS_STRING(o),
PyString_GET_SIZE(o));
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(o))
/* The above check is done in PyLong_FromUnicode(). */
return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o),
PyUnicode_GET_SIZE(o),
10);
#endif
// XXX:CW32
m = (PyNumberMethods *)o->ob_type->tp_as_number;
if (m && m->nb_long)
return m->nb_long(o);
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
return long_from_string(buffer, buffer_len);
return type_error("long() argument must be a string or a number");
}
DL_EXPORT(PyObject *)
PyNumber_Float(PyObject *o)
{
PyNumberMethods *m;
if (o == NULL)
return null_error();
if (PyFloat_CheckExact(o)) {
Py_INCREF(o);
return o;
}
if (PyFloat_Check(o)) {
PyFloatObject *po = (PyFloatObject *)o;
return PyFloat_FromDouble(po->ob_fval);
}
if (!PyString_Check(o)) {
// XXX:CW32
m = (PyNumberMethods *)o->ob_type->tp_as_number;
if (m && m->nb_float)
return m->nb_float(o);
}
return PyFloat_FromString(o, NULL);
}
/* Operations on sequences */
DL_EXPORT(int)
PySequence_Check(PyObject *s)
{
return s != NULL && s->ob_type->tp_as_sequence &&
s->ob_type->tp_as_sequence->sq_item != NULL;
}
DL_EXPORT(int)
PySequence_Size(PyObject *s)
{
PySequenceMethods *m;
if (s == NULL) {
null_error();
return -1;
}
// XXX:CW32
m = (PySequenceMethods *)s->ob_type->tp_as_sequence;
if (m && m->sq_length)
return m->sq_length(s);
type_error("len() of unsized object");
return -1;
}
#undef PySequence_Length
DL_EXPORT(int)
PySequence_Length(PyObject *s)
{
return PySequence_Size(s);
}
#define PySequence_Length PySequence_Size
DL_EXPORT(PyObject *)
PySequence_Concat(PyObject *s, PyObject *o)
{
PySequenceMethods *m;
if (s == NULL || o == NULL)
return null_error();
// XXX:CW32
m = (PySequenceMethods *)s->ob_type->tp_as_sequence;
if (m && m->sq_concat)
return m->sq_concat(s, o);
return type_error("object can't be concatenated");
}
DL_EXPORT(PyObject *)
PySequence_Repeat(PyObject *o, int count)
{
PySequenceMethods *m;
if (o == NULL)
return null_error();
// XXX:CW32
m = (PySequenceMethods *)o->ob_type->tp_as_sequence;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -