static inline std::string convert(const TypeCode *t,PyObject* o,void*)
{
std::string s;
- if (PyBytes_Check(o))
- s= PyBytes_AS_STRING(o);
+ if (PyUnicode_Check(o))
+ {
+ Py_ssize_t size;
+ char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
+ if (!ptr)
+ throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
+ s.assign(ptr, size);
+ }
else
{
stringstream msg;
{
static inline std::string convert(const TypeCode *t,PyObject* o,void*,int protocol)
{
- if (PyBytes_Check(o) && strncmp(t->id(),"python",6)!=0)
+ if (PyUnicode_Check(o) && strncmp(t->id(),"python",6)!=0)
{
// the objref is used by Python as a string (prefix:value) keep it as a string
- return PyBytes_AS_STRING(o);
+ Py_ssize_t size;
+ std::string s;
+ char *ptr = PyUnicode_AsUTF8AndSize(o, &size);
+ if (!ptr)
+ throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
+ s.assign(ptr, size);
+ return s;
}
if(strncmp(t->id(),"python",6)==0)
{
// It's a native Python object pickle it
PyObject* mod=PyImport_ImportModule("pickle");
PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",o,protocol);
- DEBTRACE(PyObject_REPR(pickled) );
+ DEBTRACE(PyObject_Repr(pickled) );
Py_DECREF(mod);
if(pickled==NULL)
{
PyErr_Print();
throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl");
}
- std::string mystr=PyBytes_AsString(pystring);
+ Py_ssize_t size;
+ std::string mystr;
+ char *ptr = PyUnicode_AsUTF8AndSize(pystring, &size);
+ if (!ptr)
+ throw YACS::ENGINE::ConversionException("Conversion from PyUnicode to string failed");
+ mystr.assign(ptr, size);
Py_DECREF(pystring);
return mystr;
}
{
static inline PyObject* convert(const TypeCode *t,std::string& o)
{
- return PyBytes_FromString(o.c_str());
+ return PyUnicode_FromString(o.c_str());
}
};
template <>
if(t->isA(Runtime::_tc_file))
{
//It's an objref file. Convert it specially
- return PyBytes_FromString(o.c_str());
+ return PyUnicode_FromString(o.c_str());
}
- if(strncmp(t->id(),"python",6)==0)
+ if(strncmp(t->id(),"python",6)==0) //ex: "python:obj:1.0"
{
//It's a python pickled object, unpickled it
PyObject* mod=PyImport_ImportModule("pickle");
- PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"s#",o.c_str(),o.length());
- DEBTRACE(PyObject_REPR(ob));
+ PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",o.c_str(),o.length());
+ DEBTRACE(PyObject_Repr(ob));
Py_DECREF(mod);
if(ob==NULL)
{
PyErr_Print();
throw YACS::ENGINE::ConversionException("Problem in convertToYacsObjref<PYTHONImpl: no simplejson module");
}
- PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"s",o.c_str());
+ PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y",o.c_str());
Py_DECREF(mod);
if(ob==NULL)
{
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject* mod=PyImport_ImportModule("pickle");
- PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"s#",s,buffer->length());
+ PyObject *ob=PyObject_CallMethod(mod,(char *)"loads",(char *)"y#",s,buffer->length());
PyObject *pickled=PyObject_CallMethod(mod,(char *)"dumps",(char *)"Oi",ob,protocol);
- DEBTRACE(PyObject_REPR(pickled));
+ DEBTRACE(PyObject_Repr(pickled));
std::string mystr=PyBytes_AsString(pickled);
Py_DECREF(mod);
Py_DECREF(ob);
{
PyObject *s;
PyGILState_STATE gstate = PyGILState_Ensure();
+ // TODO: separate treatment for string (maybe with bad encoding?) and other types of PyObject ?
+ // Do we need str() or repr() and what are the possible causes of failure of str() ?
+ // not clear, needs more analysis.
s=PyObject_Str(ob);
- std::string ss(PyBytes_AsString(s),PyBytes_Size(s));
+ if (s == NULL) // for instance string with bad encoding, non utf-8
+ {
+ s=PyObject_ASCII(ob); // escape non ASCII characters and like repr(), which is not the same as str()...
+ }
+ Py_ssize_t size;
+ char* characters=PyUnicode_AsUTF8AndSize(s, &size);
+ std::string ss( characters, size);
Py_DECREF(s);
PyGILState_Release(gstate);
return ss;
template<>
inline bool checkString<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
{
- if (PyBytes_Check(o))
+ if (PyUnicode_Check(o))
return true;
else
{
template<>
inline bool checkObjref<PYTHONImpl,PyObject*,void*>(const TypeCode *t,PyObject* o,void* aux)
{
- if (PyBytes_Check(o))
+ if (PyUnicode_Check(o))
return true;
if(strncmp(t->id(),"python",6)==0) // a Python object is expected (it's always true)
return true;