summaryrefslogtreecommitdiff
path: root/pyuno/source/module
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2012-11-25 15:59:18 +0100
committerMichael Stahl <mstahl@redhat.com>2012-11-25 16:06:40 +0100
commitaf2b7fac27aa812229c6611fd35a77aa51b290f2 (patch)
tree517f99b3235c50a1ff046438b7344d7ad70861eb /pyuno/source/module
parenta38b59265c08276fce6d73ce541cadb41aa6d347 (diff)
pyuno: fix handling of "str", "unicode", "bytes" types:
Replace currrent wrappers of Python 2 only PyString_* functions with better abstractions that handle default "str" (PyStr_*) or byte strings ("str"/"bytes" depending on version, PyStrBytes_*) and adjust all invocations to work on appropriate string types. Fixes obvious "attributes typeName and/or value of uno.Enum are not strings" exceptions with Python 3. Change-Id: I255dcb1bc198fd7f6a62b83b957901521071a480
Diffstat (limited to 'pyuno/source/module')
-rw-r--r--pyuno/source/module/pyuno.cxx2
-rw-r--r--pyuno/source/module/pyuno_adapter.cxx2
-rw-r--r--pyuno/source/module/pyuno_impl.hxx76
-rw-r--r--pyuno/source/module/pyuno_module.cxx29
-rw-r--r--pyuno/source/module/pyuno_runtime.cxx18
-rw-r--r--pyuno/source/module/pyuno_type.cxx22
-rw-r--r--pyuno/source/module/pyuno_util.cxx16
7 files changed, 104 insertions, 61 deletions
diff --git a/pyuno/source/module/pyuno.cxx b/pyuno/source/module/pyuno.cxx
index 17507bddd6e2..18d2f9d56606 100644
--- a/pyuno/source/module/pyuno.cxx
+++ b/pyuno/source/module/pyuno.cxx
@@ -428,7 +428,7 @@ PyObject *PyUNO_str( PyObject * self )
buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
}
- return PyString_FromString( buf.getStr());
+ return PyStr_FromString( buf.getStr());
}
PyObject* PyUNO_getattr (PyObject* self, char* name)
diff --git a/pyuno/source/module/pyuno_adapter.cxx b/pyuno/source/module/pyuno_adapter.cxx
index beb2d04707e0..35b6ce46fe07 100644
--- a/pyuno/source/module/pyuno_adapter.cxx
+++ b/pyuno/source/module/pyuno_adapter.cxx
@@ -242,7 +242,7 @@ Any Adapter::invoke( const OUString &aFunctionName,
buf.appendAscii( "pyuno::Adapater: Method " ).append( aFunctionName );
buf.appendAscii( " is not implemented at object " );
PyRef str( PyObject_Repr( mWrappedObject.get() ), SAL_NO_ACQUIRE );
- buf.appendAscii( PyString_AsString( str.get() ));
+ buf.append(pyString2ustring(str.get()));
throw IllegalArgumentException( buf.makeStringAndClear(), Reference< XInterface > (),0 );
}
diff --git a/pyuno/source/module/pyuno_impl.hxx b/pyuno/source/module/pyuno_impl.hxx
index 601673d06b11..e794c9d40738 100644
--- a/pyuno/source/module/pyuno_impl.hxx
+++ b/pyuno/source/module/pyuno_impl.hxx
@@ -49,44 +49,78 @@
// In Python 3, the PyString_* functions have been replaced by PyBytes_*
// and PyUnicode_* functions.
#if PY_MAJOR_VERSION >= 3
-inline char* PyString_AsString(PyObject *object)
+
+// compatibility wrappers for Python "str" type (PyUnicode in 3, PyString in 2)
+inline PyObject* PyStr_FromString(const char *string)
{
- // check whether object is already of type "PyBytes"
- if(PyBytes_Check(object))
- {
- return PyBytes_AsString(object);
- }
-
- // object is not encoded yet, so encode it to utf-8
- PyObject *pystring;
- pystring = PyUnicode_AsUTF8String(object);
- if(!pystring)
- {
- PyErr_SetString(PyExc_ValueError, "cannot utf-8 decode string");
- return 0;
- }
- return PyBytes_AsString(pystring);
+ return PyUnicode_FromString(string);
}
-inline PyObject* PyString_FromString(const char *string)
+inline char * PyStr_AsString(PyObject *object)
{
- return PyUnicode_FromString(string);
+ return PyUnicode_AsUTF8(object);
}
-inline int PyString_Check(PyObject *object)
+inline int PyStr_Check(PyObject *object)
+{
+ return PyUnicode_Check(object);
+}
+
+// compatibility wrappers for Python non-Unicode string/buffer type
+// (PyBytes in 3, PyString in 2)
+inline int PyStrBytes_Check(PyObject *object)
{
return PyBytes_Check(object);
}
-inline Py_ssize_t PyString_Size(PyObject *object)
+inline char* PyStrBytes_AsString(PyObject *object)
+{
+ return PyBytes_AsString(object);
+}
+
+inline Py_ssize_t PyStrBytes_Size(PyObject *object)
{
return PyBytes_Size(object);
}
-inline PyObject* PyString_FromStringAndSize(const char *string, Py_ssize_t len)
+inline PyObject* PyStrBytes_FromStringAndSize(const char *string, Py_ssize_t len)
{
return PyBytes_FromStringAndSize(string, len);
}
+#else
+inline char * PyStr_AsString(PyObject *object)
+{
+ return PyString_AsString(object);
+}
+
+inline PyObject* PyStr_FromString(const char *string)
+{
+ return PyString_FromString(string);
+}
+
+inline int PyStr_Check(PyObject *object)
+{
+ return PyString_Check(object);
+}
+inline int PyStrBytes_Check(PyObject *object)
+{
+ return PyString_Check(object);
+}
+
+inline char* PyStrBytes_AsString(PyObject *object)
+{
+ return PyString_AsString(object);
+}
+
+inline Py_ssize_t PyStrBytes_Size(PyObject *object)
+{
+ return PyString_Size(object);
+}
+
+inline PyObject* PyStrBytes_FromStringAndSize(const char *string, Py_ssize_t len)
+{
+ return PyString_FromStringAndSize(string, len);
+}
#endif /* PY_MAJOR_VERSION >= 3 */
namespace pyuno
diff --git a/pyuno/source/module/pyuno_module.cxx b/pyuno/source/module/pyuno_module.cxx
index bd592e302944..bd73c0bda544 100644
--- a/pyuno/source/module/pyuno_module.cxx
+++ b/pyuno/source/module/pyuno_module.cxx
@@ -169,7 +169,9 @@ static void fillStruct(
for( int i = 0 ; i < nMembers ; i ++ )
{
const OUString OUMemberName (pCompType->ppMemberNames[i]);
- PyObject *pyMemberName = PyString_FromString(::rtl::OUStringToOString( OUMemberName, RTL_TEXTENCODING_UTF8 ).getStr());
+ PyObject *pyMemberName =
+ PyStr_FromString(::rtl::OUStringToOString(OUMemberName,
+ RTL_TEXTENCODING_UTF8).getStr());
if ( PyObject *element = PyDict_GetItem(kwinitializer, pyMemberName ) )
{
state.setInitialised(OUMemberName);
@@ -333,7 +335,7 @@ PyObject * extractOneStringArg( PyObject *args, char const *funcName )
return NULL;
}
PyObject *obj = PyTuple_GetItem( args, 0 );
- if(!PyString_Check(obj) && !PyUnicode_Check(obj))
+ if (!PyStr_Check(obj) && !PyUnicode_Check(obj))
{
OStringBuffer buf;
buf.append( funcName ).append( ": expecting one string argument" );
@@ -356,13 +358,11 @@ static PyObject *createUnoStructHelper(
PyObject *structName = PyTuple_GetItem(args, 0);
PyObject *initializer = PyTuple_GetItem(args, 1);
- // Perhaps in Python 3, only PyUnicode_Check returns true and
- // in Python 2, only PyString_Check returns true.
- if(PyString_Check(structName) || PyUnicode_Check(structName))
+ if (PyStr_Check(structName))
{
if( PyTuple_Check( initializer ) && PyDict_Check ( keywordArgs ) )
{
- OUString typeName( OUString::createFromAscii(PyString_AsString(structName)));
+ OUString typeName( OUString::createFromAscii(PyStr_AsString(structName)));
RuntimeCargo *c = runtime.getImpl()->cargo;
Reference<XIdlClass> idl_class ( c->xCoreReflection->forName (typeName),UNO_QUERY);
if (idl_class.is ())
@@ -394,7 +394,7 @@ static PyObject *createUnoStructHelper(
{
OStringBuffer buf;
buf.append( "UNO struct " );
- buf.append( PyString_AsString(structName) );
+ buf.append( PyStr_AsString(structName) );
buf.append( " is unkown" );
PyErr_SetString (PyExc_RuntimeError, buf.getStr());
}
@@ -571,9 +571,7 @@ static PyObject *getClass( SAL_UNUSED_PARAMETER PyObject *, PyObject *args )
try
{
Runtime runtime;
- PyRef ret = getClass(
- OUString( PyString_AsString( obj), strlen(PyString_AsString(obj)),RTL_TEXTENCODING_ASCII_US),
- runtime );
+ PyRef ret = getClass(pyString2ustring(obj), runtime);
Py_XINCREF( ret.get() );
return ret.get();
}
@@ -706,9 +704,9 @@ static PyObject * invoke(SAL_UNUSED_PARAMETER PyObject *, PyObject *args)
{
PyObject *object = PyTuple_GetItem(args, 0);
PyObject *item1 = PyTuple_GetItem(args, 1);
- if(PyString_Check(item1) || PyUnicode_Check(item1))
+ if (PyStr_Check(item1))
{
- const char *name = PyString_AsString(item1);
+ const char *name = PyStr_AsString(item1);
PyObject *item2 = PyTuple_GetItem(args, 2);
if(PyTuple_Check(item2))
{
@@ -718,7 +716,7 @@ static PyObject * invoke(SAL_UNUSED_PARAMETER PyObject *, PyObject *args)
{
OStringBuffer buf;
buf.append("uno.invoke expects a tuple as 3rd argument, got ");
- buf.append(PyString_AsString(PyObject_Str(item2)));
+ buf.append(PyStr_AsString(PyObject_Str(item2)));
PyErr_SetString(
PyExc_RuntimeError, buf.makeStringAndClear().getStr());
}
@@ -727,7 +725,7 @@ static PyObject * invoke(SAL_UNUSED_PARAMETER PyObject *, PyObject *args)
{
OStringBuffer buf;
buf.append("uno.invoke expected a string as 2nd argument, got ");
- buf.append(PyString_AsString(PyObject_Str(item1)));
+ buf.append(PyStr_AsString(PyObject_Str(item1)));
PyErr_SetString(
PyExc_RuntimeError, buf.makeStringAndClear().getStr());
}
@@ -780,7 +778,8 @@ static PyObject *setCurrentContext(
{
OStringBuffer buf;
buf.append( "uno.setCurrentContext expects an XComponentContext implementation, got " );
- buf.append( PyString_AsString( PyObject_Str( PyTuple_GetItem( args, 0) ) ) );
+ buf.append(
+ PyStr_AsString(PyObject_Str(PyTuple_GetItem(args, 0))));
PyErr_SetString(
PyExc_RuntimeError, buf.makeStringAndClear().getStr() );
}
diff --git a/pyuno/source/module/pyuno_runtime.cxx b/pyuno/source/module/pyuno_runtime.cxx
index 2ad74169cc8e..6e282a73793a 100644
--- a/pyuno/source/module/pyuno_runtime.cxx
+++ b/pyuno/source/module/pyuno_runtime.cxx
@@ -162,8 +162,8 @@ static PyRef importUnoModule( ) throw ( RuntimeException )
OUStringBuffer buf;
buf.appendAscii( "python object raised an unknown exception (" );
PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE );
- buf.appendAscii( PyString_AsString( valueRep.get())).appendAscii( ", traceback follows\n" );
- buf.appendAscii( PyString_AsString( str.get() ) );
+ buf.appendAscii( PyStr_AsString( valueRep.get())).appendAscii( ", traceback follows\n" );
+ buf.appendAscii( PyStr_AsString( str.get() ) );
buf.appendAscii( ")" );
throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
}
@@ -613,7 +613,7 @@ lcl_ExceptionMessage(PyObject *const o, OUString const*const pWrapped)
OUStringBuffer buf;
buf.appendAscii("Couldn't convert ");
PyRef reprString( PyObject_Str(o), SAL_NO_ACQUIRE );
- buf.appendAscii( PyString_AsString(reprString.get()) );
+ buf.appendAscii( PyStr_AsString(reprString.get()) );
buf.appendAscii(" to a UNO type");
if (pWrapped)
{
@@ -719,7 +719,7 @@ Any Runtime::pyObject2Any ( const PyRef & source, enum ConversionMode mode ) con
double d = PyFloat_AsDouble (o);
a <<= d;
}
- else if (PyString_Check(o) || PyUnicode_Check(o))
+ else if (PyStrBytes_Check(o) || PyUnicode_Check(o))
{
a <<= pyString2ustring(o);
}
@@ -740,10 +740,10 @@ Any Runtime::pyObject2Any ( const PyRef & source, enum ConversionMode mode ) con
{
PyRef str(PyObject_GetAttrString( o , "value" ),SAL_NO_ACQUIRE);
Sequence< sal_Int8 > seq;
- if( PyString_Check( str.get() ) )
+ if( PyStrBytes_Check( str.get() ) )
{
seq = Sequence<sal_Int8 > (
- (sal_Int8*) PyString_AsString(str.get()), PyString_Size(str.get()));
+ (sal_Int8*) PyStrBytes_AsString(str.get()), PyStrBytes_Size(str.get()));
}
a <<= seq;
}
@@ -916,7 +916,7 @@ Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue,
PyRef args( PyTuple_New( 1), SAL_NO_ACQUIRE );
PyTuple_SetItem( args.get(), 0, excTraceback.getAcquired() );
PyRef pyStr( PyObject_CallObject( extractTraceback.get(),args.get() ), SAL_NO_ACQUIRE);
- str = rtl::OUString::createFromAscii( PyString_AsString(pyStr.get()) );
+ str = rtl::OUString::createFromAscii( PyStr_AsString(pyStr.get()) );
}
else
{
@@ -951,7 +951,7 @@ Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue,
PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE );
if( typeName.is() )
{
- buf.appendAscii( PyString_AsString( typeName.get() ) );
+ buf.appendAscii( PyStr_AsString( typeName.get() ) );
}
else
{
@@ -961,7 +961,7 @@ Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue,
PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE );
if( valueRep.is() )
{
- buf.appendAscii( PyString_AsString( valueRep.get()));
+ buf.appendAscii( PyStr_AsString( valueRep.get()));
}
else
{
diff --git a/pyuno/source/module/pyuno_type.cxx b/pyuno/source/module/pyuno_type.cxx
index 1ea9a897ac29..d30e07dd0f83 100644
--- a/pyuno/source/module/pyuno_type.cxx
+++ b/pyuno/source/module/pyuno_type.cxx
@@ -162,15 +162,15 @@ Any PyEnum2Enum( PyObject *obj ) throw ( RuntimeException )
Any ret;
PyRef typeName( PyObject_GetAttrString( obj,"typeName" ), SAL_NO_ACQUIRE);
PyRef value( PyObject_GetAttrString( obj, "value" ), SAL_NO_ACQUIRE);
- if( !PyString_Check( typeName.get() ) || ! PyString_Check( value.get() ) )
+ if( !PyStr_Check( typeName.get() ) || ! PyStr_Check( value.get() ) )
{
throw RuntimeException(
USTR_ASCII( "attributes typeName and/or value of uno.Enum are not strings" ),
Reference< XInterface > () );
}
- OUString strTypeName( OUString::createFromAscii( PyString_AsString( typeName.get() ) ) );
- char *stringValue = PyString_AsString( value.get() );
+ OUString strTypeName( OUString::createFromAscii( PyStr_AsString( typeName.get() ) ) );
+ char *stringValue = PyStr_AsString( value.get() );
TypeDescription desc( strTypeName );
if( desc.is() )
@@ -200,7 +200,7 @@ Any PyEnum2Enum( PyObject *obj ) throw ( RuntimeException )
{
OUStringBuffer buf;
buf.appendAscii( "value " ).appendAscii( stringValue ).appendAscii( "is unknown in enum " );
- buf.appendAscii( PyString_AsString( typeName.get() ) );
+ buf.appendAscii( PyStr_AsString( typeName.get() ) );
throw RuntimeException( buf.makeStringAndClear(), Reference<XInterface> () );
}
ret = Any( &pEnumDesc->pEnumValues[i], desc.get()->pWeakRef );
@@ -208,7 +208,7 @@ Any PyEnum2Enum( PyObject *obj ) throw ( RuntimeException )
else
{
OUStringBuffer buf;
- buf.appendAscii( "enum " ).appendAscii( PyString_AsString(typeName.get()) ).appendAscii( " is unknown" );
+ buf.appendAscii( "enum " ).appendAscii( PyStr_AsString(typeName.get()) ).appendAscii( " is unknown" );
throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
}
return ret;
@@ -218,7 +218,7 @@ Any PyEnum2Enum( PyObject *obj ) throw ( RuntimeException )
Type PyType2Type( PyObject * o ) throw(RuntimeException )
{
PyRef pyName( PyObject_GetAttrString( o, "typeName" ), SAL_NO_ACQUIRE);
- if( !PyString_Check( pyName.get() ) )
+ if( !PyStr_Check( pyName.get() ) )
{
throw RuntimeException(
USTR_ASCII( "type object does not have typeName property" ),
@@ -228,7 +228,7 @@ Type PyType2Type( PyObject * o ) throw(RuntimeException )
PyRef pyTC( PyObject_GetAttrString( o, "typeClass" ), SAL_NO_ACQUIRE );
Any enumValue = PyEnum2Enum( pyTC.get() );
- OUString name( OUString::createFromAscii( PyString_AsString( pyName.get() ) ) );
+ OUString name( OUString::createFromAscii( PyStr_AsString( pyName.get() ) ) );
TypeDescription desc( name );
if( ! desc.is() )
{
@@ -271,8 +271,8 @@ static PyObject* callCtor( const Runtime &r , const char * clazz, const PyRef &
PyObject *PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r )
{
PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE );
- PyTuple_SetItem( args.get() , 0 , PyString_FromString( enumBase ) );
- PyTuple_SetItem( args.get() , 1 , PyString_FromString( enumValue ) );
+ PyTuple_SetItem( args.get() , 0 , PyStr_FromString( enumBase ) );
+ PyTuple_SetItem( args.get() , 1 , PyStr_FromString( enumValue ) );
return callCtor( r, "Enum" , args );
}
@@ -283,7 +283,7 @@ PyObject* PyUNO_Type_new (const char *typeName , TypeClass t , const Runtime &r
// retrieve type object
PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE );
- PyTuple_SetItem( args.get() , 0 , PyString_FromString( typeName ) );
+ PyTuple_SetItem( args.get() , 0 , PyStr_FromString( typeName ) );
PyObject *typeClass = PyUNO_Enum_new( "com.sun.star.uno.TypeClass" , typeClassToString(t), r );
if( ! typeClass )
return NULL;
@@ -309,7 +309,7 @@ PyObject *PyUNO_ByteSequence_new(
const com::sun::star::uno::Sequence< sal_Int8 > &byteSequence, const Runtime &r )
{
PyRef str(
- PyString_FromStringAndSize( (char*)byteSequence.getConstArray(), byteSequence.getLength()),
+ PyStrBytes_FromStringAndSize( (char*)byteSequence.getConstArray(), byteSequence.getLength()),
SAL_NO_ACQUIRE );
PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
PyTuple_SetItem( args.get() , 0 , str.getAcquired() );
diff --git a/pyuno/source/module/pyuno_util.cxx b/pyuno/source/module/pyuno_util.cxx
index 88136b312adb..9f058ef3f35e 100644
--- a/pyuno/source/module/pyuno_util.cxx
+++ b/pyuno/source/module/pyuno_util.cxx
@@ -69,7 +69,7 @@ PyRef ustring2PyUnicode( const OUString & str )
PyRef ustring2PyString( const OUString &str )
{
OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
- return PyRef( PyString_FromString( o.getStr() ), SAL_NO_ACQUIRE );
+ return PyRef( PyStr_FromString( o.getStr() ), SAL_NO_ACQUIRE );
}
OUString pyString2ustring( PyObject *pystr )
@@ -80,14 +80,24 @@ OUString pyString2ustring( PyObject *pystr )
#if Py_UNICODE_SIZE == 2
ret = OUString( (sal_Unicode * ) PyUnicode_AS_UNICODE( pystr ) );
#else
+#if PY_MAJOR_VERSION >= 3
+ Py_ssize_t size(0);
+ char *pUtf8(PyUnicode_AsUTF8AndSize(pystr, &size));
+ ret = OUString(pUtf8, size, RTL_TEXTENCODING_UTF8);
+#else
PyObject* pUtf8 = PyUnicode_AsUTF8String(pystr);
- ret = OUString(PyString_AsString(pUtf8), PyString_Size(pUtf8), RTL_TEXTENCODING_UTF8);
+ ret = OUString(PyStr_AsString(pUtf8), PyStr_Size(pUtf8), RTL_TEXTENCODING_UTF8);
Py_DECREF(pUtf8);
#endif
+#endif
}
else
{
- char *name = PyString_AsString(pystr );
+#if PY_MAJOR_VERSION >= 3
+ char *name = PyBytes_AsString(pystr); // hmmm... is this a good idea?
+#else
+ char *name = PyString_AsString(pystr);
+#endif
ret = OUString( name, strlen(name), osl_getThreadTextEncoding() );
}
return ret;