forked from python/cpython
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pythongh-111545: Add Py_HashDouble() function
* Cleanup _Py_HashDouble() implementation. * Add Lib/test/test_capi/test_hash.py. * Add Modules/_testcapi/hash.c.
- Loading branch information
Showing
11 changed files
with
139 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
.. highlight:: c | ||
|
||
PyHash API | ||
---------- | ||
|
||
See also the :c:member:`PyTypeObject.tp_hash` member. | ||
|
||
.. c:function:: Py_hash_t Py_HashDouble(double value) | ||
Hash a C double number. | ||
Return ``-1`` if *value* is not-a-number (NaN). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import math | ||
import sys | ||
import unittest | ||
from test.support import import_helper | ||
_testcapi = import_helper.import_module('_testcapi') | ||
|
||
|
||
PyHASH_INF = 314159 | ||
if _testcapi.SIZEOF_VOID_P >= 8: | ||
PyHASH_BITS = 61 | ||
else: | ||
PyHASH_BITS = 31 | ||
PyHASH_MODULUS = ((1 << PyHASH_BITS) - 1) | ||
|
||
|
||
class CAPITest(unittest.TestCase): | ||
def test_hash_double(self): | ||
# Test Py_HashDouble() | ||
hash_double = _testcapi.hash_double | ||
|
||
# test integers | ||
integers = [*range(0, 10), 2**30 - 1, 2 ** 233] | ||
integers.extend([-x for x in integers]) | ||
for x in integers: | ||
expected = abs(x) % PyHASH_MODULUS | ||
if x < 0: | ||
expected = -expected | ||
if expected == -1: | ||
expected = -2 | ||
self.assertEqual(hash_double(float(x)), expected, x) | ||
|
||
# test non-finite values | ||
self.assertEqual(hash_double(float('inf')), PyHASH_INF) | ||
self.assertEqual(hash_double(float('-inf')), -PyHASH_INF) | ||
self.assertEqual(hash_double(float('nan')), -1) | ||
|
||
# special values: compare with Python hash() function | ||
def python_hash_double(x): | ||
return hash(x) | ||
|
||
special_values = ( | ||
sys.float_info.max, | ||
sys.float_info.min, | ||
sys.float_info.epsilon, | ||
math.nextafter(0.0, 1.0), | ||
) | ||
for x in special_values: | ||
with self.subTest(x=x): | ||
self.assertEqual(hash_double(x), python_hash_double(x)) | ||
self.assertEqual(hash_double(-x), python_hash_double(-x)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include "parts.h" | ||
#include "util.h" | ||
|
||
static PyObject * | ||
hash_double(PyObject *Py_UNUSED(module), PyObject *args) | ||
{ | ||
double value; | ||
if (!PyArg_ParseTuple(args, "d", &value)) { | ||
return NULL; | ||
} | ||
Py_hash_t hash = Py_HashDouble(value); | ||
Py_BUILD_ASSERT(sizeof(long long) >= sizeof(hash)); | ||
return PyLong_FromLongLong(hash); | ||
} | ||
|
||
static PyMethodDef test_methods[] = { | ||
{"hash_double", hash_double, METH_VARARGS}, | ||
{NULL}, | ||
}; | ||
|
||
int | ||
_PyTestCapi_Init_Hash(PyObject *m) | ||
{ | ||
return PyModule_AddFunctions(m, test_methods); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters