ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> pyxpcom
pyxpcom
[pyxpcom] Wrapping an existing python module with PyXPCOM
by Cyril Giraudon other posts by this author
Feb 26 2007 6:59AM messages near this date
view in the new Beta List Site
[pyxpcom] Xulrunner Dynamic Linking issues for libpyloader under linux and mac | Re: [pyxpcom] Wrapping an existing python module with PyXPCOM
Hello, I have to use a python module in a xulrunner application.
This python module already exists and I can't modify it.

I search for the best solution to create the PyPXCOM components and the 
XPCOM interfaces.


My problem is explained in the following paragraphs.

Given two python classes, perhaps localized in seperated directories :

## module titi.py
class titi:
  def sayHello():
     print "Hello"

  def sayBye():
     print "Bye"


## module toto.py
from titi import titi

class toto:
  def __init__():
    self.titi = titi()

  def sayThanks():
    print "Thanks"

  def getTiti():
    return self.titi

I decide to create an interface which represents toto's capabilities :
[scriptable, uuid(ad5cd5b0-1352-11db-ac5d-0800200c9a66)]
interface iToto : nsISupports
{
  void sayThanks();
}

and a xptoto component :

# module xptoto.py
from toto import toto

class xptoto(toto):
  _com_interfaces_ = components.interfaces.iToto
  _reg_clsid_ = "{e81e4c20-1351-11db-ac5d-0800200c9a66}"
  _reg_contractid_ = "@cyril/toto;1"
  _reg_desc_ = "a toto component"

 From javascript, an xptoto instance can say "Thanks".
var toto =  Components.classes["@cyril/toto;1].
  createInstance(Components.interfaces.iToto);
toto.sayThanks();

In a pure python world, to say "Hello" I would have typed :
toto = toto()
toto.getTiti().sayHello()

But with XPCOM, what is the right way to make xptoto say "Hello" ?

======================= First solution =================
Upgrade iToto :
[scriptable, uuid(ad5cd5b0-1352-11db-ac5d-0800200c9a66)]
interface iToto : nsISupports
{
  void sayThanks();
  void sayHello();
  void sayBye;
}
and change xptoto into :
class xptoto(toto):
  _com_interfaces_ = components.interfaces.iToto
  _reg_clsid_ = "{e81e4c20-1351-11db-ac5d-0800200c9a66}"
  _reg_contractid_ = "@cyril/toto;1"
  _reg_desc_ = "a toto component"

  def sayHello():
    self.titi.sayHello()

  def sayBye():
    self.titi.sayBye()

That is to say that for a large module, one has to create a huge python 
wrapper which takes all request for all the commands like a manager module.
There is a unique bridge.

===================== Second solution ==================
Add a new interface iTiti
[scriptable, uuid(ad5cd5b0-1352-11db-ac5d-0800200c9a67)]
interface iTiti : nsISupports
{
  void sayHello();
  void sayBye;
}
and a xptiti component :

class xptiti(titi):
  _com_interfaces_ = components.interfaces.iTiti
  _reg_clsid_ = "{e81e4c20-1351-11db-ac5d-0800200c9a68}"
  _reg_contractid_ = "@cyril/titi;1"
  _reg_desc_ = "a titi component"

Problem : How can I convert a titi instance into a xptiti instance ?
A solution is :

class xptiti:
  _com_interfaces_ = components.interfaces.iTiti
  _reg_clsid_ = "{e81e4c20-1351-11db-ac5d-0800200c9a68}"
  _reg_contractid_ = "@cyril/titi;1"
  _reg_desc_ = "a titi component"

  def __init__():
    global tmp
    self.titi = tmp

  def sayHello():
    self.titi.sayHello()

  def sayBye():
    self.titi.sayBye()

And transform iToto interface and xptoto component as follows ;
[scriptable, uuid(ad5cd5b0-1352-11db-ac5d-0800200c9a66)]
interface iToto : nsISupports
{
  void sayThanks();
  xptiti getTiti();
}

## We can use a global variable to initialize xptiti.titi
tmp = None

class xptoto(toto):
  _com_interfaces_ = components.interfaces.iToto
  _reg_clsid_ = "{e81e4c20-1351-11db-ac5d-0800200c9a66}"
  _reg_contractid_ = "@cyril/toto;1"
  _reg_desc_ = "a toto component"

  def __init__():
    self.xptiti = None

  def getTiti():
    if self.xptiti is None:
      global tmp
      tmp = self.getTiti()
      self.xptiti = components.classes["@cyril/toto;1].
        createInstance(Components.interfaces.iTiti)
    return self.xptiti

And now, we can write the following commands
var toto =  Components.classes["@cyril/toto;1].
  createInstance(Components.interfaces.iToto);
var titi = toto.getTiti().sayHello();

I'm not satisfied by this second solution either. The use of global 
variable is a trick.

===================================================================

Is there an identified way to do such a task ?

What is the original philosophy of this kind of technology ?

Thanks a lot,

Cyril Giraudon.
Thread:
Cyril Giraudon
Lekma
Cyril Giraudon
Edward Baafi
Cyril Giraudon

Privacy Policy | Email Opt-out | Feedback | Syndication
© 2004 ActiveState, a division of Sophos All rights reserved