PageRenderTime 318ms CodeModel.GetById 121ms app.highlight 5ms RepoModel.GetById 130ms app.codeStats 60ms

/Unittests/MethodObjectTest.cc

http://unladen-swallow.googlecode.com/
C++ | 52 lines | 34 code | 6 blank | 12 comment | 4 complexity | 8ad2890f97d30035342ea0e789faf9b2 MD5 | raw file
 1#include "Python.h"
 2#include "gtest/gtest.h"
 3
 4class PyCFunctionTest : public testing::Test {
 5protected:
 6    PyCFunctionTest()
 7    {
 8        Py_NoSiteFlag = true;
 9        Py_Initialize();
10    }
11    ~PyCFunctionTest()
12    {
13        Py_Finalize();
14    }
15};
16
17// Most PyMethodDef structs are allocated globally, and the compiler takes care
18// of zeroing out uninitialized fields. Not so with malloc(), which causes
19// problems for some embedding applications that don't memset() their memory.
20// This has been observed in applications that heap-allocate PyMethodDefs and
21// then set METH_NOARGS, which previously was #defined to METH_ARG_RANGE.
22// This is arguably a problem in the application, but if it works with Python
23// 2.6, it needs to work with Unladen Swallow.
24TEST_F(PyCFunctionTest, HeapAllocatedMethNoArgs)
25{
26    PyMethodDef *method_def = PyMem_New(PyMethodDef, 1);
27    ASSERT_TRUE(method_def != NULL);
28    method_def->ml_min_arity = 55;  // Dirty some memory.
29
30    // From here on, pretend that method_def was free()d, then we did another
31    // method_def = PyMem_New(PyMethodDef, 1); that returned the same memory,
32    // but uninitialized. This is the behaviour observed in the wild.
33    method_def->ml_flags = METH_NOARGS;                // Important.
34    method_def->ml_meth = (PyCFunction)PyList_Append;  // Dummy.
35
36    // Dummy objects; their type/contents are unimportant.
37    PyObject *self = PyList_New(1);
38    PyObject *module = PyList_New(1);
39    ASSERT_TRUE(self != NULL);
40    ASSERT_TRUE(module != NULL);
41
42    // This PyCFunction_NewEx call used to trigger a PyErr_BadInternalCall.
43    PyErr_Clear();
44    PyObject *my_function = PyCFunction_NewEx(method_def, self, module);
45    EXPECT_TRUE(my_function != NULL);
46    EXPECT_FALSE(PyErr_Occurred());
47
48    PyErr_Clear();
49    PyMem_Free(method_def);
50    Py_CLEAR(self);
51    Py_CLEAR(module);
52}