[Libreoffice] fixing UNO pythonloader for load-by-package [was: candidate for a new python section in SDK] examples page

Lionel Elie Mamane lionel at mamane.lu
Thu Dec 8 03:17:57 PST 2011

On Thu, Dec 08, 2011 at 10:00:24AM +0000, Michael Meeks wrote:

> But concretely, I don't care - I just want to understand this:

> 	* for a given structure of a python module:
> 		fax/
> 			__init__.py
> 			FooBaaBaz.py
> 			BingBongDing.py

Stop right here. fax is not a module, it is a package. FooBaaBaz is a
module. So if you want fax.FooBaaBaz.g_magicNameFoo, you need to
__import__("fax.FooBaaBaz"), not __import__("fax").

package = hierarchy of modules (directories with __init__.py inside)
module  = leafs in the hierarchy of modules (.py files)

The result of that __import__ is indeed the top-level package "fax"
(or actually, in the LibreOffice code, the top-level package
"wizard"). From that you get the module FooBaaBaz, and from *that* you
get g_magicNameFoo.

I hacked pythonloader.py "in-place" so that it loads the fax wizard
correctly; that should give you the idea of how to fix it correctly
for the general case. I expect calling code chopped off the last
component that I add back manually, it should not do that.

Here's the diff:

--- /home/master/src/libreoffice/core/pyuno/source/loader/pythonloader.py	2011-12-06 09:17:03.000000000 +0100
+++ pythonloader.py	2011-12-08 12:05:16.000000000 +0100
@@ -119,8 +119,13 @@
                     dependent = dependent[nSlash+1:len(dependent)]
                     if not path in sys.path:
                         sys.path.append( path )
-                var =  __import__( dependent )
-                return var
+                print "About to import " + dependent
+                topModName, dot, rest = dependent.partition('.')
+                package =  __import__(dependent + '.CallWizard')
+                print dir(package)
+                subPackage = getattr(package, rest)
+                subMod = getattr(subPackage, 'CallWizard')
+                return subMod
                 if DEBUG:
                     print("Unknown protocol '" + protocol + "'");
@@ -138,6 +143,8 @@
         mod = self.getModuleFromUrl( locationUrl )
+        print ("Fetched mod as " + str(mod))
+        print dir(mod)
         implHelper = mod.__dict__.get( "g_ImplementationHelper" , None )
         print ("dump stuff")
         if DEBUG:

> 		+ how does that module structure flatten into this
> 		  hash ?

It is not flattened.

>> Maybe instead of discussing things in generality, we should dive into
>> the concrete problem you are having? Give me UNO/LibreOffice
>> n00b/beginner-proof instructions on how to reproduce the problem.

> 	Sure :-) So - drop this services.rdb over your existing
> programservices/services.rdb;

> 	Re-start, and File->Wizards->Fax should produce this on the console:

Nothing happens but:

> The substantive change is:

>   <component loader="com.sun.star.loader.Python"
> 	     uri="vnd.openoffice.pymodule:wizards.fax">
>     <implementation name="com.sun.star.wizards.fax.CallWizard">
>       <service name="com.sun.star.wizards.fax.CallWizard"/>
>     </implementation>
>   </component>

Yeah, doing that change on top of my existing services.rdb got me


More information about the LibreOffice mailing list