/* * 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. Load more
/* * 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 int test_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_LONG static 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; }