diff --git a/pandas/core/common.py b/pandas/core/common.py index f8f5928ca7d51..d2c0406d87310 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -2537,13 +2537,13 @@ def is_hashable(arg): >>> is_hashable(a) False """ - # don't consider anything not collections.Hashable, so as not to broaden - # the definition of hashable beyond that. For example, old-style classes - # are not collections.Hashable but they won't fail hash(). - if not isinstance(arg, collections.Hashable): - return False + # unfortunately, we can't use isinstance(arg, collections.Hashable), which + # can be faster than calling hash, because numpy scalars on Python 3 fail + # this test + + # reconsider this decision once this numpy bug is fixed: + # https://github.com/numpy/numpy/issues/5562 - # narrow the definition of hashable if hash(arg) fails in practice try: hash(arg) except TypeError: diff --git a/pandas/tests/test_common.py b/pandas/tests/test_common.py index 36d6c39586d97..3d232878fb15d 100644 --- a/pandas/tests/test_common.py +++ b/pandas/tests/test_common.py @@ -424,7 +424,7 @@ def __hash__(self): raise TypeError("Not hashable") hashable = ( - 1, 'a', tuple(), (1,), HashableClass(), + 1, 3.14, np.float64(3.14), 'a', tuple(), (1,), HashableClass(), ) not_hashable = ( [], UnhashableClass1(), @@ -434,13 +434,10 @@ def __hash__(self): ) for i in hashable: - assert isinstance(i, collections.Hashable) assert com.is_hashable(i) for i in not_hashable: - assert not isinstance(i, collections.Hashable) assert not com.is_hashable(i) for i in abc_hashable_not_really_hashable: - assert isinstance(i, collections.Hashable) assert not com.is_hashable(i) # numpy.array is no longer collections.Hashable as of @@ -455,7 +452,7 @@ class OldStyleClass(): pass c = OldStyleClass() assert not isinstance(c, collections.Hashable) - assert not com.is_hashable(c) + assert com.is_hashable(c) hash(c) # this will not raise