symbian-qemu-0.9.1-12/python-2.6.1/Modules/xxsubtype.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #include "Python.h"
       
     2 #include "structmember.h"
       
     3 
       
     4 PyDoc_STRVAR(xxsubtype__doc__,
       
     5 "xxsubtype is an example module showing how to subtype builtin types from C.\n"
       
     6 "test_descr.py in the standard test suite requires it in order to complete.\n"
       
     7 "If you don't care about the examples, and don't intend to run the Python\n"
       
     8 "test suite, you can recompile Python without Modules/xxsubtype.c.");
       
     9 
       
    10 /* We link this module statically for convenience.  If compiled as a shared
       
    11    library instead, some compilers don't allow addresses of Python objects
       
    12    defined in other libraries to be used in static initializers here.  The
       
    13    DEFERRED_ADDRESS macro is used to tag the slots where such addresses
       
    14    appear; the module init function must fill in the tagged slots at runtime.
       
    15    The argument is for documentation -- the macro ignores it.
       
    16 */
       
    17 #define DEFERRED_ADDRESS(ADDR) 0
       
    18 
       
    19 /* spamlist -- a list subtype */
       
    20 
       
    21 typedef struct {
       
    22 	PyListObject list;
       
    23 	int state;
       
    24 } spamlistobject;
       
    25 
       
    26 static PyObject *
       
    27 spamlist_getstate(spamlistobject *self, PyObject *args)
       
    28 {
       
    29 	if (!PyArg_ParseTuple(args, ":getstate"))
       
    30 		return NULL;
       
    31 	return PyInt_FromLong(self->state);
       
    32 }
       
    33 
       
    34 static PyObject *
       
    35 spamlist_setstate(spamlistobject *self, PyObject *args)
       
    36 {
       
    37 	int state;
       
    38 
       
    39 	if (!PyArg_ParseTuple(args, "i:setstate", &state))
       
    40 		return NULL;
       
    41 	self->state = state;
       
    42 	Py_INCREF(Py_None);
       
    43 	return Py_None;
       
    44 }
       
    45 
       
    46 static PyObject *
       
    47 spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw)
       
    48 {
       
    49 	PyObject *result = PyTuple_New(3);
       
    50 
       
    51 	if (result != NULL) {
       
    52 		if (self == NULL)
       
    53 			self = Py_None;
       
    54 		if (kw == NULL)
       
    55 			kw = Py_None;
       
    56 		Py_INCREF(self);
       
    57 		PyTuple_SET_ITEM(result, 0, self);
       
    58 		Py_INCREF(args);
       
    59 		PyTuple_SET_ITEM(result, 1, args);
       
    60 		Py_INCREF(kw);
       
    61 		PyTuple_SET_ITEM(result, 2, kw);
       
    62 	}
       
    63 	return result;
       
    64 }
       
    65 
       
    66 static PyMethodDef spamlist_methods[] = {
       
    67 	{"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
       
    68 	 	PyDoc_STR("getstate() -> state")},
       
    69 	{"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
       
    70 	 	PyDoc_STR("setstate(state)")},
       
    71 	/* These entries differ only in the flags; they are used by the tests
       
    72 	   in test.test_descr. */
       
    73 	{"classmeth", (PyCFunction)spamlist_specialmeth,
       
    74 		METH_VARARGS | METH_KEYWORDS | METH_CLASS,
       
    75 	 	PyDoc_STR("classmeth(*args, **kw)")},
       
    76 	{"staticmeth", (PyCFunction)spamlist_specialmeth,
       
    77 		METH_VARARGS | METH_KEYWORDS | METH_STATIC,
       
    78 	 	PyDoc_STR("staticmeth(*args, **kw)")},
       
    79 	{NULL,	NULL},
       
    80 };
       
    81 
       
    82 static int
       
    83 spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
       
    84 {
       
    85 	if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
       
    86 		return -1;
       
    87 	self->state = 0;
       
    88 	return 0;
       
    89 }
       
    90 
       
    91 static PyObject *
       
    92 spamlist_state_get(spamlistobject *self)
       
    93 {
       
    94 	return PyInt_FromLong(self->state);
       
    95 }
       
    96 
       
    97 static PyGetSetDef spamlist_getsets[] = {
       
    98 	{"state", (getter)spamlist_state_get, NULL,
       
    99 	 PyDoc_STR("an int variable for demonstration purposes")},
       
   100 	{0}
       
   101 };
       
   102 
       
   103 static PyTypeObject spamlist_type = {
       
   104 	PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
       
   105 	"xxsubtype.spamlist",
       
   106 	sizeof(spamlistobject),
       
   107 	0,
       
   108 	0,					/* tp_dealloc */
       
   109 	0,					/* tp_print */
       
   110 	0,					/* tp_getattr */
       
   111 	0,					/* tp_setattr */
       
   112 	0,					/* tp_compare */
       
   113 	0,					/* tp_repr */
       
   114 	0,					/* tp_as_number */
       
   115 	0,					/* tp_as_sequence */
       
   116 	0,					/* tp_as_mapping */
       
   117 	0,					/* tp_hash */
       
   118 	0,					/* tp_call */
       
   119 	0,					/* tp_str */
       
   120 	0,					/* tp_getattro */
       
   121 	0,					/* tp_setattro */
       
   122 	0,					/* tp_as_buffer */
       
   123 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
       
   124 	0,					/* tp_doc */
       
   125 	0,					/* tp_traverse */
       
   126 	0,					/* tp_clear */
       
   127 	0,					/* tp_richcompare */
       
   128 	0,					/* tp_weaklistoffset */
       
   129 	0,					/* tp_iter */
       
   130 	0,					/* tp_iternext */
       
   131 	spamlist_methods,			/* tp_methods */
       
   132 	0,					/* tp_members */
       
   133 	spamlist_getsets,			/* tp_getset */
       
   134 	DEFERRED_ADDRESS(&PyList_Type),		/* tp_base */
       
   135 	0,					/* tp_dict */
       
   136 	0,					/* tp_descr_get */
       
   137 	0,					/* tp_descr_set */
       
   138 	0,					/* tp_dictoffset */
       
   139 	(initproc)spamlist_init,		/* tp_init */
       
   140 	0,					/* tp_alloc */
       
   141 	0,					/* tp_new */
       
   142 };
       
   143 
       
   144 /* spamdict -- a dict subtype */
       
   145 
       
   146 typedef struct {
       
   147 	PyDictObject dict;
       
   148 	int state;
       
   149 } spamdictobject;
       
   150 
       
   151 static PyObject *
       
   152 spamdict_getstate(spamdictobject *self, PyObject *args)
       
   153 {
       
   154 	if (!PyArg_ParseTuple(args, ":getstate"))
       
   155 		return NULL;
       
   156 	return PyInt_FromLong(self->state);
       
   157 }
       
   158 
       
   159 static PyObject *
       
   160 spamdict_setstate(spamdictobject *self, PyObject *args)
       
   161 {
       
   162 	int state;
       
   163 
       
   164 	if (!PyArg_ParseTuple(args, "i:setstate", &state))
       
   165 		return NULL;
       
   166 	self->state = state;
       
   167 	Py_INCREF(Py_None);
       
   168 	return Py_None;
       
   169 }
       
   170 
       
   171 static PyMethodDef spamdict_methods[] = {
       
   172 	{"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
       
   173 	 	PyDoc_STR("getstate() -> state")},
       
   174 	{"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
       
   175 	 	PyDoc_STR("setstate(state)")},
       
   176 	{NULL,	NULL},
       
   177 };
       
   178 
       
   179 static int
       
   180 spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
       
   181 {
       
   182 	if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
       
   183 		return -1;
       
   184 	self->state = 0;
       
   185 	return 0;
       
   186 }
       
   187 
       
   188 static PyMemberDef spamdict_members[] = {
       
   189 	{"state", T_INT, offsetof(spamdictobject, state), READONLY,
       
   190 	 PyDoc_STR("an int variable for demonstration purposes")},
       
   191 	{0}
       
   192 };
       
   193 
       
   194 static PyTypeObject spamdict_type = {
       
   195 	PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
       
   196 	"xxsubtype.spamdict",
       
   197 	sizeof(spamdictobject),
       
   198 	0,
       
   199 	0,					/* tp_dealloc */
       
   200 	0,					/* tp_print */
       
   201 	0,					/* tp_getattr */
       
   202 	0,					/* tp_setattr */
       
   203 	0,					/* tp_compare */
       
   204 	0,					/* tp_repr */
       
   205 	0,					/* tp_as_number */
       
   206 	0,					/* tp_as_sequence */
       
   207 	0,					/* tp_as_mapping */
       
   208 	0,					/* tp_hash */
       
   209 	0,					/* tp_call */
       
   210 	0,					/* tp_str */
       
   211 	0,					/* tp_getattro */
       
   212 	0,					/* tp_setattro */
       
   213 	0,					/* tp_as_buffer */
       
   214 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
       
   215 	0,					/* tp_doc */
       
   216 	0,					/* tp_traverse */
       
   217 	0,					/* tp_clear */
       
   218 	0,					/* tp_richcompare */
       
   219 	0,					/* tp_weaklistoffset */
       
   220 	0,					/* tp_iter */
       
   221 	0,					/* tp_iternext */
       
   222 	spamdict_methods,			/* tp_methods */
       
   223 	spamdict_members,			/* tp_members */
       
   224 	0,					/* tp_getset */
       
   225 	DEFERRED_ADDRESS(&PyDict_Type),		/* tp_base */
       
   226 	0,					/* tp_dict */
       
   227 	0,					/* tp_descr_get */
       
   228 	0,					/* tp_descr_set */
       
   229 	0,					/* tp_dictoffset */
       
   230 	(initproc)spamdict_init,		/* tp_init */
       
   231 	0,					/* tp_alloc */
       
   232 	0,					/* tp_new */
       
   233 };
       
   234 
       
   235 static PyObject *
       
   236 spam_bench(PyObject *self, PyObject *args)
       
   237 {
       
   238 	PyObject *obj, *name, *res;
       
   239 	int n = 1000;
       
   240 	time_t t0, t1;
       
   241 
       
   242 	if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n))
       
   243 		return NULL;
       
   244 	t0 = clock();
       
   245 	while (--n >= 0) {
       
   246 		res = PyObject_GetAttr(obj, name);
       
   247 		if (res == NULL)
       
   248 			return NULL;
       
   249 		Py_DECREF(res);
       
   250 	}
       
   251 	t1 = clock();
       
   252 	return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC);
       
   253 }
       
   254 
       
   255 static PyMethodDef xxsubtype_functions[] = {
       
   256 	{"bench",	spam_bench, 	METH_VARARGS},
       
   257 	{NULL,		NULL}		/* sentinel */
       
   258 };
       
   259 
       
   260 PyMODINIT_FUNC
       
   261 initxxsubtype(void)
       
   262 {
       
   263 	PyObject *m;
       
   264 
       
   265 	/* Fill in deferred data addresses.  This must be done before
       
   266 	   PyType_Ready() is called.  Note that PyType_Ready() automatically
       
   267 	   initializes the ob.ob_type field to &PyType_Type if it's NULL,
       
   268 	   so it's not necessary to fill in ob_type first. */
       
   269 	spamdict_type.tp_base = &PyDict_Type;
       
   270 	if (PyType_Ready(&spamdict_type) < 0)
       
   271 		return;
       
   272 
       
   273 	spamlist_type.tp_base = &PyList_Type;
       
   274 	if (PyType_Ready(&spamlist_type) < 0)
       
   275 		return;
       
   276 
       
   277 	m = Py_InitModule3("xxsubtype",
       
   278 			   xxsubtype_functions,
       
   279 			   xxsubtype__doc__);
       
   280 	if (m == NULL)
       
   281 		return;
       
   282 
       
   283 	if (PyType_Ready(&spamlist_type) < 0)
       
   284 		return;
       
   285 	if (PyType_Ready(&spamdict_type) < 0)
       
   286 		return;
       
   287 
       
   288 	Py_INCREF(&spamlist_type);
       
   289 	if (PyModule_AddObject(m, "spamlist",
       
   290 			       (PyObject *) &spamlist_type) < 0)
       
   291 		return;
       
   292 
       
   293 	Py_INCREF(&spamdict_type);
       
   294 	if (PyModule_AddObject(m, "spamdict",
       
   295 			       (PyObject *) &spamdict_type) < 0)
       
   296 		return;
       
   297 }