diff options
author | Andreas Becker <atayoohoo@googlemail.com> | 2011-05-07 20:35:03 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@novell.com> | 2011-05-07 20:35:03 +0100 |
commit | a09ce46818fd4d5e08b3af9a478501cd8ef5b4fe (patch) | |
tree | 187c9164d436201442794dee227627e2b9173124 /pyuno/source/loader | |
parent | 7cf799064f5d64bca62626dc73723c2c5e95ca00 (diff) |
Port PyUno to support Python 3
Diffstat (limited to 'pyuno/source/loader')
-rw-r--r-- | pyuno/source/loader/makefile.mk | 34 | ||||
-rw-r--r-- | pyuno/source/loader/pythonloader.py | 200 | ||||
-rw-r--r-- | pyuno/source/loader/pyuno_loader.cxx | 30 |
3 files changed, 142 insertions, 122 deletions
diff --git a/pyuno/source/loader/makefile.mk b/pyuno/source/loader/makefile.mk index 65ec8116f9c5..76c3dc2ffecd 100644 --- a/pyuno/source/loader/makefile.mk +++ b/pyuno/source/loader/makefile.mk @@ -32,46 +32,46 @@ ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- -.INCLUDE : settings.mk +.INCLUDE : settings.mk .IF "$(L10N_framework)"=="" -DLLPRE = +DLLPRE = #------------------------------------------------------------------- .IF "$(OS)$(COMEX)" == "SOLARIS4" # no -Bdirect for SunWS CC -DIRECT = $(LINKFLAGSDEFS) +DIRECT= $(LINKFLAGSDEFS) .ENDIF .IF "$(SYSTEM_PYTHON)" == "YES" PYTHONLIB=$(PYTHON_LIBS) CFLAGS+=$(PYTHON_CFLAGS) .IF "$(EXTRA_CFLAGS)"!="" -PYTHONLIB+=-framework Python +PYTHONLIB+= -framework Python .ENDIF # "$(EXTRA_CFLAGS)"!="" .ELSE -.INCLUDE : pyversion.mk +.INCLUDE : pyversion.mk -CFLAGS+=-I$(SOLARINCDIR)$/python +CFLAGS+= -I$(SOLARINCDIR)$/python .ENDIF -SHL1TARGET= $(TARGET) +SHL1TARGET= $(TARGET) SHL1STDLIBS= \ - $(CPPULIB) \ - $(CPPUHELPERLIB) \ - $(SALLIB) \ - $(PYUNOLIB) \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) \ + $(PYUNOLIB) \ $(PYTHONLIB) -SHL1VERSIONMAP=$(SOLARENV)$/src$/component.map +SHL1VERSIONMAP= $(SOLARENV)$/src$/component.map SHL1DEPN= -SHL1IMPLIB= i$(TARGET) -SHL1LIBS= $(SLB)$/$(TARGET).lib -SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def -DEF1NAME= $(SHL1TARGET) -SLOFILES= $(SLO)$/pyuno_loader.obj +DEF1NAME= $(SHL1TARGET) +SLOFILES= $(SLO)$/pyuno_loader.obj # --- Targets ------------------------------------------------------ diff --git a/pyuno/source/loader/pythonloader.py b/pyuno/source/loader/pythonloader.py index 15fe57481f5a..1f6716ee90c1 100644 --- a/pyuno/source/loader/pythonloader.py +++ b/pyuno/source/loader/pythonloader.py @@ -40,112 +40,110 @@ g_supportedServices = "com.sun.star.loader.Python", # referenced by the na g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader ! def splitUrl( url ): - nColon = url.find( ":" ) - if -1 == nColon: - raise RuntimeException( "PythonLoader: No protocol in url " + url, None ) - return url[0:nColon], url[nColon+1:len(url)] + nColon = url.find( ":" ) + if -1 == nColon: + raise RuntimeException( "PythonLoader: No protocol in url " + url, None ) + return url[0:nColon], url[nColon+1:len(url)] g_loadedComponents = {} def checkForPythonPathBesideComponent( url ): - path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ); - if DEBUG == 1: - print "checking for existence of " + encfile( path ) - if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: - if DEBUG == 1: - print "adding " + encfile( path ) + " to sys.path" - sys.path.append( path ) - - path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ); - if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: - if DEBUG == 1: - print "adding " + encfile( path ) + " to sys.path" - sys.path.append( path ) + path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ); + if DEBUG == 1: + print("checking for existence of " + encfile( path )) + if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: + if DEBUG == 1: + print("adding " + encfile( path ) + " to sys.path") + sys.path.append( path ) + + path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ); + if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: + if DEBUG == 1: + print("adding " + encfile( path ) + " to sys.path") + sys.path.append( path ) def encfile(uni): return uni.encode( sys.getfilesystemencoding()) class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ): - def __init__(self, ctx ): - if DEBUG: - print "pythonloader.Loader ctor" - self.ctx = ctx - - def getModuleFromUrl( self, url ): - if DEBUG: - print "pythonloader: interpreting url " +url - protocol, dependent = splitUrl( url ) - if "vnd.sun.star.expand" == protocol: - exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" ) - url = exp.expandMacros(dependent) - protocol,dependent = splitUrl( url ) - - if DEBUG: - print "pythonloader: after expansion " +protocol +":" + dependent - - try: - if "file" == protocol: - # remove \..\ sequence, which may be useful e.g. in the build env - url = unohelper.absolutize( url, url ) - - # did we load the module already ? - mod = g_loadedComponents.get( url ) - if not mod: - mod = imp.new_module("uno_component") - - # check for pythonpath.zip beside .py files - checkForPythonPathBesideComponent( url[0:url.rfind('/')] ) - - # read the file - filename = unohelper.fileUrlToSystemPath( url ) - fileHandle = file( filename ) - src = fileHandle.read().replace("\r","") - if not src.endswith( "\n" ): - src = src + "\n" - - # compile and execute the module - codeobject = compile( src, encfile(filename), "exec" ) - exec codeobject in mod.__dict__ - mod.__file__ = encfile(filename) - g_loadedComponents[url] = mod - return mod - elif "vnd.openoffice.pymodule" == protocol: - return __import__( dependent ) - else: - raise RuntimeException( "PythonLoader: Unknown protocol " + - protocol + " in url " +url, self ) - except ImportError, e: - raise RuntimeException( "Couldn't load "+url+ " for reason "+str(e), None) - return None - - def activate( self, implementationName, dummy, locationUrl, regKey ): - if DEBUG: - print "pythonloader.Loader.activate" - - mod = self.getModuleFromUrl( locationUrl ) - implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) - if implHelper == None: - return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey ) - else: - return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager) - - def writeRegistryInfo( self, regKey, dummy, locationUrl ): - if DEBUG: - print "pythonloader.Loader.writeRegistryInfo" - - mod = self.getModuleFromUrl( locationUrl ) - implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) - if implHelper == None: - return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey ) - else: - return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager ) - - def getImplementationName( self ): - return g_implementationName - - def supportsService( self, ServiceName ): - return ServiceName in self.serviceNames - - def getSupportedServiceNames( self ): - return g_supportedServices - - + def __init__(self, ctx ): + if DEBUG: + print("pythonloader.Loader ctor") + self.ctx = ctx + + def getModuleFromUrl( self, url ): + if DEBUG: + print("pythonloader: interpreting url " + url) + protocol, dependent = splitUrl( url ) + if "vnd.sun.star.expand" == protocol: + exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" ) + url = exp.expandMacros(dependent) + protocol,dependent = splitUrl( url ) + + if DEBUG: + print("pythonloader: after expansion " + protocol + ":" + dependent) + + try: + if "file" == protocol: + # remove \..\ sequence, which may be useful e.g. in the build env + url = unohelper.absolutize( url, url ) + + # did we load the module already ? + mod = g_loadedComponents.get( url ) + if not mod: + mod = imp.new_module("uno_component") + + # check for pythonpath.zip beside .py files + checkForPythonPathBesideComponent( url[0:url.rfind('/')] ) + + # read the file + filename = unohelper.fileUrlToSystemPath( url ) + fileHandle = file( filename ) + src = fileHandle.read().replace("\r","") + if not src.endswith( "\n" ): + src = src + "\n" + + # compile and execute the module + codeobject = compile( src, encfile(filename), "exec" ) + exec(codeobject, mod.__dict__) + mod.__file__ = encfile(filename) + g_loadedComponents[url] = mod + return mod + elif "vnd.openoffice.pymodule" == protocol: + return __import__( dependent ) + else: + raise RuntimeException( "PythonLoader: Unknown protocol " + + protocol + " in url " +url, self ) + except ImportError as e: + raise RuntimeException( "Couldn't load " + url + " for reason " + str(e), None ) + return None + + def activate( self, implementationName, dummy, locationUrl, regKey ): + if DEBUG: + print("pythonloader.Loader.activate") + + mod = self.getModuleFromUrl( locationUrl ) + implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) + if implHelper == None: + return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey ) + else: + return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager) + + def writeRegistryInfo( self, regKey, dummy, locationUrl ): + if DEBUG: + print( "pythonloader.Loader.writeRegistryInfo" ) + + mod = self.getModuleFromUrl( locationUrl ) + implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) + if implHelper == None: + return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey ) + else: + return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager ) + + def getImplementationName( self ): + return g_implementationName + + def supportsService( self, ServiceName ): + return ServiceName in self.serviceNames + + def getSupportedServiceNames( self ): + return g_supportedServices diff --git a/pyuno/source/loader/pyuno_loader.cxx b/pyuno/source/loader/pyuno_loader.cxx index 830254d9841f..7f2466b449e6 100644 --- a/pyuno/source/loader/pyuno_loader.cxx +++ b/pyuno/source/loader/pyuno_loader.cxx @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/*nd '!=' comparisions are defined"126G -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -118,8 +118,26 @@ static void setPythonHome ( const OUString & pythonHome ) OUString systemPythonHome; osl_getSystemPathFromFileURL( pythonHome.pData, &(systemPythonHome.pData) ); OString o = rtl::OUStringToOString( systemPythonHome, osl_getThreadTextEncoding() ); - rtl_string_acquire(o.pData); // leak this string (thats the api!) - Py_SetPythonHome( o.pData->buffer); +#if PY_MAJOR_VERSION >= 3 + // static because Py_SetPythonHome just copies the "wide" pointer + // PATH_MAX is defined in Python.h + static wchar_t wide[PATH_MAX + 1]; + size_t len = mbstowcs(wide, o.pData->buffer, PATH_MAX + 1); + if(len == (size_t)-1) + { + PyErr_SetString(PyExc_SystemError, "invalid multibyte sequence in python home path"); + return; + } + if(len == PATH_MAX + 1) + { + PyErr_SetString(PyExc_SystemError, "python home path is too long"); + return; + } + Py_SetPythonHome(wide); +#else + rtl_string_acquire(o.pData); // increase reference count + Py_SetPythonHome(o.pData->buffer); +#endif } static void prependPythonPath( const OUString & pythonPathBootstrap ) @@ -178,7 +196,11 @@ Reference< XInterface > CreateInstance( const Reference< XComponentContext > & c if( pythonPath.getLength() ) prependPythonPath( pythonPath ); - +#if PY_MAJOR_VERSION >= 3 + PyImport_AppendInittab( "pyuno", PyInit_pyuno ); +#else + PyImport_AppendInittab( "pyuno", initpyuno ); +#endif // initialize python Py_Initialize(); PyEval_InitThreads(); |