diff --git a/source/baseObject.py b/source/baseObject.py index 30635416391..5819f05f34d 100755 --- a/source/baseObject.py +++ b/source/baseObject.py @@ -121,11 +121,8 @@ class AutoPropertyObject(object, metaclass=AutoPropertyType): """ #: Tracks the instances of this class; used by L{invalidateCaches}. - #: @type: weakref.WeakValueDictionary - # We really just want to store the instances as a set of weak references, - # but as there is no easy way to have NVDAObjects and TextInfos remain hashable in Python3, as they override equality, - # We store them on a WeakValueDictionary, keyed by their id (address). - __instances=weakref.WeakValueDictionary() + #: @type: weakref.WeakKeyDictionary + __instances=weakref.WeakKeyDictionary() #: Specifies whether properties are cached by default; #: can be overridden for individual properties by setting _cache_propertyName. #: @type: bool @@ -137,7 +134,7 @@ def __new__(cls, *args, **kwargs): #: Maps properties to cached values. #: @type: dict self._propertyCache={} - self.__instances[id(self)]=self + self.__instances[self]=None return self def _getPropertyViaCache(self,getterMethod=None): @@ -160,7 +157,7 @@ def invalidateCaches(cls): # We use keys() here instead of iterkeys(), as invalidating the cache on an object may cause instances to disappear, # which would in turn cause an exception due to the dictionary changing size during iteration. # #9067 (Py3 review required): because of this, wrap this in a list, as dict.keys() in Python 3 returns iterators. - for instance in list(cls.__instances.values()): + for instance in list(cls.__instances.keys()): instance.invalidateCache() class ScriptableType(AutoPropertyType): diff --git a/source/eventHandler.py b/source/eventHandler.py index 3d99e30e643..6f724c293ef 100755 --- a/source/eventHandler.py +++ b/source/eventHandler.py @@ -20,10 +20,8 @@ #Some dicts to store event counts by name and or obj _pendingEventCountsByName={} -# Note that due to the fact it is hard to keep NVDAObjects remaining hashable in Python3 due to their equality method being overridden, -# the id (address) of the NVDAObject will be used as the key in the dict, not the NVDAObject itself. -_pendingEventCountsByObjID={} -_pendingEventCountsByNameAndObjID={} +_pendingEventCountsByObj={} +_pendingEventCountsByNameAndObj={} # Needed to ensure updates are atomic, as these might be updated from multiple threads simultaneously. _pendingEventCountsLock=threading.RLock() @@ -40,8 +38,8 @@ def queueEvent(eventName,obj,**kwargs): lastQueuedFocusObject=obj with _pendingEventCountsLock: _pendingEventCountsByName[eventName]=_pendingEventCountsByName.get(eventName,0)+1 - _pendingEventCountsByObjID[id(obj)]=_pendingEventCountsByObjID.get(id(obj),0)+1 - _pendingEventCountsByNameAndObjID[(eventName,id(obj))]=_pendingEventCountsByNameAndObjID.get((eventName,id(obj)),0)+1 + _pendingEventCountsByObj[obj]=_pendingEventCountsByObj.get(obj,0)+1 + _pendingEventCountsByNameAndObj[(eventName,obj)]=_pendingEventCountsByNameAndObj.get((eventName,obj),0)+1 queueHandler.queueFunction(queueHandler.eventQueue,_queueEventCallback,eventName,obj,kwargs) def _queueEventCallback(eventName,obj,kwargs): @@ -51,16 +49,16 @@ def _queueEventCallback(eventName,obj,kwargs): _pendingEventCountsByName[eventName]=(curCount-1) elif curCount==1: del _pendingEventCountsByName[eventName] - curCount=_pendingEventCountsByObjID.get(id(obj),0) + curCount=_pendingEventCountsByObj.get(obj,0) if curCount>1: - _pendingEventCountsByObjID[id(obj)]=(curCount-1) + _pendingEventCountsByObj[obj]=(curCount-1) elif curCount==1: - del _pendingEventCountsByObjID[id(obj)] - curCount=_pendingEventCountsByNameAndObjID.get((eventName,id(obj)),0) + del _pendingEventCountsByObj[obj] + curCount=_pendingEventCountsByNameAndObj.get((eventName,obj),0) if curCount>1: - _pendingEventCountsByNameAndObjID[(eventName,id(obj))]=(curCount-1) + _pendingEventCountsByNameAndObj[(eventName,obj)]=(curCount-1) elif curCount==1: - del _pendingEventCountsByNameAndObjID[(eventName,id(obj))] + del _pendingEventCountsByNameAndObj[(eventName,obj)] executeEvent(eventName,obj,**kwargs) def isPendingEvents(eventName=None,obj=None): @@ -75,11 +73,11 @@ def isPendingEvents(eventName=None,obj=None): if not eventName and not obj: return bool(len(_pendingEventCountsByName)) elif not eventName and obj: - return id(obj) in _pendingEventCountsByObjID + return obj in _pendingEventCountsByObj elif eventName and not obj: return eventName in _pendingEventCountsByName elif eventName and obj: - return (eventName,id(obj)) in _pendingEventCountsByNameAndObjID + return (eventName,obj) in _pendingEventCountsByNameAndObj class _EventExecuter(object): """Facilitates execution of a chain of event functions.