classification
Title: is it a bug in `functools._HashedSeq`
Type: Stage: resolved
Components: Library (Lib) Versions: Python 3.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: Jiajun Huang, python-dev, rhettinger
Priority: normal Keywords:

Created on 2017-01-08 02:02 by Jiajun Huang, last changed 2017-01-09 07:20 by serhiy.storchaka. This issue is now closed.

Messages (6)
msg284949 - (view) Author: Jiajun Huang (Jiajun Huang) * Date: 2017-01-08 02:02
the class definition:

class _HashedSeq(list):
    """ This class guarantees that hash() will be called no more than once
        per element.  This is important because the lru_cache() will hash
        the key multiple times on a cache miss.

    """

    __slots__ = 'hashvalue'

    def __init__(self, tup, hash=hash):
        self[:] = tup
        self.hashvalue = hash(tup)

    def __hash__(self):
        return self.hashvalue

and I've test for it:

In [1]: from functools import _HashedSeq

In [2]: from unittest.mock import Mock

In [3]: test_tup = 1, 2, 3, "hello", "world"

In [4]: hash_func = Mock()

In [5]: _HashedSeq(test_tup, hash=hash_func)
Out[5]: [1, 2, 3, 'hello', 'world']

In [6]: _HashedSeq(test_tup, hash=hash_func)
Out[6]: [1, 2, 3, 'hello', 'world']

In [7]: _HashedSeq(test_tup, hash=hash_func)
Out[7]: [1, 2, 3, 'hello', 'world']

In [8]: hash_func.call_count
Out[8]: 3

the hash function had been called 3 times rather than 1.
msg284951 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-01-08 02:16
Sorry, but I think you've missed the point of _HashedSeq.  The hash() is called no more than once per instance, not once per instance creation.

    >>> from functools import _HashedSeq
    >>> from unittest.mock import Mock
    >>> test_tup = 1, 2, 3, "hello", "world"
    >>> hash_func = Mock(return_value=999)
    >>> hs = _HashedSeq(test_tup, hash=hash_func)
    >>> hash(hs)
    999
    >>> hash(hs)
    999
    >>> hash(hs)
    999
    >>> hash_func.call_count
    1
msg284959 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2017-01-08 04:45
New changeset 52d3cbcf546f by Raymond Hettinger in branch 'default':
Issue #29200: Add test for lru cache only calling __hash__ once
https://hg.python.org/cpython/rev/52d3cbcf546f
msg284960 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-01-08 04:45
To honor your report, I've added a test for this functionality.
msg284961 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2017-01-08 04:53
New changeset 2e7e91785306 by Raymond Hettinger in branch 'default':
Issue #29200: Fix test to use self.assertEqual instead of py.test style tests
https://hg.python.org/cpython/rev/2e7e91785306
msg284964 - (view) Author: Jiajun Huang (Jiajun Huang) * Date: 2017-01-08 06:13
thanks for reply :)

2017年1月8日星期日,Roundup Robot <report@bugs.python.org> 写道:

>
> Roundup Robot added the comment:
>
> New changeset 2e7e91785306 by Raymond Hettinger in branch 'default':
> Issue #29200: Fix test to use self.assertEqual instead of py.test style
> tests
> https://hg.python.org/cpython/rev/2e7e91785306
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org <javascript:;>>
> <http://bugs.python.org/issue29200>
> _______________________________________
>
History
Date User Action Args
2017-01-09 07:20:47serhiy.storchakasetstage: resolved
2017-01-08 06:13:18Jiajun Huangsetmessages: + msg284964
2017-01-08 04:53:18python-devsetmessages: + msg284961
2017-01-08 04:45:47rhettingersetmessages: + msg284960
2017-01-08 04:45:00python-devsetnosy: + python-dev
messages: + msg284959
2017-01-08 02:16:07rhettingersetstatus: open -> closed
resolution: not a bug
messages: + msg284951
2017-01-08 02:05:24rhettingersetassignee: rhettinger

nosy: + rhettinger
2017-01-08 02:02:12Jiajun Huangcreate