From cbarton at metavr.com Sun Aug 5 09:38:36 2007 From: cbarton at metavr.com (Campbell Barton) Date: Sun, 05 Aug 2007 17:38:36 +1000 Subject: [capi-sig] Weakref callbacks Message-ID: <46B57E7C.5000800@metavr.com> Hi, recently I needed to use weakrefs and found them a bit awkward because they need to accept a python function when that function is (usually/always?) a C function. Heres an example of a weakref callback in C... Anyone know if theres a nicer way to use PyCFunction_New, rather then define a PyMethodDef beforehand? Id prefer if you could just pass the C function as the weakref callback, perhaps it would be possible to have an alternate PyWeakref_NewProxy function that accepted a C function as a callback. heres the weakref callback method I used.... _________ /* c function*/ PyObject * arm_weakref_callback_weakref_dealloc(PyObject *self, PyObject *weakref); /* python callable */ PyObject * arm_weakref_callback_weakref_dealloc__pyfunc; /* internal func to remove weakref from weakref list */ PyObject * arm_weakref_callback_weakref_dealloc(PyObject *self, PyObject *weakref) { char *list_name = ARM_WEAKREF_LIST_NAME; PyObject *maindict = NULL, *armlist = NULL; int i; /* error checking below removed */ maindict= PyModule_GetDict(PyImport_AddModule( "__main__")); armlist = PyDict_GetItemString(maindict, list_name); i = PySequence_Index(armlist, weakref); PySequence_DelItem(armlist, i); Py_RETURN_NONE; } PyObject *Armature_CreatePyObject(struct bArmature *armature) { /* snip----- */ weakref = PyWeakref_NewProxy((PyObject*)py_armature, arm_weakref_callback_weakref_dealloc__pyfunc); /* snip----- */ return (PyObject *) py_armature; } /* internal use only */ static PyMethodDef bpy_arm_weakref_callback_weakref_dealloc[] = { {"arm_weakref_callback_weakref_dealloc", arm_weakref_callback_weakref_dealloc, METH_O, ""} }; //-------------------MODULE INITIALIZATION-------------------------------- PyObject *Armature_Init(void) { /* snip----- */ arm_weakref_callback_weakref_dealloc__pyfunc = PyCFunction_New(bpy_arm_weakref_callback_weakref_dealloc, NULL); /* snip----- */ } -- Campbell J Barton (ideasman42) From pablo.yabo at gmail.com Mon Aug 13 23:51:27 2007 From: pablo.yabo at gmail.com (Pablo Yabo) Date: Mon, 13 Aug 2007 18:51:27 -0300 Subject: [capi-sig] Threading Message-ID: Hello, I want to embed Python in an application and use an API of the application from Python. The application uses a library that creates several threads and I the users of the application will write Python scripts handling this events. The problem is that I having problems with threads. I saw that I have to PyEval_InitThreads and then PyThreadState_New and PyThreadState_Swap from the new thread but this way to solve the problem doesn't work for me because I need to let 2 or more threads run at the SAME time. The interpreter lock doesn't let them run at the same time so I'm looking for another solution. I saw Py_NewInterpreter and I tried to use it but it doesn't work if I don't keep the lock. Can anyone help me to solve this issue or tell me 'Forget it!'? Thanks on advance, Pablo Yabo -- http://www.nektra.com From alika at spray.se Tue Aug 14 10:15:16 2007 From: alika at spray.se (Ali Alhakim) Date: Tue, 14 Aug 2007 08:15:16 +0000 Subject: [capi-sig] Extension Problem Message-ID: <114389462927509@lycos-europe.com> Hello! I'm quite new to Python and definitely a beginner in implementing Python extensions in C/C++. I've followed the structure given in the formal Python documentation to write the following code block: =========== //cmatmod.c #include static unsigned int eigenvect_calc(double *min_eps) { return 5; } static PyObject *cmat_eigv(PyObject *self, PyObject *args) { double *min_eps; unsigned int m; if(!PyArg_ParseTuple(args, "d", &min_eps)) return NULL; m=eigenvect_calc(min_eps); return Py_BuildValue("I", m); } static PyMethodDef cmat_methods[]= { { "eigenvect", cmat_eigv, METH_VARARGS, "Comment"},{NULL, NULL, 0, NULL} }; void initcmat(void) { (void) Py_InitModule("cmat", cmat_methods); } =========== I have succeeded to build and install this extension using disutils package in the setup.py file below: =========== from distutils.core import setup from distutils.extension import Extension setup(name='eigenvect', version='1.0', ext_modules=[Extension('cmat', ['cmatmod.c'])], ) ========== But when I try to call eigenvect(3.0) from Python I would receive a core dump: ========== 6 [main] python 2336 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack) Segmentation fault (core dumped) ========== My question is what is wrong with the extension code above? Is it something with reference counting? I don't know which method is suitable for debugging extension codes. I've tried gdb but I didn't understand the debug information: ========== (gdb) >>> eigenvect(4.0) Program received signal SIGSEGV, Segmentation fault. ---Type to continue, or q to quit--- 0x6abb248e in libpython2!PyEval_EvalFrameEx () from /usr/bin/libpython2.5dll (gdb) ========== /best regards G? in och titta p? n?tets roligaste filmer just nu eller ladda upp ditt eget bidrag p? Spray Crazy. http://crazy.spray.se/ From mhammond at skippinet.com.au Tue Aug 14 15:51:04 2007 From: mhammond at skippinet.com.au (Mark Hammond) Date: Tue, 14 Aug 2007 08:51:04 -0500 Subject: [capi-sig] Extension Problem In-Reply-To: <114389462927509@lycos-europe.com> References: <114389462927509@lycos-europe.com> Message-ID: <069401c7de7a$287aa090$6c01a8c0@bobcat> I'm not 100% sure, but try the following: > static unsigned int eigenvect_calc(double *min_eps) { return 5; } > > static PyObject *cmat_eigv(PyObject *self, PyObject *args) { Try adding a 3rd arg - PyObject *kw - although I was under the impression this should not matter, it might. Indeed, I hope it does, as I can't spot any other issue. Mark From anthony.tuininga at gmail.com Tue Aug 14 17:34:28 2007 From: anthony.tuininga at gmail.com (Anthony Tuininga) Date: Tue, 14 Aug 2007 09:34:28 -0600 Subject: [capi-sig] Extension Problem In-Reply-To: <114389462927509@lycos-europe.com> References: <114389462927509@lycos-europe.com> Message-ID: <703ae56b0708140834s2beaadb4hce0a40797c07cdb9@mail.gmail.com> I suspect the problem is the following: double *min_eps; if (!PyArg_ParseTuple(args, "d", &min_eps)) return NULL; That should be double min_eps; as Python is expecting a double, not a pointer to a double! And since the difference is about 4 bytes, that would explain the segfault. :-) Anthony On 8/14/07, Ali Alhakim wrote: > Hello! > > I'm quite new to Python and definitely a beginner in implementing Python > extensions in C/C++. I've followed the structure given in the formal Python > documentation to write the following code block: > =========== > //cmatmod.c > > #include > > static unsigned int eigenvect_calc(double *min_eps) > { > return 5; > } > > static PyObject *cmat_eigv(PyObject *self, PyObject *args) > { > double *min_eps; > unsigned int m; > if(!PyArg_ParseTuple(args, "d", &min_eps)) > return NULL; > m=eigenvect_calc(min_eps); > return Py_BuildValue("I", m); > } > static PyMethodDef cmat_methods[]= > { > { "eigenvect", cmat_eigv, METH_VARARGS, "Comment"},{NULL, NULL, 0, NULL} > }; > > void initcmat(void) > { > (void) Py_InitModule("cmat", cmat_methods); > } > > =========== > > I have succeeded to build and install this extension using disutils package > in the setup.py file below: > =========== > from distutils.core import setup > from distutils.extension import Extension > setup(name='eigenvect', > version='1.0', > ext_modules=[Extension('cmat', ['cmatmod.c'])], > ) > > ========== > But when I try to call eigenvect(3.0) from Python I would receive a core > dump: > ========== > > 6 [main] python 2336 _cygtls::handle_exceptions: Error while dumping state > (probably corrupted stack) > Segmentation fault (core dumped) > > ========== > My question is what is wrong with the extension code above? Is it something > with reference counting? > I don't know which method is suitable for debugging extension codes. I've > tried gdb but I didn't understand the debug information: > ========== > > (gdb) >>> eigenvect(4.0) > > Program received signal SIGSEGV, Segmentation fault. > ---Type to continue, or q to quit--- > 0x6abb248e in libpython2!PyEval_EvalFrameEx () from > /usr/bin/libpython2.5dll > (gdb) > > ========== > /best regards > > > > > > > > > > > > > > G? in och titta p? n?tets roligaste filmer just nu eller ladda upp ditt eget bidrag p? Spray Crazy. http://crazy.spray.se/ > _______________________________________________ > capi-sig mailing list > capi-sig at python.org > http://mail.python.org/mailman/listinfo/capi-sig > > From alika at spray.se Tue Aug 14 23:27:15 2007 From: alika at spray.se (Ali Alhakim) Date: Tue, 14 Aug 2007 21:27:15 +0000 Subject: [capi-sig] Extension Problem Message-ID: <57698768041784@lycos-europe.com> Thank you Anthony and Joe. I thought that all arguments should be passed into pointers. The introductary example in the python reference documentation about Python extension confused me. I hope that the mentioned example will be changed to something simpler. On Tue, 14 Aug 2007 17:34:28 +0200, Anthony Tuininga wrote: > I suspect the problem is the following: > > double *min_eps; > > if (!PyArg_ParseTuple(args, "d", &min_eps)) > return NULL; > > That should be > > double min_eps; > > as Python is expecting a double, not a pointer to a double! And since > the difference is about 4 bytes, that would explain the segfault. :-) > > Anthony > > On 8/14/07, Ali Alhakim wrote: >> Hello! >> >> I'm quite new to Python and definitely a beginner in implementing Python >> extensions in C/C++. I've followed the structure given in the formal >> Python >> documentation to write the following code block: >> =========== >> //cmatmod.c >> >> #include >> >> static unsigned int eigenvect_calc(double *min_eps) >> { >> return 5; >> } >> >> static PyObject *cmat_eigv(PyObject *self, PyObject *args) >> { >> double *min_eps; >> unsigned int m; >> if(!PyArg_ParseTuple(args, "d", &min_eps)) >> return NULL; >> m=eigenvect_calc(min_eps); >> return Py_BuildValue("I", m); >> } >> static PyMethodDef cmat_methods[]= >> { >> { "eigenvect", cmat_eigv, METH_VARARGS, "Comment"},{NULL, NULL, 0, >> NULL} >> }; >> >> void initcmat(void) >> { >> (void) Py_InitModule("cmat", cmat_methods); >> } >> >> =========== >> >> I have succeeded to build and install this extension using disutils >> package >> in the setup.py file below: >> =========== >> from distutils.core import setup >> from distutils.extension import Extension >> setup(name='eigenvect', >> version='1.0', >> ext_modules=[Extension('cmat', ['cmatmod.c'])], >> ) >> >> ========== >> But when I try to call eigenvect(3.0) from Python I would receive a core >> dump: >> ========== >> >> 6 [main] python 2336 _cygtls::handle_exceptions: Error while dumping >> state >> (probably corrupted stack) >> Segmentation fault (core dumped) >> >> ========== >> My question is what is wrong with the extension code above? Is it >> something >> with reference counting? >> I don't know which method is suitable for debugging extension codes. >> I've >> tried gdb but I didn't understand the debug information: >> ========== >> >> (gdb) >>> eigenvect(4.0) >> >> Program received signal SIGSEGV, Segmentation fault. >> ---Type to continue, or q to quit--- >> 0x6abb248e in libpython2!PyEval_EvalFrameEx () from >> /usr/bin/libpython2.5dll >> (gdb) >> >> ========== >> /best regards >> >> >> >> >> >> >> >> >> >> >> >> >> >> capi-sig mailing list >> capi-sig at python.org >> http://mail.python.org/mailman/listinfo/capi-sig >> >> > > > __________ NOD32 2460 (20070814) Information __________ > > This message was checked by NOD32 antivirus system. > http://www.eset.com > > Spray Webbhotell. Ingen startkostnad, 3 m?nader gratis och fri support. Perfekt f?r dig som ska starta en egen webbplats. http://www.spray.se/kampanj From mhammond at skippinet.com.au Tue Aug 14 23:44:02 2007 From: mhammond at skippinet.com.au (Mark Hammond) Date: Tue, 14 Aug 2007 16:44:02 -0500 Subject: [capi-sig] Extension Problem In-Reply-To: <57698768041784@lycos-europe.com> References: <57698768041784@lycos-europe.com> Message-ID: <06f601c7debc$3a963950$6c01a8c0@bobcat> In an attempt to redeem my previous blindness: > Thank you Anthony and Joe. I thought that all arguments > should be passed into pointers. By passing the address of a double, you *are* passing a pointer. > The introductary example in > the python reference documentation about Python extension > confused me. I hope that the mentioned example will be > changed to something simpler. Which specific example did you find confusing? I'm guessing the 'spam' example at http://docs.python.org/ext/simpleExample.html, as it does: const char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; and strings are somewhat "special", in that a pointer is the "native" type of a string, so a pointer to a pointer is indeed what is passed. If that example also parsed an integer it might have made things a little clearer... Cheers, Mark From alika at spray.se Tue Aug 14 23:54:28 2007 From: alika at spray.se (Ali Alhakim) Date: Tue, 14 Aug 2007 21:54:28 +0000 Subject: [capi-sig] Extension Problem Message-ID: <18358884839798@lycos-europe.com> Thank you Mark. That is exactly what my problem was.If the example included parsed integer and/or float (double) variables it would be much desriptive On Tue, 14 Aug 2007 23:44:02 +0200, Mark Hammond wrote: In an attempt to redeem my previous blindness: Thank you Anthony and Joe. I thought that all arguments should be passed into pointers. By passing the address of a double, you *are* passing a pointer. The introductary example in the python reference documentation about Python extension confused me. I hope that the mentioned example will be changed to something simpler. Which specific example did you find confusing? I'm guessing the 'spam' example at http://docs.python.org/ext/simpleExample.html, as it does: const char *command; int sts; if (!PyArg_ParseTuple(args, "s", &command)) return NULL; and strings are somewhat "special", in that a pointer is the "native" type of a string, so a pointer to a pointer is indeed what is passed. If that example also parsed an integer it might have made things a little clearer.. Cheers, Mark __________ NOD32 2460 (20070814) Information __________ This message was checked by NOD32 antivirus system. http://www.eset.com G? in och titta p? n?tets roligaste filmer just nu eller ladda upp ditt eget bidrag p? Spray Crazy. http://crazy.spray.se/ From cbarton at metavr.com Wed Aug 15 00:32:17 2007 From: cbarton at metavr.com (Campbell Barton) Date: Wed, 15 Aug 2007 08:32:17 +1000 Subject: [capi-sig] Extension Problem In-Reply-To: <114389462927509@lycos-europe.com> References: <114389462927509@lycos-europe.com> Message-ID: <46C22D71.5000702@metavr.com> Hi, as mentioned before, the pointers the issue here, Some other things you might want to consider. there more of a style thing ;) static PyObject *cmat_eigv(PyObject *self, PyObject *value) { double min_eps = PyFloat_AsDouble(value); if (min_eps==-1 && PyErr_Occurred()) return NULL; return PyInt_FromLong((long)eigenvect_calc(min_eps)); } static PyMethodDef cmat_methods[]= { { "eigenvect", cmat_eigv, METH_O, "Comment"},{NULL, NULL, 0, NULL} }; notice that Iv replaced METH_VARARGS with METH_O, this means the function only accepts 1 arg and you can use that as a float without using PyArg_ParseTuple - This should be a bit faster too. PyFloat_AsDouble will convert from ints or other non float types that support the PyNumber protocol. I can see why this isnt used for an example because its much less generic. Ali Alhakim wrote: > Hello! > > I'm quite new to Python and definitely a beginner in implementing Python > extensions in C/C++. I've followed the structure given in the formal Python > documentation to write the following code block: > =========== > //cmatmod.c > > #include > > static unsigned int eigenvect_calc(double *min_eps) > { > return 5; > } > > static PyObject *cmat_eigv(PyObject *self, PyObject *args) > { > double *min_eps; > unsigned int m; > if(!PyArg_ParseTuple(args, "d", &min_eps)) > return NULL; > m=eigenvect_calc(min_eps); > return Py_BuildValue("I", m); > } > static PyMethodDef cmat_methods[]= > { > { "eigenvect", cmat_eigv, METH_VARARGS, "Comment"},{NULL, NULL, 0, NULL} > }; > > void initcmat(void) > { > (void) Py_InitModule("cmat", cmat_methods); > } > > =========== > > I have succeeded to build and install this extension using disutils package > in the setup.py file below: > =========== > from distutils.core import setup > from distutils.extension import Extension > setup(name='eigenvect', > version='1.0', > ext_modules=[Extension('cmat', ['cmatmod.c'])], > ) > > ========== > But when I try to call eigenvect(3.0) from Python I would receive a core > dump: > ========== > > 6 [main] python 2336 _cygtls::handle_exceptions: Error while dumping state > (probably corrupted stack) > Segmentation fault (core dumped) > > ========== > My question is what is wrong with the extension code above? Is it something > with reference counting? > I don't know which method is suitable for debugging extension codes. I've > tried gdb but I didn't understand the debug information: > ========== > > (gdb) >>> eigenvect(4.0) > > Program received signal SIGSEGV, Segmentation fault. > ---Type to continue, or q to quit--- > 0x6abb248e in libpython2!PyEval_EvalFrameEx () from > /usr/bin/libpython2.5dll > (gdb) > > ========== > /best regards > > > > > > > > > > > > > > G?? in och titta p?? n??tets roligaste filmer just nu eller ladda upp ditt eget bidrag p?? Spray Crazy. http://crazy.spray.se/ > > > ------------------------------------------------------------------------ > > _______________________________________________ > capi-sig mailing list > capi-sig at python.org > http://mail.python.org/mailman/listinfo/capi-sig -- Campbell J Barton (ideasman42) From python_capi at behnel.de Wed Aug 15 11:15:58 2007 From: python_capi at behnel.de (Stefan Behnel) Date: Wed, 15 Aug 2007 11:15:58 +0200 Subject: [capi-sig] Extension Problem In-Reply-To: <114389462927509@lycos-europe.com> References: <114389462927509@lycos-europe.com> Message-ID: <46C2C44E.9010005@behnel.de> Ali Alhakim wrote: > I'm quite new to Python and definitely a beginner in implementing Python > extensions in C/C++. You might want to take a look at Pyrex or Cython. Both allow you to write C extensions in a very Python-like language. Both use the same language, but the C code that Cython generates is a lot more efficient. http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/ http://www.cython.org/ Stefan