support new style classes - allowing a python xpcom class to inherit
from "object"
--- a/xpcom/server/loader.py
+++ b/xpcom/server/loader.py
@@ -67,21 +67,26 @@ def FindCOMComponents(py_module):
return comps
else:
sys.stderr.write("PYXPCOM_CLASSES should be a list, "
"not %s. File: %s" % (type(pyxpcom_classes),
py_module.__file__))
# Else, run over all top-level objects looking for likely candidates.
for name, obj in py_module.__dict__.items():
- if type(obj)==types.ClassType and \
- _has_good_attr(obj, "_com_interfaces_") and \
- _has_good_attr(obj, "_reg_clsid_") and \
- _has_good_attr(obj, "_reg_contractid_"):
- comps.append(obj)
+ try:
+ # Examine class types or new style classes that inherit from object.
+ if (type(obj) == types.ClassType or issubclass(obj, object)) and \
+ _has_good_attr(obj, "_com_interfaces_") and \
+ _has_good_attr(obj, "_reg_clsid_") and \
+ _has_good_attr(obj, "_reg_contractid_"):
+ comps.append(obj)
+ except TypeError:
+ # The issubclass call raises TypeError when the obj is not a class.
+ pass
return comps
def register_self(klass, compMgr, location, registryLocation, componentType):
pcl = ModuleLoader
from xpcom import _xpcom
svc = _xpcom.GetServiceManager().getServiceByContractID("@mozilla.org/categorymanager;1", components.interfaces.nsICategoryManager)
# The category 'module-loader' is special - the component manager uses it
# to create the nsIModuleLoader for a given component type.
--- a/xpcom/src/PyGBase.cpp
+++ b/xpcom/src/PyGBase.cpp
@@ -197,17 +197,18 @@ void *PyG_Base::ThisAsIID( const nsIID &
}
// Call back into Python, passing a Python instance, and get back
// an interface object that wraps the instance.
/*static*/ PRBool
PyG_Base::AutoWrapPythonInstance(PyObject *ob, const nsIID &iid, nsISupports **ppret)
{
NS_PRECONDITION(ppret!=NULL, "null pointer when wrapping a Python instance!");
- NS_PRECONDITION(ob && PyInstance_Check(ob), "AutoWrapPythonInstance is expecting an non-NULL instance!");
+ NS_PRECONDITION(ob && PyObject_HasAttrString(ob, "__class__"),
+ "AutoWrapPythonInstance is expecting a non-NULL instance!");
PRBool ok = PR_FALSE;
if (PR_LOG_TEST(nsPyxpcomLog, PR_LOG_DEBUG)) {
PyObject *r = PyObject_Repr(ob);
if (r!=NULL) {
char idstr[NSID_LENGTH];
iid.ToProvidedString(idstr);
LOG(PR_LOG_DEBUG, ("PyG_Base::AutoWrapPythonInstance: ob: '%s' to iid: %s", PyString_AsString(r), idstr));
Py_DECREF(r);
--- a/xpcom/src/PyIID.cpp
+++ b/xpcom/src/PyIID.cpp
@@ -105,17 +105,17 @@ Py_nsIID::IIDFromPyObject(PyObject *ob,
if (PyString_Check(ob)) {
ok = iid.Parse(PyString_AsString(ob));
if (!ok) {
PyErr_SetString(PyExc_ValueError, "The string is formatted as a valid nsID");
return PR_FALSE;
}
} else if (ob->ob_type == &type) {
iid = ((Py_nsIID *)ob)->m_iid;
- } else if (PyInstance_Check(ob)) {
+ } else if (PyObject_HasAttrString(ob, "__class__")) {
// Get the _iidobj_ attribute
PyObject *use_ob = PyObject_GetAttrString(ob, "_iidobj_");
if (use_ob==NULL) {
PyErr_SetString(PyExc_TypeError, "Only instances with _iidobj_ attributes can be used as IID objects");
return PR_FALSE;
}
if (use_ob->ob_type != &type) {
Py_DECREF(use_ob);
--- a/xpcom/src/PyISupports.cpp
+++ b/xpcom/src/PyISupports.cpp
@@ -241,17 +241,17 @@ Py_nsISupports::InterfaceFromPyObject(Py
PyErr_SetString(PyExc_TypeError, "None is not a invalid interface object in this context");
return PR_FALSE;
}
}
// support nsIVariant
if (iid.Equals(NS_GET_IID(nsIVariant)) || iid.Equals(NS_GET_IID(nsIWritableVariant))) {
// Check it is not already nsIVariant
- if (PyInstance_Check(ob)) {
+ if (PyObject_HasAttrString(ob, "__class__")) {
PyObject *sub_ob = PyObject_GetAttrString(ob, "_comobj_");
if (sub_ob==NULL) {
PyErr_Clear();
} else {
if (InterfaceFromPyISupports(sub_ob, iid, ppv)) {
Py_DECREF(sub_ob);
return PR_TRUE;
}
@@ -264,17 +264,17 @@ Py_nsISupports::InterfaceFromPyObject(Py
PyXPCOM_BuildPyException(nr);
return PR_FALSE;
}
NS_ASSERTION(ppv != nsnull, "PyObject_AsVariant worked but gave null!");
return PR_TRUE;
}
// end of variant support.
- if (PyInstance_Check(ob)) {
+ if (PyObject_HasAttrString(ob, "__class__")) {
// Get the _comobj_ attribute
PyObject *use_ob = PyObject_GetAttrString(ob, "_comobj_");
if (use_ob==NULL) {
PyErr_Clear();
if (bTryAutoWrap)
// Try and auto-wrap it - errors will leave Py exception set,
return PyXPCOM_XPTStub::AutoWrapPythonInstance(ob, iid, ppv);
PyErr_SetString(PyExc_TypeError, "The Python instance can not be converted to an XPCOM object");