except KeyError:
return
-def _makeQuery(iid):
+def _makeQuery(interface):
'''
Builds a function querying to a specific interface and returns it.
- @param iid: Interface identifier to use when querying
- @type iid: string
+ @param interface: Class representing an AT-SPI interface
+ @type interface: class
@return: Function querying to the given interface
@rtype: function
'''
@rtype: object
@raise NotImplementedError: When the desired interface is not supported
'''
+ iid = utils.getInterfaceIID(interface)
try:
i = self._icache[iid]
except KeyError:
# interface not cached
caching = True
- except TypeError:
+ except AttributeError:
# determine if we're caching
caching = _CACHE_LEVEL is not None
if caching:
try:
# do the query remotely
i = self.queryInterface(iid)
+ if i is not None:
+ i = i._narrow(interface)
except Exception, e:
- raise LookupError(e)
+ raise LookupError(e)
if i is None:
# cache that the interface is not supported
if caching:
self._icache[iid] = None
raise NotImplementedError
- # not needed according to ORBit2 spec, but makes Java queries work
- # more reliably according to Orca experience
- i = i._narrow(i.__class__)
if caching:
# cache the narrow'ed result, but only if we're caching for this object
self._icache[iid] = i
# build name of converter from the name of the interface
name = 'query%s' % utils.getInterfaceName(interface)
# build a function that queries to the given interface
- func = _makeQuery(utils.getInterfaceIID(interface))
+ func = _makeQuery(interface)
# build a new method that is a clone of the original function
method = new.function(func.func_code, func.func_globals, name,
func.func_defaults, func.func_closure)
@type SLOTS: tuple
'''
SLOTTED_CLASSES = {}
- SLOTS = ('_icache',)
+ SLOTS = ('_icache', 'user_data')
def __new__(cls):
'''
- Creates a new class mimicking the one requested, but with an extra _cache
- attribute set in the __slots__ tuple. This field can be set to a dictionary
- or other object to allow caching to occur.
+ Creates a new class mimicking the one requested, but with extra named
+ defined in __slots__. The _cache attribute is used internally for interface
+ caching. The user_data field may be populated with whatever data structure
+ a client wishes to use. Neither is set to a default value by default.
Note that we can't simply mix __slots__ into this class because __slots__
- has an effect only at class creation time.
+ has an effect only at class creation time.
+
+ We also do not completely obliterate __slots__ to allow __dict__ to be
+ instantiated as normal as reducing the initialization and memory overhead
+ of the millions of accessible objects that are created is a good thing for
+ many clients.
@param cls: Accessibility object class
@type cls: class
'__slots__' : _AccessibleMixin.SLOTS})
_AccessibleMixin.SLOTTED_CLASSES[cls] = new_cls
obj = cls._mix___new__(new_cls)
- # don't create the interface cache until we need it
- obj._icache = None
return obj
def __del__(self):
# return None if the application isn't reachable for any reason
return None
+class _RelationMixin(object):
+ '''
+ Defines methods to be added to the Relation class. At this time it only
+ overrides L{_RelationMixin.getTarget} which by the IDL's standard is
+ supposed to return CORBA.Objects but we expect LAccessibility.Accessible
+ objects (see http://bugzilla.gnome.org/show_bug.cgi?id=435833).
+ This seems to be a problem especially with the Java implementation of CORBA.
+ '''
+ def getTarget(self, index):
+ '''
+ Overrides the regular getTarget to return Accessibility.Accessible
+ objects.
+
+ @return: The 'nth' target of this Relation.
+ @rtype: Accessibility.Accessible
+ '''
+ target = self._mix_getTarget(index)
+ target.ref()
+ return target._narrow(Accessibility.Accessible)
+
# 1. mix the exception handlers into all queryable interfaces
map(_mixExceptions, constants.ALL_INTERFACES)
# 2. mix the exception handlers into other Accessibility objects
['_get_name', '_get_description'])
# 4. mix queryInterface convenience methods
_mixInterfaces(Accessibility.Accessible, constants.ALL_INTERFACES)
+# 5. mix Relation class
+_mixClass(Accessibility.Relation, _RelationMixin)