Browse Source

add dir() support for interfaces and components (b=896577 r=toddw)

Mook 11 years ago
parent
commit
6ef747026b
3 changed files with 33 additions and 8 deletions
  1. 11 0
      xpcom/client/__init__.py
  2. 13 8
      xpcom/components.py
  3. 9 0
      xpcom/test/test_misc.py

+ 11 - 0
xpcom/client/__init__.py

@@ -447,6 +447,17 @@ class Component(_XPCOMBase):
         iface_desc = self._get_classinfo_repr_()
         return "<XPCOM component '%s' (%s)>" % (self._object_name_,iface_desc)
 
+    def __dir__(self):
+        if not self._tried_classinfo_:
+            try:
+                self._build_all_supported_interfaces_()
+            except:
+                # Error building the info - ignore the error, but ensure that
+                # we are flagged as *not* having built, so the error is seen
+                # by the first caller who actually *needs* this to work.
+                self.__dict__['_tried_classinfo_'] = 0
+        return sorted(self.__dict__['_name_to_interface_iid_'].keys())
+
 class _Interface(_XPCOMBase):
     def __init__(self, comobj, iid, method_infos, getters, setters, constants):
         self.__dict__['_comobj_'] = comobj

+ 13 - 8
xpcom/components.py

@@ -129,19 +129,24 @@ class _Interface:
         raise TypeError, "components.interface objects are not subscriptable"
     def __setattr__(self, attr, value):
         raise AttributeError, "Can not set attributes on components.Interface objects"
-    def __getattr__(self, attr):
-        # Support constants as attributes.
-        c = _constants_by_iid_map.get(self._iidobj_)
-        if c is None:
+    def __get_constants(self):
+        try:
+            return _constants_by_iid_map[self._iidobj_]
+        except KeyError:
             c = {}
             i = xpt.Interface(self._iidobj_)
             for c_ob in i.constants:
                 c[c_ob.name] = c_ob.value
             _constants_by_iid_map[self._iidobj_] = c
-        if c.has_key(attr):
-            return c[attr]
-        raise AttributeError, "'%s' interfaces do not define a constant '%s'" % (self.name, attr)
-
+            return c
+    def __getattr__(self, attr):
+        # Support constants as attributes.
+        try:
+            return self.__get_constants()[attr]
+        except KeyError:
+            raise AttributeError, "'%s' interfaces do not define a constant '%s'" % (self.name, attr)
+    def __dir__(self):
+        return sorted(self.__get_constants().keys())
 
 class _Interfaces(_ComponentCollection):
     def _get_one(self, name):

+ 9 - 0
xpcom/test/test_misc.py

@@ -272,6 +272,15 @@ class TestNoInterfaceCaching(unittest.TestCase):
         # (the bug caused it to look on nsILoadGroup)
         self.assertIsNone(comp.notificationCallbacks)
 
+class TestDirInterfaces(unittest.TestCase):
+    def testDirInterface(self):
+        self.assertIn("TYPE_INTERFACE_POINTER",
+                      dir(xpcom.components.interfaces.nsISupportsInterfacePointer))
+
+    def testDirComponent(self):
+        sip = xpcom.components.classes["@mozilla.org/supports-interface-pointer;1"]\
+                   .createInstance(xpcom.components.interfaces.nsISupportsInterfacePointer)
+        self.assertIn("dataIID", dir(sip))
 
 if __name__=='__main__':
     testmain()