[please always reply to the list]
Jason Baker, 31.05.2010 21:45:
> On Mon, May 31, 2010 at 2:05 PM, Stefan Behnel wrote:
>> Jason Baker, 31.05.2010 18:15:
>>>
>>> I'm working on a Python-to-mzscheme binding using mzscheme's ffi
>>> library (mzscheme's rough equivalent of the Python ctypes library).
Since you didn't provide the link (and "mzscheme ffi" doesn't get me
anything that looks right at first sight), am I right in guessing that you
might be referring to this?
http://download.plt-scheme.org/doc/351/html/foreign/
>>> I'm looking for a way to convert Python objects into Scheme values.
>>> Essentially what I'm trying to do is say "Is this a Python integer?
>>> Ok, convert it to a Scheme integer." or "Is this a Python string?
>>> Ok, convert it into a Scheme string." ... etc.
>>>
>>> What is the best way to do this? My first intuition was to call
>>> Py*_Check to determine the type, but it turns out that's a macro that
>>> can't be used in non-c code. I'm sure I could translate that into the
>>> appropriate C code, but that gives me a bad feeling.
>>
>> Those are macros because that makes them really, really fast, especially in
>> Py3. However, their definition changes between Python versions, so replacing
>> them by regular C code is really not a good idea.
>>
>> In general, I wouldn't try to make the wrapper too generic. You might want
>> to inspect the underlying Scheme code (potentially at runtime), and infer
>> the possible types (or the required conversion) from that.
>
> Perhaps I should clarify. For now, I'm just trying to embed the python
> interpreter in Scheme. Thus, I know what types the scheme values are,
> and I know how to translate them into the appropriate Python values.
> What I'm trying to figure out is how to go the other way. That is,
> how do I figure out what type a PyObject is so I know how to create
> the appropriate Scheme value?
Why not write a type checking cascade in plain C or Cython?
>>> Right now, I'm
>>> looking for simple and easy more than efficient and complete (but I
>>> would also like to know what the efficient and complete approach would
>>> be).
>>
>> Have you considered integrating this with Cython via a thin C bridge,
>> instead of talking to Python's C-API directly? Without knowing anything
>> about the FFI you are using here, I suspect that it likely wouldn't be a
>> generic wrapper in that case. Instead, it would allow users to write
>> specialised and well optimised Scheme wrappers for their specific use case.
>> So far, Cython supports calling into C, C++ and Fortran, where the Fortran
>> wrapper is also implemented as a C-bridge (via fwrap). A similar Scheme
>> binding would allow users to take advantage of Cython's static typing
>> features, so that your code wouldn't have to guess types in the first place.
>
> While I'm sure this approach works for C, C++, and Fortran, I'm afraid
> I don't see how this would apply to Scheme. Scheme is a dynamically
> typed language just like Python. Why do I want a layer of static
> typing in between two dynamically typed languages?
Scheme is a strictly typed language, though, and your Scheme code won't run
with (or even accept) arbitrary Python input value types, just like your
Python code won't run with arbitrary Scheme value types as input. So you
have to draw the line somewhere. And since you are using an FFI, which, I
assume, passes through C anyway, you might just as well restrict your glue
code to suitable types.
Stefan
I'm working on a Python-to-mzscheme binding using mzscheme's ffi
library (mzscheme's rough equivalent of the Python ctypes library).
I'm looking for a way to convert Python objects into Scheme values.
Essentially what I'm trying to do is say "Is this a Python integer?
Ok, convert it to a Scheme integer." or "Is this a Python string?
Ok, convert it into a Scheme string." ... etc.
What is the best way to do this? My first intuition was to call
Py*_Check to determine the type, but it turns out that's a macro that
can't be used in non-c code. I'm sure I could translate that into the
appropriate C code, but that gives me a bad feeling. Right now, I'm
looking for simple and easy more than efficient and complete (but I
would also like to know what the efficient and complete approach would
be).
Can anyone tell me what the best way to tackle this problem is?
In a C program I need to unpickle a Python pickle which is generated by someone's Python program. A Python newbie, I was able to do this, but only by writing a little python script file and loading it as a module. But reading from a script file is fragile, has lots of possible errors to handle as you can see below, and is silly since there's only one line of Python.
I'd therefore like to create the Python module from a string constant, as with PyRun_SimpleString(), instead of reading a file. But I can't find a function like that which returns a value. Or I just don't know how.
Certainly there must be a simpler way to do this...
Thank you,
Jerry Krinock
***** somePython.py *****************************
#!/usr/bin/env python
from pickle import loads
def unpickle(x):
return loads(x)
***** My C "Proof of Concept" Function **********
#include <Python/Python.h> // Running on Mac OS X
char* PythonUnpickle(char* pickle) {
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
char* unpickledString = NULL ;
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\"/Users/jk/Documents/Programming/Python/\")");
pName = PyString_FromString("somePython");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, "unpickle");
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(1);
// Create the argument to unpickle()
pValue = PyString_FromString(pickle);
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return NULL ;
}
// Set the argument into the pArgs tuple
PyTuple_SetItem(pArgs, 0, pValue);
// Run the python unpickle() function, get result pValue
pValue = PyObject_CallObject(pFunc, pArgs) ;
Py_DECREF(pArgs) ;
// Convert the Python string pValue to a C string
if (pValue != NULL) {
unpickledString = PyString_AsString(pValue) ;
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return NULL ;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find 'unpickle' function\n") ;
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load python script file\n");
}
Py_Finalize() ;
return unpickledString ;
}
I'm working on http://bugs.python.org/issue8654 and I'd like to get some
feedback from extension-writers, since it will impact them.
Synopsis of the problem:
If you try to load an extension module that:
- uses any of Python's Unicode functions, and
- was compiled by a Python with the opposite Unicode setting (UCS2 vs UCS4)
then you get an ugly "undefined symbol" error from the linker.
For Python 3, __repr__ must return a Unicode object which means that almost
all extensions will need to call some Unicode functions. It's basically
fruitless to upload a binary egg for Python 3 to PyPi, since it will
generate link errors for a large fraction of downloaders (as I discovered
the hard way).
Proposed solution:
By default, extensions will compile in a "Unicode-agnostic" mode, where
Py_UNICODE is an incomplete type. The extension's code can pass Py_UNICODE
pointers back and forth between Python API functions, but it cannot
dereference them nor use sizeof(Py_UNICODE). Unicode-agnostic modules will
load and run in both UCS2 and UCS4 interpreters. Most extensions fall into
this category.
If a module needs to dereference Py_UNICODE, it can define
PY_REAL_PY_UNICODE before including Python.h to make Py_UNICODE a complete
type, .Attempting to load such a module into a mismatched interpreter will
cause an ImportError (instead of an ugly linker error). If an extension
uses PY_REAL_PY_UNICODE in any .c file, it must also use it in the .c file
that calls PyModule_Create to ensure the Unicode width is stored in the
module's information.
I have two questions for the greater community:
1) Do you have any fundamental concerns with this design?
2) Would you prefer the default be reversed? i.e, that Py_UNICODE be a
complete type by default, and an extension must have a #define to compile in
Unicode-agnostic mode?
--
Daniel Stutzbach, Ph.D.
President, Stutzbach Enterprises, LLC <http://stutzbachenterprises.com>
Hello.
I'd like to do some ML-like type inference for Python code. I'm not trying to resurrect the static typing vs. dynamic typing debate here. It's simply that I'd need to get static typing for Python for code-generation reasons.
Therefore, I'd like to ask: Does the Python C API support a way to inspect the bytecode or the source code of a given piece of Python code? What approach would be promising enough to type things in ML-way (I'm unfortunately not interested in cartesian-product type inference), and what help may the C API provide to meet this goal? (Maybe I haven't looked far enough, but I could not discern clearly what could be useful...)
(Sorry for posting in non-text-mode. Using a webmail because port 25 policies in this bloody country ar sooooo restrictive.)
Thanks.
Issyk Kol.
Hi,
what am I doing wrong?
C code:
--------------
static PyObject *is_prime(PyObject *self, PyObject *value)
{
if (!PyInt_Check(value)) {
PyErr_SetString(PyExc_TypeError, "only integers are acceptable");
return NULL;
}
--------------
Test (I'm using integer 3):
------------
>>> primes.is_prime(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: only integers are acceptable
-------------
Thanks
I am getting a SIGABRT
PyImport_GetModuleDict: no module dictionary!"
this is the code.
I need a InterpreterState because I need to create new threads using
pthread and clone the existing state.
Does PyInterpreterState_New, create a fulling initalized IS?
Does PyThreadState_New clone the existing state or a clean new one?
Py_Initialize();
is = PyInterpreterState_New();
if ( is == NULL ) {
fclose ( maa->pFILE);
free( maa );
return -2;
}
maa->is = is;
PyEval_InitThreads();
ts = PyThreadState_New(is);
PyThreadState_Swap( ts );
ts = PyThreadState_Get();
maa->ts = ts;
PyImport_ImportModule( "sys" );
EXPY is an express way to extend Python!
EXPY provides a way to extend python in an elegant way. For more information and a tutorial, see: http://expy.sourceforge.net/
What's new:
1. Special methods can now take @throws decorators.
2. Added convenience macros <type>_NEW and <type>_CheckExact for extension types.
3. Give warnings of missing Py_INCREF on all methods/functions returning an object.
4. And the responsibility of Py_INCREF is left for the developer.
5. Documentation update.
Cheers,
Yingjie