-
-
Notifications
You must be signed in to change notification settings - Fork 745
Remove need for hashing NVDAObject and TextInfo objects #9746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ingEventCounts: NvDAObject and TextInfo instances can no longer be used directly as the key in a dict due to hashing issues in Python3. Rather, the key is now the id (address) of the object.
| #: @type: weakref.WeakValueDictionary | ||
| # Theoretically we could use weakref.WeakSet, | ||
| # 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). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment suggest that we could theoretically use a WeakSet, but that's not going to work as in sets, only hashable types are allowed. Doesn't that mean we theoretically can not use a set?
source/eventHandler.py
Outdated
| _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. | ||
| _pendingEventCountsByObj={} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I prefer this to be renamed to something like:
| _pendingEventCountsByObj={} | |
| _pendingEventCountsByObjId={} |
source/eventHandler.py
Outdated
| # 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. | ||
| _pendingEventCountsByObj={} | ||
| _pendingEventCountsByNameAndObj={} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar here:
| _pendingEventCountsByNameAndObj={} | |
| _pendingEventCountsByNameAndObjId={} |
|
Hopefully I made the comment a bit easier to understand?
|
This reverts commit 6ef31d9.
This reverts commit 6ef31d9.
Link to issue number:
None
Summary of the issue:
In baseObject.AutoPropertyObject: all instances are tracked on the class by storing them in a WeakKeyDictionary. Tracking of these instances is to allow clearing the proprty cache of all living objects in one go.
In eventHandler: there are several dictionaries that track currently queued events, keyed by eventName, object, or eventName and object.
Storing NvDAObjects and or TextInfo objects in these dictionaries requires these objects to be hashable.
However, in Python3, if an object's equality check is customized (I.e. a custom
__eq__method is provided), the object becomes unhashable, as Python3 requires that any two objects that report being equal must also share the same hash value.If
__eq__is implemented on an object and there is a need for the object to be hashable, one must also implement__hash__on the object (and all it subclasses it seems) as well.As our equality checks are rather complex, and many of them short-circuit for performance reasons, it is next to impossible to provide an optimal
__hash__that will honor the requirement that the hash values of two objects be equal if the objects report equal.Therefore, we should try to remove the need to hash NVDAObjects and TextInfo instances, by no longer using these as keys for dictionaries.
Description of how this pull request fixes the issue:
In baseObject.AutoPropertyObject:
The instance WeakKeyDictionary has been changed to a WeakValueDictionary which holds the instances as its values, keyed by the instance's id (address).
The eventHandler._pendingEventCounts dictionaries no longer use the object as the key directly, rather the id (address) of the object.
In both cases of baseObject and eventHandler, we are only tracking the objects over their lifetime, and we expect to only look up the same physical object (not one that just "looks" like that object), thus using the object's id (address) is perfectly fine.
Testing performed:
TypeError("Unhashable type") is no longer raised when trying to start / use NVDA.
Known issues with pull request:
None.
Change log entry:
None.
Section: New features, Changes, Bug fixes