cinap_lenrekadd hg and python4bb9e2215 years agoHistory
898 lines · 23.6 KB · C
RawDownload
/* * C Extension module to test Python interpreter C APIs. * * The 'test_*' functions exported by this module are run as part of the * standard Python regression test, via Lib/test/test_capi.py. */ #include "Python.h"#include <float.h>#include "structmember.h" #ifdef WITH_THREAD#include "pythread.h"#endif /* WITH_THREAD */static PyObject *TestError;	/* set to exception object in init */ /* Raise TestError with test_name + ": " + msg, and return NULL. */ static PyObject *raiseTestError(const char* test_name, const char* msg){	char buf[2048]; 	if (strlen(test_name) + strlen(msg) > sizeof(buf) - 50)		PyErr_SetString(TestError, "internal error msg too large");	else {		PyOS_snprintf(buf, sizeof(buf), "%s: %s", test_name, msg);		PyErr_SetString(TestError, buf);	}	return NULL;} /* Test #defines from pyconfig.h (particularly the SIZEOF_* defines).    The ones derived from autoconf on the UNIX-like OSes can be relied   upon (in the absence of sloppy cross-compiling), but the Windows   platforms have these hardcoded.  Better safe than sorry.*/static PyObject*sizeof_error(const char* fatname, const char* typname,        int expected, int got){	char buf[1024];	PyOS_snprintf(buf, sizeof(buf),		"%.200s #define == %d but sizeof(%.200s) == %d",		fatname, expected, typname, got);	PyErr_SetString(TestError, buf);	return (PyObject*)NULL;} static PyObject*test_config(PyObject *self){#define CHECK_SIZEOF(FATNAME, TYPE) \	    if (FATNAME != sizeof(TYPE)) \    	    	return sizeof_error(#FATNAME, #TYPE, FATNAME, sizeof(TYPE)) 	CHECK_SIZEOF(SIZEOF_SHORT, short);	CHECK_SIZEOF(SIZEOF_INT, int);	CHECK_SIZEOF(SIZEOF_LONG, long);	CHECK_SIZEOF(SIZEOF_VOID_P, void*);	CHECK_SIZEOF(SIZEOF_TIME_T, time_t);#ifdef HAVE_LONG_LONG	CHECK_SIZEOF(SIZEOF_LONG_LONG, PY_LONG_LONG);#endif #undef CHECK_SIZEOF 	Py_INCREF(Py_None);	return Py_None;} static PyObject*test_list_api(PyObject *self){	PyObject* list;	int i; 	/* SF bug 132008:  PyList_Reverse segfaults */#define NLIST 30	list = PyList_New(NLIST);	if (list == (PyObject*)NULL)		return (PyObject*)NULL;	/* list = range(NLIST) */	for (i = 0; i < NLIST; ++i) {		PyObject* anint = PyInt_FromLong(i);		if (anint == (PyObject*)NULL) {			Py_DECREF(list);			return (PyObject*)NULL;		}		PyList_SET_ITEM(list, i, anint);	}	/* list.reverse(), via PyList_Reverse() */	i = PyList_Reverse(list);   /* should not blow up! */	if (i != 0) {		Py_DECREF(list);		return (PyObject*)NULL;	}	/* Check that list == range(29, -1, -1) now */	for (i = 0; i < NLIST; ++i) {		PyObject* anint = PyList_GET_ITEM(list, i);		if (PyInt_AS_LONG(anint) != NLIST-1-i) {			PyErr_SetString(TestError,			                "test_list_api: reverse screwed up");			Py_DECREF(list);			return (PyObject*)NULL;		}	}	Py_DECREF(list);#undef NLIST 	Py_INCREF(Py_None);	return Py_None;} static inttest_dict_inner(int count){	Py_ssize_t pos = 0, iterations = 0;	int i;	PyObject *dict = PyDict_New();	PyObject *v, *k; 	if (dict == NULL)		return -1; 	for (i = 0; i < count; i++) {		v = PyInt_FromLong(i);		PyDict_SetItem(dict, v, v);		Py_DECREF(v);	} 	while (PyDict_Next(dict, &pos, &k, &v)) {		PyObject *o;		iterations++; 		i = PyInt_AS_LONG(v) + 1;		o = PyInt_FromLong(i);		if (o == NULL)			return -1;		if (PyDict_SetItem(dict, k, o) < 0) {			Py_DECREF(o);			return -1;		}		Py_DECREF(o);	} 	Py_DECREF(dict); 	if (iterations != count) {		PyErr_SetString(			TestError,			"test_dict_iteration: dict iteration went wrong ");		return -1;	} else {		return 0;	}} static PyObject*test_dict_iteration(PyObject* self){	int i; 	for (i = 0; i < 200; i++) {		if (test_dict_inner(i) < 0) {			return NULL;		}	} 	Py_INCREF(Py_None);	return Py_None;}  /* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG)   PyLong_{As, From}{Unsigned,}LongLong().    Note that the meat of the test is contained in testcapi_long.h.   This is revolting, but delicate code duplication is worse:  "almost   exactly the same" code is needed to test PY_LONG_LONG, but the ubiquitous   dependence on type names makes it impossible to use a parameterized   function.  A giant macro would be even worse than this.  A C++ template   would be perfect.    The "report an error" functions are deliberately not part of the #include   file:  if the test fails, you can set a breakpoint in the appropriate   error function directly, and crawl back from there in the debugger.*/ #define UNBIND(X)  Py_DECREF(X); (X) = NULL static PyObject *raise_test_long_error(const char* msg){	return raiseTestError("test_long_api", msg);} #define TESTNAME	test_long_api_inner#define TYPENAME	long#define F_S_TO_PY	PyLong_FromLong#define F_PY_TO_S	PyLong_AsLong#define F_U_TO_PY	PyLong_FromUnsignedLong#define F_PY_TO_U	PyLong_AsUnsignedLong #include "testcapi_long.h" static PyObject *test_long_api(PyObject* self){	return TESTNAME(raise_test_long_error);} #undef TESTNAME#undef TYPENAME#undef F_S_TO_PY#undef F_PY_TO_S#undef F_U_TO_PY#undef F_PY_TO_U #ifdef HAVE_LONG_LONG static PyObject *raise_test_longlong_error(const char* msg){	return raiseTestError("test_longlong_api", msg);} #define TESTNAME	test_longlong_api_inner#define TYPENAME	PY_LONG_LONG#define F_S_TO_PY	PyLong_FromLongLong#define F_PY_TO_S	PyLong_AsLongLong#define F_U_TO_PY	PyLong_FromUnsignedLongLong#define F_PY_TO_U	PyLong_AsUnsignedLongLong #include "testcapi_long.h" static PyObject *test_longlong_api(PyObject* self, PyObject *args){	return TESTNAME(raise_test_longlong_error);} #undef TESTNAME#undef TYPENAME#undef F_S_TO_PY#undef F_PY_TO_S#undef F_U_TO_PY#undef F_PY_TO_U /* Test the L code for PyArg_ParseTuple.  This should deliver a PY_LONG_LONG   for both long and int arguments.  The test may leak a little memory if   it fails.*/static PyObject *test_L_code(PyObject *self){	PyObject *tuple, *num;	PY_LONG_LONG value;         tuple = PyTuple_New(1);        if (tuple == NULL)        	return NULL;         num = PyLong_FromLong(42);        if (num == NULL)        	return NULL;         PyTuple_SET_ITEM(tuple, 0, num);         value = -1;        if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)        	return NULL;        if (value != 42)        	return raiseTestError("test_L_code",			"L code returned wrong value for long 42"); 	Py_DECREF(num);        num = PyInt_FromLong(42);        if (num == NULL)        	return NULL;         PyTuple_SET_ITEM(tuple, 0, num); 	value = -1;        if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0)        	return NULL;        if (value != 42)        	return raiseTestError("test_L_code",			"L code returned wrong value for int 42"); 	Py_DECREF(tuple);	Py_INCREF(Py_None);	return Py_None;} #endif	/* ifdef HAVE_LONG_LONG */ /* Test tuple argument processing */static PyObject *getargs_tuple(PyObject *self, PyObject *args){	int a, b, c;	if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c))		return NULL;	return Py_BuildValue("iii", a, b, c);} /* Functions to call PyArg_ParseTuple with integer format codes,   and return the result.*/static PyObject *getargs_b(PyObject *self, PyObject *args){	unsigned char value;	if (!PyArg_ParseTuple(args, "b", &value))		return NULL;	return PyLong_FromUnsignedLong((unsigned long)value);} static PyObject *getargs_B(PyObject *self, PyObject *args){	unsigned char value;	if (!PyArg_ParseTuple(args, "B", &value))		return NULL;	return PyLong_FromUnsignedLong((unsigned long)value);} static PyObject *getargs_H(PyObject *self, PyObject *args){	unsigned short value;	if (!PyArg_ParseTuple(args, "H", &value))		return NULL;	return PyLong_FromUnsignedLong((unsigned long)value);} static PyObject *getargs_I(PyObject *self, PyObject *args){	unsigned int value;	if (!PyArg_ParseTuple(args, "I", &value))		return NULL;	return PyLong_FromUnsignedLong((unsigned long)value);} static PyObject *getargs_k(PyObject *self, PyObject *args){	unsigned long value;	if (!PyArg_ParseTuple(args, "k", &value))		return NULL;	return PyLong_FromUnsignedLong(value);} static PyObject *getargs_i(PyObject *self, PyObject *args){	int value;	if (!PyArg_ParseTuple(args, "i", &value))		return NULL;	return PyLong_FromLong((long)value);} static PyObject *getargs_l(PyObject *self, PyObject *args){	long value;	if (!PyArg_ParseTuple(args, "l", &value))		return NULL;	return PyLong_FromLong(value);} static PyObject *getargs_n(PyObject *self, PyObject *args){	Py_ssize_t value;	if (!PyArg_ParseTuple(args, "n", &value))	return NULL;	return PyInt_FromSsize_t(value);} #ifdef HAVE_LONG_LONGstatic PyObject *getargs_L(PyObject *self, PyObject *args){	PY_LONG_LONG value;	if (!PyArg_ParseTuple(args, "L", &value))		return NULL;	return PyLong_FromLongLong(value);} static PyObject *getargs_K(PyObject *self, PyObject *args){	unsigned PY_LONG_LONG value;	if (!PyArg_ParseTuple(args, "K", &value))		return NULL;	return PyLong_FromUnsignedLongLong(value);}#endif /* This function not only tests the 'k' getargs code, but also the   PyInt_AsUnsignedLongMask() and PyInt_AsUnsignedLongMask() functions. */static PyObject *test_k_code(PyObject *self){	PyObject *tuple, *num;	unsigned long value;         tuple = PyTuple_New(1);        if (tuple == NULL)        	return NULL; 	/* a number larger than ULONG_MAX even on 64-bit platforms */        num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);        if (num == NULL)        	return NULL; 	value = PyInt_AsUnsignedLongMask(num);	if (value != ULONG_MAX)        	return raiseTestError("test_k_code",	    "PyInt_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");         PyTuple_SET_ITEM(tuple, 0, num);         value = 0;        if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)        	return NULL;        if (value != ULONG_MAX)        	return raiseTestError("test_k_code",			"k code returned wrong value for long 0xFFF...FFF"); 	Py_DECREF(num);        num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16);        if (num == NULL)        	return NULL; 	value = PyInt_AsUnsignedLongMask(num);	if (value != (unsigned long)-0x42)        	return raiseTestError("test_k_code",	    "PyInt_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF");         PyTuple_SET_ITEM(tuple, 0, num); 	value = 0;        if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)        	return NULL;        if (value != (unsigned long)-0x42)        	return raiseTestError("test_k_code",			"k code returned wrong value for long -0xFFF..000042"); 	Py_DECREF(tuple);	Py_INCREF(Py_None);	return Py_None;} #ifdef Py_USING_UNICODE /* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case   of an error.*/static PyObject *test_u_code(PyObject *self){	PyObject *tuple, *obj;	Py_UNICODE *value;	int len;         tuple = PyTuple_New(1);        if (tuple == NULL)        	return NULL;         obj = PyUnicode_Decode("test", strlen("test"),			       "ascii", NULL);        if (obj == NULL)        	return NULL;         PyTuple_SET_ITEM(tuple, 0, obj);         value = 0;        if (PyArg_ParseTuple(tuple, "u:test_u_code", &value) < 0)        	return NULL;        if (value != PyUnicode_AS_UNICODE(obj))        	return raiseTestError("test_u_code",			"u code returned wrong value for u'test'");        value = 0;        if (PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len) < 0)        	return NULL;        if (value != PyUnicode_AS_UNICODE(obj) ||	    len != PyUnicode_GET_SIZE(obj))        	return raiseTestError("test_u_code",			"u# code returned wrong values for u'test'"); 	Py_DECREF(tuple);	Py_INCREF(Py_None);	return Py_None;} 

Lines 1–500 of 898.