- Translations
- Introduction
- State
- Download
- Tutorial
-- PyUNO Installation
-- PyUNO Bridge Modes
-- More examples
- UNO language binding
-- UNO type mapping
-- Implementing UNO objects
-- Implementing UNO components
-- Out parameter handling
-- Exception handling
-- unohelper module
- Dependencies
- Bootstrapping in non-OOo environments
- Building from source
- Replacing the python runtime
- Support for the new scripting framework
- External references
- FAQ (read this FIRST when you have problems)
- Authors
Translations
Find
here
a shortened spanish version of this document.
Introduction
The Python-UNO bridge allows to use the standard OpenOffice.org API from
the well known python scripting language. It addtionally allows to develop UNO components
in python, thus python UNO components may be run within the office process and
e.g. can be called
from Java, C++ or the built in StarBasic scripting language.
You should find the most current version of this document at
http://udk.openoffice.org/python/python-bridge.html
Download
You can download this documentation including examples
and support for the new scripting-framework
for offline work.
Download pyuno-doc.zip ( less than 0.5 MB).
State
The Python-UNO bridge is feature complete, but has not been used by many people up to now, so it may contain some bugs. It is now integrated in the OpenOffice.org 1.1 source tree. It does not run with the OpenOffice.org 1.0.x source tree.
The documentation in its current state is targeted at developers, who
have already some experience with OpenOffice.org API and with some other
programming language (Java/C++/StarBasic). If you are a newbie and you think,
that some background information is missing, you should try the
developer manual mentioned in the external reference section.
PyUNO tutorial for OpenOffice
This tutorial shows, how the PyUNO bridge
can be used to automate OpenOffice. This is not an OpenOffice tutorial,
there is lots of resources available in the office development kit and
the developer manual.
PyUNO Installation
With OpenOffice1.1RC4 and higher, PyUNO is included in the default installation. You
can skip to the next paragraph.
When you use OpenOffice1.1RC3 or earlier, the PyUNO-Bridge must be explicitly selected during OOo installation. Choose therefor customized setup,
and activate the PyUNO bridge in the Optional Components section
You can also install PyUNO after the initial installation by starting setup
within the office installation and selecting Modify
in the upcoming
dialog.
Note: When you choose the install
script
(e.g. install --prefix=/usr/local
) for installation, you can
only activate pyuno after the installation by starting setup /net
and choosing Modify. Note, that in OOorc2, there is a bug which does not install
two .ini files as they should in this case.
PyUNO bridge modes
PyUNO can be used in two different modes
Use this mode, when you
Make sure, that the office doesn't run (note that on windows you must also terminate the quickstarter in the system tray at the right bottom of your desktop). Start a system shell ( cmd on Win NT/2000/XP, command on Win9x, tcsh or bash on unix). Switch to the Office program directory (e.g. C:\Program Files\OpenOffice.org1.1\program ) and start the office with the following command line parameters
c:\Program Files\OpenOffice1.1\program> soffice "-accept=socket,host=localhost,port=2002;urp;" |
Now use your favourite text editor to create the following hello_world.py sample program:
import uno # get the uno component context from the PyUNO runtime localContext = uno.getComponentContext() # create the UnoUrlResolver resolver = localContext.ServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", localContext ) # connect to the running office ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" ) smgr = ctx.ServiceManager # get the central desktop object desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx) # access the current writer document model = desktop.getCurrentComponent() # access the document's text property text = model.Text # create a cursor cursor = text.createTextCursor() # insert the text into the document text.insertString( cursor, "Hello World", 0 ) # Do a nasty thing before exiting the python process. In case the # last call is a oneway call (e.g. see idl-spec of insertString), # it must be forced out of the remote-bridge caches before python # exits the process. Otherwise, the oneway call may or may not reach # the target object. # I do this here by calling a cheap synchronous call (getPropertyValue). ctx.ServiceManager |
Now start the above script with the python script located in the program directory
c:\Program Files\OpenOffice1.1\program> .\python hello_world.py |
This scripts prints "Hello World" into the current writer document.
Use this mode, when
hello_world_comp.py:
import uno import unohelper from com.sun.star.task import XJobExecutor # implement a UNO component by deriving from the standard unohelper.Base class # and from the interface(s) you want to implement. class HelloWorldJob( unohelper.Base, XJobExecutor ): def __init__( self, ctx ): # store the component context for later use self.ctx = ctx def trigger( self, args ): # note: args[0] == "HelloWorld", see below config settings # retrieve the desktop object desktop = self.ctx.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", self.ctx ) # get current document model model = desktop.getCurrentComponent() # access the document's text property text = model.Text # create a cursor cursor = text.createTextCursor() # insert the text into the document text.insertString( cursor, "Hello World", 0 ) # pythonloader looks for a static g_ImplementationHelper variable g_ImplementationHelper = unohelper.ImplementationHelper() # g_ImplementationHelper.addImplementation( \ HelloWorldJob, # UNO object class "org.openoffice.comp.pyuno.demo.HelloWorld", # implemenation name # Change this name for your own # script ("com.sun.star.task.Job",),) # list of implemented services # (the only service) |
The code needs to be linked to a user event. This can be done e.g. with the following configuration settings :
Addons.xcu:
<?xml version="1.0" encoding="UTF-8"?> <oor:node xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Addons" oor:package="org.openoffice.Office"> <node oor:name="AddonUI"> <node oor:name="AddonMenu"> <node oor:name="org.openoffice.comp.pyuno.demo.HelloWorld" oor:op="replace"> <prop oor:name="URL" oor:type="xs:string"> <value>service:org.openoffice.comp.pyuno.demo.HelloWorld?insert</value> </prop> <prop oor:name="ImageIdentifier" oor:type="xs:string"> <value>private:image/3216</value> </prop> <prop oor:name="Title" oor:type="xs:string"> <value xml:lang="en-US">Insert Hello World</value> </prop> </node> </node> </node> </oor:node> |
zip hello_world.zip Addons.xcu hello_world_comp.py adding: Addons.xcu (deflated 55%) adding: hello_world_comp.py (deflated 55%) |
pkgchk
tool, which is located in the OOo program directory. Note,
that the office must have been terminated before.
Note: Make sure, that the PYTHONPATH environment variable is NOT set when you start pkgchk or soffice (see #i17339#). This may require, that you create a batch file for soffice on windows, unset PYTHONPATH in the system configuration or always start soffice from the shell with set PYTHONPATH= (windows) or unsetenv PYTHONPATH (unix tcsh shell).
c:\Program Files\OpenOffice.org1.1\program> pkgchk hello_world.zip c:\Program Files\OpenOffice.org1.1\program> |
Tools/Addtional Components/Insert Hello World
).
You must add the swritercomp.py program with the pkgchk tool (see below) to the office installation and can then use the swritercomp_client.py program to execute it.
IDL datatype | representation in python | ||
---|---|---|---|
integer types (byte, short, unsigned short, long, unsigned long, hyper, unsigned hyper |
Python internally knows only the C datatypes long and long long as integer types.
On most machines, a long is a 32 bit value while long long is a 64 bit value.
|
boolean | Python internally has a boolean data type, which is derived from the
integer type ( see
http://python.org/peps/pep-0285.html
). There exists the singletons True and
False , which pyuno uses to distinguish between integers
and boolean values.
As long as a boolean is specified in the interface method signature, you may also use numbers. In the following example, all calls are valid:
True
or False .
Note: There also exists the uno.Bool class, which is deprecated since pyuno 0.9.2, but still supported. Don't use it anymore. |
string | In general, the string is mapped to the python unicode string. However, you may pass an
8 bit python string where a UNO string is expected, the bridge converts the
8 bit string to a unicode string using the system locale.
|
||
char |
A char is mapped to a uno.Char . It has a public unicode string member value
with length 1 containing the unicode char.
|
||
enum | A concrete enum value is represented by an instance of the class uno.Enum . It has
two members, typeName is a string containing the name of the enum type and
value |
||
type | A type is mapped to a uno.Type . It has public members typeName (string) and
typeClass (enum value of com.sun.star.uno.TypeClass).
There exists a function uno.getTypeByName() to easily
create a type instance, the functions raises a RuntimeException in case the
type is unknown.
You may create concrete type values in two ways
|
||
struct (and exception) |
For each UNO struct (or exception), a new python class is generated on the fly. It
is guaranteed, that there is only one instance of the struct (or exception) class per
python interpreter instance. The generated class does reflect the inheritance
hierarchy of the conrete UNO type (e.g. important for exception handling, see below).
One can generate a struct class by using the import mechanism. An instance of a struct can then be instantiated by using the python constructor. The constructor supports zero arguments (members get default constructed), 1 argument which the same type (copy constructor), and n arguments, where n is the number of elements of the concrete struct. The struct supports the equality operator, two structs are equal, if they are of the same type and each member is equal. Example:
uno.createUnoStruct() and passing the name of the struct
as the first parameter and optionial constructor arguments (see above for
an example of possible ctors).
ATTENTION: In UNO, structs have value semantic, however the handling in python does not reflect this. When a struct gets passed as a parameter to a function, the values are passed to the callee. Later modification of the struct instance does not influence the callee anymore. However, simply assigning a struct to another local variable does not create a copy, but simply creates an alias to the original instance.
|
||
sequence | A sequence is in general mapped to a python tuple. A python list is not (!)
accepted.
sequence<byte>
is mapped to the class uno.ByteSequence .
It has a string member named value , which holds the data of the byte sequence.
As the bytesequence most often is a container for binary data, this class allows to handle
binaries efficiently. This also embeds pyuno nicely into python, as python keeps binary
data in strings. Example:
|
||
constants | An UNO idl constant can be given by the following ways:
|
||
any | In general, the python programmer does not come into touch with anys. At all places
where anys appear in method signatures, the python programmer can simply pass a concrete
value. Consequently, return values or out parameters also never contain a concrete any.
However, there are certain circumstances, where a python programmer may want to pass a concrete typed value to a callee (note, this is only possible for 'bridged' calls, you can't pass a typed any to another python uno object). You can create a
These anys can only be used in conjunction with the
sequence<short> .
When obj is a local python object, it gets simply the (4,5) as it would have
got it with the normal call.
|
To be an UNO object, a python class MUST implement the com.sun.star.lang.XTypeProvider interface by implementing two methods getTypes() and getImplementationId(), which inform the python-UNO bridge, which concrete UNO interfaces the python class implements. The getTypes() function defines, which interfaces are implemented by the class.
To make this easier, there exists a unohelper.Base
class, where
a python UNO object should derive from. You can then implement a UNO interface
simply by deriving from the wanted interfaces. The following example
implements a com.sun.star.io.XOutputStream, which stores
all data written into the stream within a ByteSequence. (Note that this is
quite a poor implementation, which is just for demonstration purposes).
import unohelper from com.sun.star.io import XOutputStream class SequenceOutputStream( unohelper.Base, XOutputStream ): def __init__( self ): self.s = uno.ByteSequence("") self.closed = 0 def closeOutput(self): self.closed = 1 def writeBytes( self, seq ): self.s = self.s + seq def flush( self ): pass def getSequence( self ): return self.s |
If the reader is unfamilar with the component registration process, it should visit the OpenOffice.org developer manual for a comprehensive explanation.
The python loader currently supports the following protocols for incoming urls :
Protocol name | Description |
---|---|
vnd.openoffice.pymodule | The protocol dependend part is interpreted as a python module name, which is imported
using the common python import mechanism (which uses the PYTHONPATH environment variable).
Example: The given module is added to the |
file | A mandatory absolute file url to a python component file.
The file itself does not need to be contained within PYTHONPATH, but it may
only import files, which are contained within PYTHONPATH.
The module is not added to sys.modules .
Example: |
vnd.sun.star.expand | The python loader supports the common macro expansion mechanisms as the Java or
C++ loader does.
Example: |
After the module has been imported, the python loader looks for a module-global variable
with the name g_ImplementationHelper
, which is expected to be an instance
of unohelper.ImplementationHelper
.
The following sample code makes a uno component out of the above UNO object
( note that the component is not useful, because there is no UNO method to retrieve
the tuple nor does a com.sun.star.io.OutputStream service specification exist, it's just here
as an example).
import unohelper from com.sun.star.io import XOutputStream g_ImplementationHelper = unohelper.ImplementationHelper() class TupleOutputStream( unohelper.Base, XOutputStream ): # The component must have a ctor with the component context as argument. def __init__( self, ctx ): self.t = () self.closed = 0 # idl void closeOutput(); def closeOutput(self): self.closed = 1 # idl void writeBytes( [in] sequence |
regcomp -register -br types.rdb -br services.rdb -r services.rdb -c vnd.openoffice.pymodule:tuplestrm
You can of course also use the pkgchk
tool as explained in the tutorial chapter with
pkgchk tuplestrm.py
, but note, that this command creates a copy of the file (when the script changes,it must be redeployed using the above command).
The component can be instantiated e.g. from OpenOffice Basic with
tupleStrm = createUnoService( "com.sun.star.io.OutputStream" ) tupleStrm.flush() |
None
value should be used as a place holder.
This is best explained with an example.
Lets' assume we have the following IDL method spec
long foo( [in] long first, [inout] long second, [out] third ) |
class Dummy( XFoo ): def foo( self, first,second,third): # Note: the value of third is always None, but it must be there # as a placeholder if more args would follow ! return first,2*second,second + first |
ret,second,third = unoObject.foo( 2, 5 , None ) print ret,second,third # results into 2,10,7 |
However, note that
RuntimeException
during the call.
None
followed by possible
out parameters, so when you have a void method with one out parameter
you must assign the output to two variables (though the first one
will always be None).
None
as the first parameter.
Example for catching
from com.sun.star.uno import RuntimeException from com.sun.star.lang import IllegalArgumentException from com.sun.star.connection import NoConnectException try: uuresoler.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" ) except NoConnectException e: print "The OpenOffice process is not started or does not listen on the resource ("+e.Message+")" except IllegalArgumentException e: print "The url is invalid ( "+ e.Message+ ")" except RuntimeException e: print "An unknown error occured: " + e.Message |
from com.sun.star.io import IOException class TupleOutputStream(XOutputStream,unohelper.Base): def writeBytes( self, seq ): if self.closed: raise IOException( "Output stream already closed", self ) self.t = self.t + seq |
def systemPathToFileUrl( systemPath )
|
Returns a file-url for the given system path. Most of the OOo API functions
expect a file-url, while the python runtime functions in general only work
with system pathes. The function is implemented using the core C function
osl_getFileUrlFromSystemPath() .
|
def fileUrlToSystemPath( url ) |
Returns a system path (determined by the system, the python interpreter
is running on). Most OOo function return a file-url, while most python
runtime functions expect system pathes. The function is implemented by
using the core osl_getSystemPathFromFileUrl() function.
|
def absolutize( path, relativeUrl )
|
Returns an absolute file url from a given, mandatory absolute, directory url
and a relative file url, which may be absolute or relative (which includes
e.g. ../ parts. The function is implemented by using the core
osl_getAbsolutePathFromFileUrl() function.
|
def addComponentsToContext( toBeExtendedContext, contextRuntime, componentUrls, loaderName ) |
This functions adds a tuple of component urls
to the
toBeExtendedContext using the contextRuntime to
instantiate the loader loaderName and some other services needed for this
task. After completing the function, all services within these components
can be instantiated as long as the toBeExtendedContext is
not disposed. The changes are not made persistent.
|
def inspect( unoobject, file )
|
Dumps the typeinformation about the given UNO object into a file (in fact, file needs to be an instance of a class, that implements a write method). The typeinformation include implementation name, supported services, supported interfaces, supported methods and supported properties. |
Unlike the Java or C++ UNO binding, the python UNO binding is not self contained. It requires the C++ UNO binding and additional scripting components. These additional components currently live in the shared libraries typeconverter.uno,invocation.uno,corereflection.uno,introspection.uno,invocadapt.uno, proxyfac.uno,pythonloader.uno (on windows typeconverter.uno.dll,...; unix typeconverter.uno.so,...).
Often, the components for setting up an interprocess connection are additonally required. These are uuresolver.uno,connector.uno,remotebridge.uno,bridgefac.uno shared libraries.
The path environment variables ( LD_LIBRARY_PATH on unix, PATH on windows)
must point to a directory, where the core UNO libraries, the above listed
components and the pyuno shared library is located. (On unix, there exists
two files: libpyuno.so containing the code and a pyuno.so which is needed
for importing a native python module).
Additionally, the python module uno.py, unohelper.py and pythonloader.py must
be located in a directory, which is listed in the PYTHONPATH environment variable.
Bootstrapping pyuno from the python executable
When the uno module gets first imported from an arbitrary python script, it must bootstrap a properly prepared UNO component context.
# bootstraps the uno component context import uno # retrieve the already bootstrapped component context unoContext = uno.getComponentContext() |
PYUNOLIBDIR is a special bootstrap variable, which contains the path to the currently used pyuno shared library. Example:
# The bootstrap variable PYUNOLIBDIR will be set by the pyuno runtime library UNO_TYPES=$PYUNOLIBDIR/types.rdb UNO_SERVICES=$PYUNOLIBDIR/pyuno_services.rdb |
$ python myscript.py
Sometimes it is preferable to mention the librarynames of the desired
components directly within the script instead of preparing a registry
(however note that the above mentioned bootstrap components always needs
to be registered in a registry).
This can be achieved by using the function
unohelper.addComponentsToContext(
toBeExtendedContext, contextRuntime, componentUrls, loaderName )
Example:
import uno import unohelper localContext = uno.getComponentContext() unohelper.addComponentsToContext( localContext, localContext, ("streams.uno",), "com.sun.star.loader.SharedLibrary") pipe = localContext.ServiceManager.createInstanceWithContext( "com.sun.star.io.Pipe", localContext ) pipe.writeBytes( uno.ByteSequence( "abc" ) ) ret,seq = pipe.readBytes( None, 3 ) |
Build and deliver this project.
prj -- build details source/module -- contains the core Python-UNO bridge and the module, that is loaded my the python executable. The result is a shared C++ library, to which the python loader links to. source/loader -- contains the UNO loader for python components inc/pyuno -- contains exported API for the python module. unotypes -- generates the types needed for the bridge test -- contains test python scripts. In order to execture the tests, simply type dmake test demo -- contains demo python scripts and a makefile , which creates a deployment file for the OO1.1beta build. zipcore -- creates a zip file, which contains the whole python core. This file is used during OpenOffice.org setup.Build this project. In order to run the tests, you need to get a HEAD version of the testtools project, which currently does not get built by default, build and deliver the testtools project. Afterwards run the tests in the pyuno/test directory using dmake runtest, you shouldn't get any errors there. Deliver this project.
This shall not be a full explanation, on how you can exchange the python runtime. Also note, that this has not been tested. However, here is a list of hints, which should help you doing this.
java CommandLineTools -d hello-framework-python.sxp \ /usr/local/joerg/OpenOffice.org1.1/user/Scripts).
Below you can find the sample script, which just pastes a
'Hello Scriptingframework' into the current document. The following
script is stored as HelloFramework.py
.
# Sample python script for the scripting framework # scriptCtx supports getDocument(), getComponentContext(), getDesktop() def Hello( scriptCtx ): print "entering HelloFramework.Hello" model = scriptCtx.getDocument() # access the document's text property text = model.Text # create a cursor cursor = text.createTextCursor() # insert the text into the document text.insertString( cursor, "Hello Scriptingframework", 0 ) return None |
parcel-descriptor.xml
file which describes all functions, that shall be callable fromt the office.
Here is the sample file for the above script.
<?xml version="1.0" encoding="UTF-8"?> <parcel language="Python" xmlns:parcel="scripting.dtd"> <script language="Python"> <locale lang="en"> <displayname value="HelloFramework.Hello"/> <description> Prints a 'Hello Framework' into the current document </description> </locale> <functionname value="HelloFramework.Hello"/> <logicalname value="HelloFramework.Hello"/> </script> </parcel> |
<source-file-name-without-.py>.<function-name>
.
The function gets called with a XScriptContext implementation as the first parameter. It provides the UNO component context (getComponentContext()), the desktop (getDesktop()) and the current document model (getDocument()) (if any).
Zip these two files as a .sxp file and deploy it into the office using the scripting frameworks commandlinetool. When you restart the office, you should be able to select the new script in the scriptinframework's dialogs.
Things to keep in mind:
return None
Python homepage | http://www.python.org |
The OpenOffice.org component model | http://udk.openoffice.org |
OpenOffice.org developer manual | http://api.openoffice.org/DevelopersGuide/DevelopersGuide.html |
<openoffice-install>/program $ ls -c1d py*
pyunorc pythonloader.py pythonloader.unorc python python.sh python-core python-core-2.2.2 pythonloader.uno.so pyuno.soUnder certain circumstances, it may occur, that the following ini files are missing
pyunorc (or pyuno.ini on windows):
[Bootstrap] UNO_TYPES=$ORIGIN/types.rdb UNO_SERVICES=$ORIGIN/services.rdb |
pythonloader.unorc (or pythonloader.unorc on windows):
[Bootstrap] PYTHONHOME=$ORIGIN/python-core PYTHONPATH=$ORIGIN/python-core/lib $ORIGIN/python-core/lib/lib-dynload $ORIGIN |
export PYTHONPATH="$sd_prog":"$sd_prog/python-core/lib":"$sd_prog/python-core/lib/lib-dynload":"$PYTHONPATH" export PYTHONHOME="$sd_prog"/python-core |
PYTHONPATH="$sd_prog":"$sd_prog/python-core/lib":"$sd_prog/python-core/lib/lib-dynload":"$PYTHONPATH" export PYTHONPATH PYTHONHOME="$sd_prog"/python-core export PYTHONHOME |
You may try to workaround this bug by adding a try: except:
level
in your trigger() implementation, which dumps an error message to stdout/stderr, but
sadly this will not help in all cases (e.g. compilation failure for some reason :o( ).
Of course, there may be other reasons for a crash, you will only know, when you try to retrieve a native callstack (e.g. using the gdb).
In python you don't need queryInterface
. E.g. Java code like
oInterface = (XInterface) oMSF.createInstance( "com.sun.star.frame.Desktop" ); oCLoader = ( XComponentLoader ) UnoRuntime.queryInterface( XComponentLoader.class, oInterface ); PropertyValue [] szEmptyArgs = new PropertyValue [0]; aDoc = oCLoader.loadComponentFromURL( "private:factory/swriter" , "_blank", 0, szEmptyArgs ); |
oCLoader = oMSF.createInstance( "com.sun.star.frame.Desktop" ) aDoc = oCLoader.loadComponentFromURL( "private:factory/swriter", "_blank", 0, () ) |
doc = desktop.loadComponentFromURL(infileurl, "_blank", 0, ()) doc.storeAsURL(outfileurl, ()) doc.print( () )You can workaround the problem by using the
uno.invoke()
function like below :
uno.invoke( doc , "print" , ( (), ) )
sequence< PropertyValue >
, while the PyUNO runtime
converts it to a sequence< any>
, where each any
contains a PropertyValue
. In my eyes, this is a bug within
the C++ code. However, there has been added a workaround for pyuno, which the
scripter can use.
See the below sample:
import uno import unohelper localContext = uno.getComponentContext() resolver = localContext.ServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", localContext) ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") smgr= ctx.ServiceManager desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx) doc = desktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, ()) style = doc.createInstance("com.sun.star.style.NumberingStyle") family = doc.getStyleFamilies().getByName('NumberingStyles') family.insertByName('List test', style) rule = style.getPropertyValue('NumberingRules') level = rule.getByIndex(0) # the normal call would have been: # rule.replaceByIndex( 0, level ) # but this will end up in a excpetion # magic to pass the exact type to the callee uno.invoke( rule , "replaceByIndex", (0, uno.Any("[]com.sun.star.beans.PropertyValue",level)) ) |
This is the only place, where the uno.Any is used. Using the uno.Any in normal calls will lead to RuntimeExceptions. A python uno object implementation will never receive an instance of uno.Any() as a incoming parameter, instead always the value within the is passed.
This solution looks really ugly, but it allows you to continue, where you otherwise can only give up or switch to another implementation language.
encoding = "ascii" # Default value set by _PyUnicode_Init()with
encoding = "is8859-1" # Default value set by _PyUnicode_Init()(or any other encoding you wish). However, note that this is a per installation configuration. It would be better to do the necessary conversions explicitly in the code.
Please use the dev@udk.openoffice.org mailing list for further questions.