summaryrefslogtreecommitdiffstats
path: root/Objects/abstract.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1998-05-22 00:47:05 (GMT)
committerGuido van Rossum <guido@python.org>1998-05-22 00:47:05 (GMT)
commitcea1c8ca22b318ce38a9a135c68b812f76b24404 (patch)
treebb07ff65b5cdfd777dd601d1b58a3233e570ee9f /Objects/abstract.c
parentc9132066e73d9ae077f918ffbc5105aa18c22fae (diff)
downloadcpython-cea1c8ca22b318ce38a9a135c68b812f76b24404.zip
cpython-cea1c8ca22b318ce38a9a135c68b812f76b24404.tar.gz
cpython-cea1c8ca22b318ce38a9a135c68b812f76b24404.tar.bz2
Completely reformatted, standardizing indentation as well as
programming style. Recoded many routines to incorporate better error checking, and/or better versions of the same function found elsewhere (e.g. bltinmodule.c or ceval.c). In particular, Py_Number_{Int,Long,Float}() now convert from strings, just like the built-in functions int(), long() and float(). Sequences and mappings are now safe to have NULL function pointers anywhere in their tp_as_sequence or tp_as_mapping fields. (A few places in other files need to be checked in too.) Renamed PySequence_In() to PySequence_Contains().
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r--Objects/abstract.c1482
1 files changed, 900 insertions, 582 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 0835fe3..fa7b6b7 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -30,73 +30,162 @@ PERFORMANCE OF THIS SOFTWARE.
******************************************************************/
/* Abstract Object Interface (many thanks to Jim Fulton) */
-
+
#include "Python.h"
-#define Py_TRY(E) if(!(E)) return NULL
-#define Py_ASSERT(EXP,E,V) if(!(EXP)) return PyErr_SetString(E,V), (void*)NULL
-#define SPAM printf("line %d\n",__LINE__)
+/* Shorthands to return certain errors */
static PyObject *
-Py_ReturnMethodError(name)
- char *name;
+type_error(msg)
+ char *msg;
{
- if(! name) name = "Unknown Error";
- PyErr_SetString(PyExc_AttributeError,name);
- return 0;
+ PyErr_SetString(PyExc_TypeError, msg);
+ return NULL;
}
static PyObject *
-Py_ReturnNullError()
+null_error()
{
- if(! PyErr_Occurred())
- PyErr_SetString(PyExc_SystemError,
- "null argument to internal routine");
- return 0;
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_SystemError,
+ "null argument to internal routine");
+ return NULL;
}
-int
-PyObject_Cmp(o1, o2, result)
- PyObject *o1;
- PyObject *o2;
- int *result;
+/* Copied with modifications from stropmodule.c: atoi, atof, atol */
+
+static PyObject *
+int_from_string(v)
+ PyObject *v;
+{
+ extern long PyOS_strtol Py_PROTO((const char *, char **, int));
+ char *s, *end;
+ long x;
+ char buffer[256]; /* For errors */
+
+ s = PyString_AS_STRING(v);
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ if (s[0] == '\0') {
+ PyErr_SetString(PyExc_ValueError, "empty string for int()");
+ return NULL;
+ }
+ errno = 0;
+ x = PyOS_strtol(s, &end, 10);
+ while (*end && isspace(Py_CHARMASK(*end)))
+ end++;
+ if (*end != '\0') {
+ sprintf(buffer, "invalid literal for int(): %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ return NULL;
+ }
+ else if (end-s != PyString_GET_SIZE(v)) {
+ PyErr_SetString(PyExc_ValueError,
+ "null byte in argument for int()");
+ return NULL;
+ }
+ else if (errno != 0) {
+ sprintf(buffer, "int() literal too large: %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ return NULL;
+ }
+ return PyInt_FromLong(x);
+}
+
+static PyObject *
+long_from_string(v)
+ PyObject *v;
{
- int r;
+ char *s, *end;
+ PyObject *x;
+ char buffer[256]; /* For errors */
+
+ s = PyString_AS_STRING(v);
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ if (s[0] == '\0') {
+ PyErr_SetString(PyExc_ValueError, "empty string for long()");
+ return NULL;
+ }
+ x = PyLong_FromString(s, &end, 10);
+ if (x == NULL)
+ return NULL;
+ while (*end && isspace(Py_CHARMASK(*end)))
+ end++;
+ if (*end != '\0') {
+ sprintf(buffer, "invalid literal for long(): %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ Py_DECREF(x);
+ return NULL;
+ }
+ else if (end-s != PyString_GET_SIZE(v)) {
+ PyErr_SetString(PyExc_ValueError,
+ "null byte in argument for float()");
+ return NULL;
+ }
+ return x;
+}
- if(! o1 || ! o2) return Py_ReturnNullError(),-1;
- r=PyObject_Compare(o1,o2);
- if(PyErr_Occurred()) return -1;
- *result=r;
- return 0;
+static PyObject *
+float_from_string(v)
+ PyObject *v;
+{
+ extern double strtod Py_PROTO((const char *, char **));
+ char *s, *end;
+ double x;
+ char buffer[256]; /* For errors */
+
+ s = PyString_AS_STRING(v);
+ while (*s && isspace(Py_CHARMASK(*s)))
+ s++;
+ if (s[0] == '\0') {
+ PyErr_SetString(PyExc_ValueError, "empty string for float()");
+ return NULL;
+ }
+ errno = 0;
+ PyFPE_START_PROTECT("float_from_string", return 0)
+ x = strtod(s, &end);
+ PyFPE_END_PROTECT(x)
+ while (*end && isspace(Py_CHARMASK(*end)))
+ end++;
+ if (*end != '\0') {
+ sprintf(buffer, "invalid literal for float(): %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ return NULL;
+ }
+ else if (end-s != PyString_GET_SIZE(v)) {
+ PyErr_SetString(PyExc_ValueError,
+ "null byte in argument for float()");
+ return NULL;
+ }
+ else if (errno != 0) {
+ sprintf(buffer, "float() literal too large: %.200s", s);
+ PyErr_SetString(PyExc_ValueError, buffer);
+ return NULL;
+ }
+ return PyFloat_FromDouble(x);
}
-#if 0 /* Already in object.c */
+/* Operations on any object */
+
int
-PyCallable_Check(x)
- PyObject *x;
+PyObject_Cmp(o1, o2, result)
+ PyObject *o1;
+ PyObject *o2;
+ int *result;
{
- if (x == NULL)
- return 0;
- if (x->ob_type->tp_call != NULL ||
- PyFunction_Check(x) ||
- PyMethod_Check(x) ||
- PyCFunction_Check(x) ||
- PyClass_Check(x))
- return 1;
- if (PyInstance_Check(x)) {
- PyObject *call = PyObject_GetAttrString(x, "__call__");
- if (call == NULL) {
- PyErr_Clear();
- return 0;
- }
- /* Could test recursively but don't, for fear of endless
- recursion if some joker sets self.__call__ = self */
- Py_DECREF(call);
- return 1;
+ int r;
+
+ if (o1 == NULL || o2 == NULL) {
+ null_error();
+ return -1;
}
+ r = PyObject_Compare(o1, o2);
+ if (PyErr_Occurred())
+ return -1;
+ *result = r;
return 0;
}
-#endif
PyObject *
PyObject_Type(o)
@@ -104,7 +193,8 @@ PyObject_Type(o)
{
PyObject *v;
- if(! o) return Py_ReturnNullError();
+ if (o == NULL)
+ return null_error();
v = (PyObject *)o->ob_type;
Py_INCREF(v);
return v;
@@ -112,86 +202,100 @@ PyObject_Type(o)
int
PyObject_Length(o)
- PyObject *o;
+ PyObject *o;
{
- PySequenceMethods *m;
+ PySequenceMethods *m;
- if(! o) return Py_ReturnNullError(),-1;
+ if (o == NULL) {
+ null_error();
+ return -1;
+ }
- if((m=o->ob_type->tp_as_sequence) && m->sq_length)
- return m->sq_length(o);
+ m = o->ob_type->tp_as_sequence;
+ if (m && m->sq_length)
+ return m->sq_length(o);
- return PyMapping_Length(o);
+ return PyMapping_Length(o);
}
PyObject *
PyObject_GetItem(o, key)
- PyObject *o;
- PyObject *key;
+ PyObject *o;
+ PyObject *key;
{
- PyMappingMethods *m;
+ PyMappingMethods *m;
- if(! o || ! key) return Py_ReturnNullError();
+ if (o == NULL || key == NULL)
+ return null_error();
- if((m=o->ob_type->tp_as_mapping) && m->mp_subscript)
- return m->mp_subscript(o,key);
-
- if(PyInt_Check(key))
- return PySequence_GetItem(o,PyInt_AsLong(key));
+ m = o->ob_type->tp_as_mapping;
+ if (m && m->mp_subscript)
+ return m->mp_subscript(o, key);
- PyErr_SetString(PyExc_TypeError,"expected integer index");
- return NULL;
+ if (PyInt_Check(key))
+ return PySequence_GetItem(o, PyInt_AsLong(key));
+
+ return type_error("unsubscriptable object");
}
int
PyObject_SetItem(o, key, value)
- PyObject *o;
- PyObject *key;
- PyObject *value;
+ PyObject *o;
+ PyObject *key;
+ PyObject *value;
{
- PyMappingMethods *m;
+ PyMappingMethods *m;
- if(! o || ! key || ! value) return Py_ReturnNullError(),-1;
- if((m=o->ob_type->tp_as_mapping) && m->mp_ass_subscript)
- return m->mp_ass_subscript(o,key,value);
-
- if(PyInt_Check(key))
- return PySequence_SetItem(o,PyInt_AsLong(key),value);
+ if (o == NULL || key == NULL || value == NULL) {
+ null_error();
+ return -1;
+ }
+ m = o->ob_type->tp_as_mapping;
+ if (m && m->mp_ass_subscript)
+ return m->mp_ass_subscript(o, key, value);
+
+ if (PyInt_Check(key))
+ return PySequence_SetItem(o, PyInt_AsLong(key), value);
- PyErr_SetString(PyExc_TypeError,"expected integer index");
- return -1;
+ type_error("object does not support item assignment");
+ return -1;
}
int
PyObject_DelItem(o, key)
- PyObject *o;
- PyObject *key;
+ PyObject *o;
+ PyObject *key;
{
- PyMappingMethods *m;
+ PyMappingMethods *m;
+
+ if (o == NULL || key == NULL) {
+ null_error();
+ return -1;
+ }
+ m = o->ob_type->tp_as_mapping;
+ if (m && m->mp_ass_subscript)
+ return m->mp_ass_subscript(o, key, (PyObject*)NULL);
- if(! o || ! key) return Py_ReturnNullError(),-1;
- if((m=o->ob_type->tp_as_mapping) && m->mp_ass_subscript)
- return m->mp_ass_subscript(o,key,(PyObject*)NULL);
-
- if(PyInt_Check(key))
- return PySequence_SetItem(o,PyInt_AsLong(key),(PyObject*)NULL);
+ if (PyInt_Check(key))
+ return PySequence_DelItem(o, PyInt_AsLong(key));
- PyErr_SetString(PyExc_TypeError,"expected integer index");
- return -1;
+ type_error("object does not support item deletion");
+ return -1;
}
-int
+/* Operations on numbers */
+
+int
PyNumber_Check(o)
- PyObject *o;
+ PyObject *o;
{
- return o && o->ob_type->tp_as_number;
+ return o && o->ob_type->tp_as_number;
}
+/* Binary operators */
-#define BINOP(opname, ropname, thisfunc) \
- if (!PyInstance_Check(v) && !PyInstance_Check(w)) \
- ; \
- else \
+#define BINOP(v, w, opname, ropname, thisfunc) \
+ if (PyInstance_Check(v) || PyInstance_Check(w)) \
return PyInstance_DoBinOp(v, w, opname, ropname, thisfunc)
PyObject *
@@ -200,7 +304,7 @@ PyNumber_Or(v, w)
{
extern int PyNumber_Coerce();
- BINOP("__or__", "__ror__", PyNumber_Or);
+ BINOP(v, w, "__or__", "__ror__", PyNumber_Or);
if (v->ob_type->tp_as_number != NULL) {
PyObject *x = NULL;
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
@@ -213,8 +317,7 @@ PyNumber_Or(v, w)
if (f != NULL)
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for |");
- return NULL;
+ return type_error("bad operand type(s) for |");
}
PyObject *
@@ -223,7 +326,7 @@ PyNumber_Xor(v, w)
{
extern int PyNumber_Coerce();
- BINOP("__xor__", "__rxor__", PyNumber_Xor);
+ BINOP(v, w, "__xor__", "__rxor__", PyNumber_Xor);
if (v->ob_type->tp_as_number != NULL) {
PyObject *x = NULL;
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
@@ -236,15 +339,14 @@ PyNumber_Xor(v, w)
if (f != NULL)
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for ^");
- return NULL;
+ return type_error("bad operand type(s) for ^");
}
PyObject *
PyNumber_And(v, w)
PyObject *v, *w;
{
- BINOP("__and__", "__rand__", PyNumber_And);
+ BINOP(v, w, "__and__", "__rand__", PyNumber_And);
if (v->ob_type->tp_as_number != NULL) {
PyObject *x = NULL;
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
@@ -257,15 +359,14 @@ PyNumber_And(v, w)
if (f != NULL)
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for &");
- return NULL;
+ return type_error("bad operand type(s) for &");
}
PyObject *
PyNumber_Lshift(v, w)
PyObject *v, *w;
{
- BINOP("__lshift__", "__rlshift__", PyNumber_Lshift);
+ BINOP(v, w, "__lshift__", "__rlshift__", PyNumber_Lshift);
if (v->ob_type->tp_as_number != NULL) {
PyObject *x = NULL;
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
@@ -278,15 +379,14 @@ PyNumber_Lshift(v, w)
if (f != NULL)
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for <<");
- return NULL;
+ return type_error("bad operand type(s) for <<");
}
PyObject *
PyNumber_Rshift(v, w)
PyObject *v, *w;
{
- BINOP("__rshift__", "__rrshift__", PyNumber_Rshift);
+ BINOP(v, w, "__rshift__", "__rrshift__", PyNumber_Rshift);
if (v->ob_type->tp_as_number != NULL) {
PyObject *x = NULL;
PyObject * (*f) Py_FPROTO((PyObject *, PyObject *));
@@ -299,17 +399,19 @@ PyNumber_Rshift(v, w)
if (f != NULL)
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for >>");
- return NULL;
+ return type_error("bad operand type(s) for >>");
}
PyObject *
PyNumber_Add(v, w)
PyObject *v, *w;
{
- BINOP("__add__", "__radd__", PyNumber_Add);
- if (v->ob_type->tp_as_sequence != NULL)
- return (*v->ob_type->tp_as_sequence->sq_concat)(v, 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;
if (PyNumber_Coerce(&v, &w) != 0)
@@ -319,15 +421,14 @@ PyNumber_Add(v, w)
Py_DECREF(w);
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for +");
- return NULL;
+ return type_error("bad operand type(s) for +");
}
PyObject *
PyNumber_Subtract(v, w)
PyObject *v, *w;
{
- BINOP("__sub__", "__rsub__", PyNumber_Subtract);
+ BINOP(v, w, "__sub__", "__rsub__", PyNumber_Subtract);
if (v->ob_type->tp_as_number != NULL) {
PyObject *x;
if (PyNumber_Coerce(&v, &w) != 0)
@@ -337,17 +438,17 @@ PyNumber_Subtract(v, w)
Py_DECREF(w);
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for -");
- return NULL;
+ return type_error("bad operand type(s) for -");
}
PyObject *
PyNumber_Multiply(v, w)
PyObject *v, *w;
{
- PyTypeObject *tp;
- tp = v->ob_type;
- BINOP("__mul__", "__rmul__", PyNumber_Multiply);
+ 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)) {
@@ -374,24 +475,21 @@ PyNumber_Multiply(v, w)
Py_DECREF(w);
return x;
}
- if (tp->tp_as_sequence != NULL) {
- if (!PyInt_Check(w)) {
- PyErr_SetString(PyExc_TypeError,
+ m = tp->tp_as_sequence;
+ if (m && m->sq_repeat) {
+ if (!PyInt_Check(w))
+ return type_error(
"can't multiply sequence with non-int");
- return NULL;
- }
- return (*tp->tp_as_sequence->sq_repeat)
- (v, (int)PyInt_AsLong(w));
+ return (*m->sq_repeat)(v, (int)PyInt_AsLong(w));
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for *");
- return NULL;
+ return type_error("bad operand type(s) for *");
}
PyObject *
PyNumber_Divide(v, w)
PyObject *v, *w;
{
- BINOP("__div__", "__rdiv__", PyNumber_Divide);
+ BINOP(v, w, "__div__", "__rdiv__", PyNumber_Divide);
if (v->ob_type->tp_as_number != NULL) {
PyObject *x;
if (PyNumber_Coerce(&v, &w) != 0)
@@ -401,8 +499,7 @@ PyNumber_Divide(v, w)
Py_DECREF(w);
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for /");
- return NULL;
+ return type_error("bad operand type(s) for /");
}
PyObject *
@@ -412,7 +509,7 @@ PyNumber_Remainder(v, w)
if (PyString_Check(v)) {
return PyString_Format(v, w);
}
- BINOP("__mod__", "__rmod__", PyNumber_Remainder);
+ BINOP(v, w, "__mod__", "__rmod__", PyNumber_Remainder);
if (v->ob_type->tp_as_number != NULL) {
PyObject *x;
if (PyNumber_Coerce(&v, &w) != 0)
@@ -422,8 +519,7 @@ PyNumber_Remainder(v, w)
Py_DECREF(w);
return x;
}
- PyErr_SetString(PyExc_TypeError, "bad operand type(s) for %");
- return NULL;
+ return type_error("bad operand type(s) for %");
}
PyObject *
@@ -432,23 +528,20 @@ PyNumber_Divmod(v, w)
{
PyObject *res;
- if (PyInstance_Check(v) || PyInstance_Check(w))
- return PyInstance_DoBinOp(v, w, "__divmod__", "__rdivmod__",
- PyNumber_Divmod);
- if (v->ob_type->tp_as_number == NULL ||
- w->ob_type->tp_as_number == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "divmod() requires numeric or class instance arguments");
- return NULL;
+ BINOP(v, w, "__divmod__", "__rdivmod__", PyNumber_Divmod);
+ 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_divmod)(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ return x;
}
- if (PyNumber_Coerce(&v, &w) != 0)
- return NULL;
- res = (*v->ob_type->tp_as_number->nb_divmod)(v, w);
- Py_DECREF(v);
- Py_DECREF(w);
- return res;
+ return type_error("bad operand type(s) for divmod()");
}
+/* Power (binary or ternary) */
static PyObject *
do_pow(v, w)
@@ -463,8 +556,11 @@ do_pow(v, w)
"pow() requires numeric arguments");
return NULL;
}
- if (PyFloat_Check(v) && PyFloat_Check(w) &&
- PyFloat_AsDouble(v) < 0.0) {
+ if (
+#ifndef WITHOUT_COMPLEX
+ !PyComplex_Check(v) &&
+#endif
+ PyFloat_Check(w) && PyFloat_AsDouble(v) < 0.0) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_ValueError,
"negative number to float power");
@@ -479,7 +575,7 @@ do_pow(v, w)
}
PyObject *
-PyNumber_Power(v,w,z)
+PyNumber_Power(v, w, z)
PyObject *v, *w, *z;
{
PyObject *res;
@@ -493,8 +589,7 @@ PyNumber_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) {
- PyErr_SetString(PyExc_TypeError, "pow() requires numeric arguments");
- return NULL;
+ return type_error("pow() requires numeric arguments");
}
if (PyNumber_Coerce(&v, &w) != 0)
return NULL;
@@ -510,519 +605,771 @@ PyNumber_Power(v,w,z)
res = (*v1->ob_type->tp_as_number->nb_power)(v1, w2, z2);
Py_DECREF(w2);
Py_DECREF(z2);
- error1:
+ error1:
Py_DECREF(v1);
Py_DECREF(z1);
- error2:
+ error2:
Py_DECREF(v);
Py_DECREF(w);
return res;
}
+/* Unary operators and functions */
PyObject *
-PyNumber_Negative(v)
- PyObject *v;
+PyNumber_Negative(o)
+ PyObject *o;
{
- 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;
+ PyNumberMethods *m;
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_negative)
+ return (*m->nb_negative)(o);
+
+ return type_error("bad operand type for unary -");
}
PyObject *
-PyNumber_Positive(v)
- PyObject *v;
+PyNumber_Positive(o)
+ PyObject *o;
{
- 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;
+ PyNumberMethods *m;
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_positive)
+ return (*m->nb_positive)(o);
+
+ return type_error("bad operand type for unary +");
}
PyObject *
-PyNumber_Invert(v)
- PyObject *v;
+PyNumber_Invert(o)
+ PyObject *o;
{
- 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;
+ PyNumberMethods *m;
+
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_invert)
+ return (*m->nb_invert)(o);
+
+ return type_error("bad operand type for unary ~");
}
PyObject *
PyNumber_Absolute(o)
- PyObject *o;
+ PyObject *o;
{
- PyNumberMethods *m;
+ PyNumberMethods *m;
- if(! o) return Py_ReturnNullError();
- if((m=o->ob_type->tp_as_number) && m->nb_absolute)
- return m->nb_absolute(o);
+ if (o == NULL)
+ return null_error();
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_absolute)
+ return m->nb_absolute(o);
- return Py_ReturnMethodError("__abs__");
+ return type_error("bad operand type for abs()");
}
PyObject *
PyNumber_Int(o)
- PyObject *o;
+ PyObject *o;
{
- PyNumberMethods *m;
+ PyNumberMethods *m;
- if(! o) return Py_ReturnNullError();
- if((m=o->ob_type->tp_as_number) && m->nb_int)
- return m->nb_int(o);
+ if (o == NULL)
+ return null_error();
+ if (PyString_Check(o))
+ return int_from_string(o);
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_int)
+ return m->nb_int(o);
- return Py_ReturnMethodError("__int__");
+ return type_error("object can't be converted to int");
}
PyObject *
PyNumber_Long(o)
- PyObject *o;
+ PyObject *o;
{
- PyNumberMethods *m;
+ PyNumberMethods *m;
- if(! o) return Py_ReturnNullError();
- if((m=o->ob_type->tp_as_number) && m->nb_long)
- return m->nb_long(o);
+ if (o == NULL)
+ return null_error();
+ if (PyString_Check(o))
+ return long_from_string(o);
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_long)
+ return m->nb_long(o);
- return Py_ReturnMethodError("__long__");
+ return type_error("object can't be converted to long");
}
PyObject *
PyNumber_Float(o)
- PyObject *o;
+ PyObject *o;
{
- PyNumberMethods *m;
+ PyNumberMethods *m;
- if(! o) return Py_ReturnNullError();
- if((m=o->ob_type->tp_as_number) && m->nb_float)
- return m->nb_float(o);
+ if (o == NULL)
+ return null_error();
+ if (PyString_Check(o))
+ return float_from_string(o);
+ m = o->ob_type->tp_as_number;
+ if (m && m->nb_float)
+ return m->nb_float(o);
- return Py_ReturnMethodError("__float__");
+ return type_error("object can't be converted to float");
}
+/* Operations on sequences */
-int
-PySequence_Check(o)
- PyObject *o;
+int
+PySequence_Check(s)
+ PyObject *s;
{
- return o && o->ob_type->tp_as_sequence;
+ return s != NULL && s->ob_type->tp_as_sequence;
}
-int
+int
PySequence_Length(s)
- PyObject *s;
+ PyObject *s;
{
- PySequenceMethods *m;
+ PySequenceMethods *m;
- if(! s) return Py_ReturnNullError(),-1;
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
- if((m=s->ob_type->tp_as_sequence) && m->sq_length)
- return m->sq_length(s);
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_length)
+ return m->sq_length(s);
- Py_ReturnMethodError("__len__");
- return -1;
+ type_error("len() of unsized object");
+ return -1;
}
PyObject *
PySequence_Concat(s, o)
- PyObject *s;
- PyObject *o;
+ PyObject *s;
+ PyObject *o;
{
- PySequenceMethods *m;
+ PySequenceMethods *m;
+
+ if (s == NULL || o == NULL)
+ return null_error();
- if(! s || ! o) return Py_ReturnNullError();
-
- if((m=s->ob_type->tp_as_sequence) && m->sq_concat)
- return m->sq_concat(s,o);
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_concat)
+ return m->sq_concat(s, o);
- return Py_ReturnMethodError("__concat__");
+ return type_error("object can't be concatenated");
}
PyObject *
PySequence_Repeat(o, count)
- PyObject *o;
- int count;
+ PyObject *o;
+ int count;
{
- PySequenceMethods *m;
+ PySequenceMethods *m;
- if(! o) return Py_ReturnNullError();
-
- if((m=o->ob_type->tp_as_sequence) && m->sq_repeat)
- return m->sq_repeat(o,count);
+ if (o == NULL)
+ return null_error();
- return Py_ReturnMethodError("__repeat__");
+ m = o->ob_type->tp_as_sequence;
+ if (m && m->sq_repeat)
+ return m->sq_repeat(o, count);
+
+ return type_error("object can't be repeated");
}
PyObject *
PySequence_GetItem(s, i)
- PyObject *s;
- int i;
+ PyObject *s;
+ int i;
{
- PySequenceMethods *m;
- int l;
-
- if(! s) return Py_ReturnNullError();
-
- if(! ((m=s->ob_type->tp_as_sequence) && m->sq_item))
- return Py_ReturnMethodError("__getitem__");
+ PySequenceMethods *m;
+
+ if (s == NULL)
+ return null_error();
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_item) {
+ if (i < 0) {
+ if (m->sq_length) {
+ int l = (*m->sq_length)(s);
+ if (l < 0)
+ return NULL;
+ i += l;
+ }
+ }
+ return m->sq_item(s, i);
+ }
- if(i < 0)
- {
- if(! m->sq_length || 0 > (l=m->sq_length(s))) return NULL;
- i += l;
- }
-
- return m->sq_item(s,i);
+ return type_error("unindexable object");
}
PyObject *
PySequence_GetSlice(s, i1, i2)
- PyObject *s;
- int i1;
- int i2;
+ PyObject *s;
+ int i1;
+ int i2;
{
- PySequenceMethods *m;
- int l;
-
- if(! s) return Py_ReturnNullError();
-
- if(! ((m=s->ob_type->tp_as_sequence) && m->sq_slice))
- return Py_ReturnMethodError("__getslice__");
-
- if(i1 < 0 || i2 < 0)
- {
-
- if(! m->sq_length || 0 > (l=m->sq_length(s))) return NULL;
+ PySequenceMethods *m;
+
+ if (!s) return null_error();
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_slice) {
+ if (i1 < 0 || i2 < 0) {
+ if (m->sq_length) {
+ int l = (*m->sq_length)(s);
+ if (l < 0)
+ return NULL;
+ if (i1 < 0)
+ i1 += l;
+ if (i2 < 0)
+ i2 += l;
+ }
+ }
+ return m->sq_slice(s, i1, i2);
+ }
- if(i1 < 0) i1 += l;
- if(i2 < 0) i2 += l;
- }
-
- return m->sq_slice(s,i1,i2);
+ return type_error("unsliceable object");
}
int
PySequence_SetItem(s, i, o)
- PyObject *s;
- int i;
- PyObject *o;
+ PyObject *s;
+ int i;
+ PyObject *o;
{
- PySequenceMethods *m;
- int l;
- if(! s) return Py_ReturnNullError(),-1;
-
- if(! ((m=s->ob_type->tp_as_sequence) && m->sq_length && m->sq_ass_item))
- return Py_ReturnMethodError("__setitem__"),-1;
-
- if(i < 0)
- {
- if(0 > (l=m->sq_length(s))) return -1;
- i += l;
- }
-
- return m->sq_ass_item(s,i,o);
+ PySequenceMethods *m;
+
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_ass_item) {
+ if (i < 0) {
+ if (m->sq_length) {
+ int l = (*m->sq_length)(s);
+ if (l < 0)
+ return NULL;
+ i += l;
+ }
+ }
+ return m->sq_ass_item(s, i, o);
+ }
+
+ type_error("object doesn't support item assignment");
+ return -1;
}
int
PySequence_DelItem(s, i)
- PyObject *s;
- int i;
+ PyObject *s;
+ int i;
{
- PySequenceMethods *m;
- int l;
- if(! s) return Py_ReturnNullError(),-1;
-
- if(! ((m=s->ob_type->tp_as_sequence) && m->sq_length && m->sq_ass_item))
- return Py_ReturnMethodError("__delitem__"),-1;
-
- if(i < 0)
- {
- if(0 > (l=m->sq_length(s))) return -1;
- i += l;
- }
-
- return m->sq_ass_item(s,i,(PyObject*)NULL);
+ PySequenceMethods *m;
+
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
+
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_ass_item) {
+ if (i < 0) {
+ if (m->sq_length) {
+ int l = (*m->sq_length)(s);
+ if (l < 0)
+ return NULL;
+ i += l;
+ }
+ }
+ return m->sq_ass_item(s, i, (PyObject *)NULL);
+ }
+
+ type_error("object doesn't support item deletion");
+ return -1;
}
-int
+int
PySequence_SetSlice(s, i1, i2, o)
- PyObject *s;
- int i1;
- int i2;
- PyObject *o;
+ PyObject *s;
+ int i1;
+ int i2;
+ PyObject *o;
{
- PySequenceMethods *m;
- int l;
-
- if(! s) return Py_ReturnNullError(),-1;
+ PySequenceMethods *m;
- if(! ((m=s->ob_type->tp_as_sequence) && m->sq_length && m->sq_ass_slice))
- return Py_ReturnMethodError("__setslice__"),-1;
-
- if(0 > (l=m->sq_length(s))) return -1;
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
- if(i1 < 0) i1 += l;
- if(i2 < 0) i2 += l;
-
- return m->sq_ass_slice(s,i1,i2,o);
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_ass_slice) {
+ if (i1 < 0 || i2 < 0) {
+ if (m->sq_length) {
+ int l = (*m->sq_length)(s);
+ if (l < 0)
+ return NULL;
+ if (i1 < 0)
+ i1 += l;
+ if (i2 < 0)
+ i2 += l;
+ }
+ }
+ return m->sq_ass_slice(s, i1, i2, o);
+ }
+ type_error("object doesn't support slice assignment");
+ return -1;
}
-int
+int
PySequence_DelSlice(s, i1, i2)
- PyObject *s;
- int i1;
- int i2;
+ PyObject *s;
+ int i1;
+ int i2;
{
- PySequenceMethods *m;
- int l;
-
- if(! s) return Py_ReturnNullError(),-1;
+ PySequenceMethods *m;
- if(! ((m=s->ob_type->tp_as_sequence) && m->sq_length && m->sq_ass_slice))
- return Py_ReturnMethodError("__delslice__"),-1;
-
- if(0 > (l=m->sq_length(s))) return -1;
+ if (s == NULL) {
+ null_error();
+ return -1;
+ }
- if(i1 < 0) i1 += l;
- if(i2 < 0) i2 += l;
-
- return m->sq_ass_slice(s,i1,i2,(PyObject*)NULL);
+ m = s->ob_type->tp_as_sequence;
+ if (m && m->sq_ass_slice) {
+ if (i1 < 0 || i2 < 0) {
+ if (m->sq_length) {
+ int l = (*m->sq_length)(s);
+ if (l < 0)
+ return NULL;
+ if (i1 < 0)
+ i1 += l;
+ if (i2 < 0)
+ i2 += l;
+ }
+ }
+ return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL);
+ }
+ type_error("object doesn't support slice deletion");
+ return -1;
}
PyObject *
-PySequence_Tuple(s)
- PyObject *s;
+PySequence_Tuple(v)
+ PyObject *v;
{
- int l, i;
- PyObject *t, *item;
+ PySequenceMethods *m;
- if(! s) return Py_ReturnNullError();
+ if (v == NULL)
+ return null_error();
- Py_TRY((l=PySequence_Length(s)) != -1);
- Py_TRY(t=PyTuple_New(l));
+ if (PyTuple_Check(v)) {
+ Py_INCREF(v);
+ return v;
+ }
+
+ if (PyList_Check(v))
+ return PyList_AsTuple(v);
+
+ if (PyString_Check(v)) {
+ int n = PyString_Size(v);
+ PyObject *t = PyTuple_New(n);
+ if (t != NULL) {
+ int i;
+ char *p = PyString_AsString(v);
+ for (i = 0; i < n; i++) {
+ PyObject *item =
+ PyString_FromStringAndSize(p+i, 1);
+ if (item == NULL) {
+ Py_DECREF(t);
+ t = NULL;
+ break;
+ }
+ PyTuple_SetItem(t, i, item);
+ }
+ }
+ return t;
+ }
- for(i=0; i < l; i++)
- {
- if(!(item=PySequence_GetItem(s,i)) ||
- PyTuple_SetItem(t,i,item) == -1)
- {
- Py_DECREF(t);
- return NULL;
+ /* Generic sequence object */
+ m = v->ob_type->tp_as_sequence;
+ if (m && m->sq_item) {
+ /* XXX Should support indefinite-length sequences */
+ int i;
+ PyObject *t;
+ int n = PySequence_Length(v);
+ if (n < 0)
+ return NULL;
+ t = PyTuple_New(n);
+ if (t == NULL)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ PyObject *item = (*m->sq_item)(v, i);
+ if (item == NULL) {
+ Py_DECREF(t);
+ t = NULL;
+ break;
+ }
+ PyTuple_SetItem(t, i, item);
+ }
+ return t;
}
- }
- return t;
+
+ /* None of the above */
+ return type_error("tuple() argument must be a sequence");
}
PyObject *
-PySequence_List(s)
- PyObject *s;
+PySequence_List(v)
+ PyObject *v;
{
- int l, i;
- PyObject *t, *item;
-
- if(! s) return Py_ReturnNullError();
+ PySequenceMethods *m;
+
+ m = v->ob_type->tp_as_sequence;
+ if (m && m->sq_item) {
+ /* XXX Should support indefinite-length sequences */
+ int i;
+ PyObject *l;
+ int n = PySequence_Length(v);
+ if (n < 0)
+ return NULL;
+ l = PyList_New(n);
+ if (l == NULL)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ PyObject *item = (*m->sq_item)(v, i);
+ if (item == NULL) {
+ Py_DECREF(l);
+ l = NULL;
+ break;
+ }
+ PyList_SetItem(l, i, item);
+ }
+ return l;
+ }
+ return type_error("list() argument must be a sequence");
+}
- Py_TRY((l=PySequence_Length(s)) != -1);
- Py_TRY(t=PyList_New(l));
+int
+PySequence_Count(s, o)
+ PyObject *s;
+ PyObject *o;
+{
+ int l, i, n, cmp, err;
+ PyObject *item;
- for(i=0; i < l; i++)
- {
- if(!(item=PySequence_GetItem(s,i)) ||
- PyList_SetItem(t,i,item) == -1)
- {
- Py_DECREF(t);
- return NULL;
+ if (s == NULL || o == NULL) {
+ null_error();
+ return -1;
+ }
+
+ l = PySequence_Length(s);
+ if (l < 0)
+ return -1;
+
+ n = 0;
+ for (i = 0; i < l; i++) {
+ item = PySequence_GetItem(s, i);
+ if (item == NULL)
+ return -1;
+ err = PyObject_Cmp(item, o, &cmp);
+ Py_DECREF(item);
+ if (err < 0)
+ return err;
+ if (cmp == 0)
+ n++;
}
- }
- return t;
+ return n;
}
-int
-PySequence_Count(s, o)
- PyObject *s;
- PyObject *o;
+int
+PySequence_Contains(w, v) /* v in w */
+ PyObject *w;
+ PyObject *v;
{
- int l, i, n=0, not_equal, err;
- PyObject *item;
-
- if(! s || ! o) return Py_ReturnNullError(), -1;
- if((l=PySequence_Length(s)) == -1) return -1;
-
- for(i=0; i < l; i++)
- {
- if((item=PySequence_GetItem(s,i)) == NULL) return -1;
- err=PyObject_Cmp(item,o,&not_equal) == -1;
- Py_DECREF(item);
- if(err) return -1;
- n += ! not_equal;
- }
- return n;
+ int i, cmp;
+ PyObject *x;
+ PySequenceMethods *sq;
+
+ /* Special case for char in string */
+ if (PyString_Check(w)) {
+ register char *s, *end;
+ register char c;
+ if (!PyString_Check(v) || PyString_Size(v) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "string member test needs char left operand");
+ return -1;
+ }
+ c = PyString_AsString(v)[0];
+ s = PyString_AsString(w);
+ end = s + PyString_Size(w);
+ while (s < end) {
+ if (c == *s++)
+ return 1;
+ }
+ return 0;
+ }
+
+ sq = w->ob_type->tp_as_sequence;
+ if (sq == NULL || sq->sq_item == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "'in' or 'not in' needs sequence right argument");
+ return -1;
+ }
+
+ for (i = 0; ; i++) {
+ x = (*sq->sq_item)(w, i);
+ if (x == NULL) {
+ if (PyErr_Occurred() == PyExc_IndexError) {
+ PyErr_Clear();
+ break;
+ }
+ return -1;
+ }
+ cmp = PyObject_Compare(v, x);
+ Py_XDECREF(x);
+ if (cmp == 0)
+ return 1;
+ if (PyErr_Occurred())
+ return -1;
+ }
+
+ return 0;
}
-int
-PySequence_In(s, o)
- PyObject *s;
- PyObject *o;
+/* Backwards compatibility */
+#undef PySequence_In
+int
+PySequence_In(w, v)
+ PyObject *w;
+ PyObject *v;
{
- int l, i, not_equal, err;
- PyObject *item;
-
- if(! o || ! s) return Py_ReturnNullError(), -1;
- if((l=PySequence_Length(s)) == -1) return -1;
-
- for(i=0; i < l; i++)
- {
- if((item=PySequence_GetItem(s,i)) == NULL) return -1;
- err=PyObject_Cmp(item,o,&not_equal) == -1;
- Py_DECREF(item);
- if(err) return -1;
- if(! not_equal) return 1;
- }
- return 0;
+ return PySequence_Contains(w, v);
}
-int
+int
PySequence_Index(s, o)
- PyObject *s;
- PyObject *o;
+ PyObject *s;
+ PyObject *o;
{
- int l, i, not_equal, err;
- PyObject *item;
-
- if(! s || ! o) return Py_ReturnNullError(), -1;
- if((l=PySequence_Length(s)) == -1) return -1;
-
- for(i=0; i < l; i++)
- {
- if((item=PySequence_GetItem(s,i)) == NULL) return -1;
- err=PyObject_Cmp(item,o,&not_equal) == -1;
- Py_DECREF(item);
- if(err) return -1;
- if(! not_equal) return i;
- }
- PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list");
- return -1;
+ int l, i, cmp, err;
+ PyObject *item;
+
+ if (s == NULL || o == NULL) {
+ null_error();
+ return -1;
+ }
+
+ l = PySequence_Length(s);
+ if (l < 0)
+ return -1;
+
+ for (i = 0; i < l; i++) {
+ item = PySequence_GetItem(s, i);
+ if (item == NULL)
+ return -1;
+ err = PyObject_Cmp(item, o, &cmp);
+ Py_DECREF(item);
+ if (err < 0)
+ return err;
+ if (cmp == 0)
+ return i;
+ }
+
+ PyErr_SetString(PyExc_ValueError, "sequence.index(x): x not in list");
+ return -1;
}
-int
+/* Operations on mappings */
+
+int
PyMapping_Check(o)
- PyObject *o;
+ PyObject *o;
{
- return o && o->ob_type->tp_as_mapping;
+ return o && o->ob_type->tp_as_mapping;
}
-int
-PyMapping_Length(s)
- PyObject *s;
+int
+PyMapping_Length(o)
+ PyObject *o;
{
- PyMappingMethods *m;
+ PyMappingMethods *m;
- if(! s) return Py_ReturnNullError(),-1;
+ if (o == NULL) {
+ null_error();
+ return -1;
+ }
- if((m=s->ob_type->tp_as_mapping) && m->mp_length)
- return m->mp_length(s);
+ m = o->ob_type->tp_as_mapping;
+ if (m && m->mp_length)
+ return m->mp_length(o);
- Py_ReturnMethodError("__len__");
- return -1;
+ type_error("len() of unsized object");
+ return -1;
}
-int
+PyObject *
+PyMapping_GetItemString(o, key)
+ PyObject *o;
+ char *key;
+{
+ PyObject *okey, *r;
+
+ if (key == NULL)
+ return null_error();
+
+ okey = PyString_FromString(key);
+ if (okey == NULL)
+ return NULL;
+ r = PyObject_GetItem(o, okey);
+ Py_DECREF(okey);
+ return r;
+}
+
+int
+PyMapping_SetItemString(o, key, value)
+ PyObject *o;
+ char *key;
+ PyObject *value;
+{
+ PyObject *okey;
+ int r;
+
+ if (key == NULL) {
+ null_error();
+ return -1;
+ }
+
+ okey = PyString_FromString(key);
+ if (okey == NULL)
+ return NULL;
+ r = PyObject_SetItem(o, okey, value);
+ Py_DECREF(okey);
+ return r;
+}
+
+int
PyMapping_HasKeyString(o, key)
- PyObject *o;
- char *key;
+ PyObject *o;
+ char *key;
{
- PyObject *v;
-
- v=PyMapping_GetItemString(o,key);
- if(v) {
- Py_DECREF(v);
- return 1;
- }
- PyErr_Clear();
- return 0;
+ PyObject *v;
+
+ v = PyMapping_GetItemString(o, key);
+ if (v) {
+ Py_DECREF(v);
+ return 1;
+ }
+ PyErr_Clear();
+ return 0;
}
-int
+int
PyMapping_HasKey(o, key)
- PyObject *o;
- PyObject *key;
+ PyObject *o;
+ PyObject *key;
{
- PyObject *v;
-
- v=PyObject_GetItem(o,key);
- if(v) {
- Py_DECREF(v);
- return 1;
- }
- PyErr_Clear();
- return 0;
+ PyObject *v;
+
+ v = PyObject_GetItem(o, key);
+ if (v) {
+ Py_DECREF(v);
+ return 1;
+ }
+ PyErr_Clear();
+ return 0;
}
+/* Operations on callable objects */
+
+/* XXX PyCallable_Check() is in object.c */
+
PyObject *
PyObject_CallObject(o, a)
- PyObject *o, *a;
+ PyObject *o, *a;
{
- PyObject *r;
+ PyObject *r;
+ PyObject *args = a;
- if(a) return PyEval_CallObject(o,a);
+ if (args == NULL) {
+ args = PyTuple_New(0);
+ if (args == NULL)
+ return NULL;
+ }
+
+ r = PyEval_CallObject(o, args);
- if(! (a=PyTuple_New(0)))
- return NULL;
- r=PyEval_CallObject(o,a);
- Py_DECREF(a);
- return r;
-}
+ if (args != a)
+ Py_DECREF(args);
+
+ return r;
+}
PyObject *
#ifdef HAVE_STDARG_PROTOTYPES
/* VARARGS 2 */
-PyObject_CallFunction(PyObject *PyCallable_Check, char *format, ...)
+PyObject_CallFunction(PyObject *callable, char *format, ...)
#else
/* VARARGS */
-PyObject_CallFunction(va_alist) va_dcl
+ PyObject_CallFunction(va_alist) va_dcl
#endif
{
- va_list va;
- PyObject *args, *retval;
+ va_list va;
+ PyObject *args, *retval;
#ifdef HAVE_STDARG_PROTOTYPES
- va_start(va, format);
+ va_start(va, format);
#else
- PyObject *PyCallable_Check;
- char *format;
- va_start(va);
- PyCallable_Check = va_arg(va, PyObject *);
- format = va_arg(va, char *);
+ PyObject *callable;
+ char *format;
+ va_start(va);
+ callable = va_arg(va, PyObject *);
+ format = va_arg(va, char *);
#endif
- if( ! PyCallable_Check)
- {
- va_end(va);
- return Py_ReturnNullError();
- }
-
- if(format)
- args = Py_VaBuildValue(format, va);
- else
- args = PyTuple_New(0);
-
- va_end(va);
- if(! args) return NULL;
-
- if(! PyTuple_Check(args))
- {
- PyObject *a;
-
- Py_TRY(a=PyTuple_New(1));
- Py_TRY(PyTuple_SetItem(a,0,args) != -1);
- args=a;
- }
- retval = PyObject_CallObject(PyCallable_Check,args);
- Py_DECREF(args);
- return retval;
+ if (callable == NULL) {
+ va_end(va);
+ return null_error();
+ }
+
+ if (format)
+ args = Py_VaBuildValue(format, va);
+ else
+ args = PyTuple_New(0);
+
+ va_end(va);
+
+ if (args == NULL)
+ return NULL;
+
+ if (!PyTuple_Check(args)) {
+ PyObject *a;
+
+ a = PyTuple_New(1);
+ if (a == NULL)
+ return NULL;
+ if (PyTuple_SetItem(a, 0, args) < 0)
+ return NULL;
+ args = a;
+ }
+ retval = PyObject_CallObject(callable, args);
+
+ Py_DECREF(args);
+
+ return retval;
}
PyObject *
@@ -1031,94 +1378,65 @@ PyObject *
PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
#else
/* VARARGS */
-PyObject_CallMethod(va_alist) va_dcl
+ PyObject_CallMethod(va_alist) va_dcl
#endif
{
- va_list va;
- PyObject *args, *func=0, *retval;
+ va_list va;
+ PyObject *args, *func = 0, *retval;
#ifdef HAVE_STDARG_PROTOTYPES
- va_start(va, format);
+ va_start(va, format);
#else
- PyObject *o;
- char *name;
- char *format;
- va_start(va);
- o = va_arg(va, PyObject *);
- name = va_arg(va, char *);
- format = va_arg(va, char *);
+ PyObject *o;
+ char *name;
+ char *format;
+ va_start(va);
+ o = va_arg(va, PyObject *);
+ name = va_arg(va, char *);
+ format = va_arg(va, char *);
#endif
- if( ! o || ! name)
- {
- va_end(va);
- return Py_ReturnNullError();
- }
-
- func=PyObject_GetAttrString(o,name);
- if(! func)
- {
- va_end(va);
- PyErr_SetString(PyExc_AttributeError,name);
- return 0;
- }
-
- if(! (PyCallable_Check(func)))
- {
- va_end(va);
- PyErr_SetString(PyExc_TypeError,"call of non-callable attribute");
- return 0;
- }
-
- if(format && *format)
- args = Py_VaBuildValue(format, va);
- else
- args = PyTuple_New(0);
-
- va_end(va);
-
- if(! args) return NULL;
-
- if(! PyTuple_Check(args))
- {
- PyObject *a;
-
- Py_TRY(a=PyTuple_New(1));
- Py_TRY(PyTuple_SetItem(a,0,args) != -1);
- args=a;
- }
-
- retval = PyObject_CallObject(func,args);
- Py_DECREF(args);
- Py_DECREF(func);
- return retval;
-}
+ if (o == NULL || name == NULL) {
+ va_end(va);
+ return null_error();
+ }
-PyObject *
-PyMapping_GetItemString(o, key)
- PyObject *o;
- char *key;
-{
- PyObject *okey, *r;
+ func = PyObject_GetAttrString(o, name);
+ if (func == NULL) {
+ va_end(va);
+ PyErr_SetString(PyExc_AttributeError, name);
+ return 0;
+ }
- if( ! key) return Py_ReturnNullError();
- Py_TRY(okey=PyString_FromString(key));
- r = PyObject_GetItem(o,okey);
- Py_DECREF(okey);
- return r;
-}
+ if (!PyCallable_Check(func)) {
+ va_end(va);
+ return type_error("call of non-callable attribute");
+ }
-int
-PyMapping_SetItemString(o, key, value)
- PyObject *o;
- char *key;
- PyObject *value;
-{
- PyObject *okey;
- int r;
-
- if( ! key) return Py_ReturnNullError(),-1;
- if (!(okey=PyString_FromString(key))) return -1;
- r = PyObject_SetItem(o,okey,value);
- Py_DECREF(okey);
- return r;
+ if (format && *format)
+ args = Py_VaBuildValue(format, va);
+ else
+ args = PyTuple_New(0);
+
+ va_end(va);
+
+ if (!args)
+ return NULL;
+
+ if (!PyTuple_Check(args)) {
+ PyObject *a;
+
+ a = PyTuple_New(1);
+ if (a == NULL)
+ return NULL;
+ if (PyTuple_SetItem(a, 0, args) < 0)
+ return NULL;
+ args = a;
+ }
+
+ retval = PyObject_CallObject(func, args);
+
+ Py_DECREF(args);
+ Py_DECREF(func);
+
+ return retval;
}