avocado/core/tree.py: allow MuxTreeNode to be hashed under Python 3
Under Python 3, as in Python 2, most objects are automatically hashable. Example: >>> class Foo(object): >>> pass >>> hash(Foo()) >>> 8760583602380 But if an object that implements __eq__ also has to implement __hash__. Under Python 3: >>> class Foo(object): >>> def __eq__(self, other): >>> return False Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'Foo' Since TreeNode implements __eq__, under Python 3, it *must* implement __hash__. There are a few tricky points, though. One of them is that "The only required property is that objects which compare equal have the same hash value". TreeNodes have a very flexible equality comparison, which cannot be taken into account in a hash implementation which doesn't have access to the "other" object. To the best of my knowledge, the way to go with the TreeNode __hash__ implementation is to take into account the comparison of all attributes that are used on __eq__ (name, values, children) and use those as the composition for __hash__, as suggested by the Python docs. Unfortunately, some of the content of "values" and "children" may themselves be unshashable values (such as dicts coming from YAML test suite loader). My coward's way out here was to use a string representation of such unhashable types to compose the TreeNode hash. This fixes 5 unittests of the varianter_yaml_to_mux plugin when run under Python 3, such as: ====================================================================== ERROR: test_get_rel_path (tests.test_mux.TestAvocadoParams) ---------------------------------------------------------------------- .... if len(set([_[1] for _ in ret])) == 1: # single source of results TypeError: unhashable type: 'MuxTreeNode' Reference: https://docs.python.org/3/reference/datamodel.html#object.__hash__Signed-off-by: NCleber Rosa <crosa@redhat.com>
Showing
想要评论请 注册 或 登录