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 PyHash_Double() function
* Cleanup PyHash_Double() implementation based _Py_HashDouble(): * Move variable declaration to their first assignment. * Add braces (PEP 7). * Cast result to signed Py_hash_t before the final "== -1" test, to reduce the number of casts. * Add an assertion on Py_IS_NAN(v) in the only code path which can return -1. * Add tests: Modules/_testcapi/hash.c and Lib/test/test_capi/test_hash.py.
- Loading branch information
Showing
13 changed files
with
155 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 PyHash_Double(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
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,61 @@ | ||
import math | ||
import sys | ||
import unittest | ||
from test.support import import_helper | ||
_testcapi = import_helper.import_module('_testcapi') | ||
|
||
|
||
PyHASH_INF = sys.hash_info.inf | ||
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 PyHash_Double() | ||
hash_double = _testcapi.hash_double | ||
|
||
# test integers | ||
def python_hash_int(x): | ||
negative = (x < 0) | ||
x = abs(x) % PyHASH_MODULUS | ||
if negative: | ||
x = -x | ||
if x == -1: | ||
x = -2 | ||
return x | ||
|
||
integers = [ | ||
*range(1, 30), | ||
2**30 - 1, | ||
2 ** 233, | ||
int(sys.float_info.max), | ||
] | ||
integers.extend([-x for x in integers]) | ||
integers.append(0) | ||
|
||
for x in integers: | ||
self.assertEqual(hash_double(float(x)), python_hash_int(x), 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)) |
2 changes: 2 additions & 0 deletions
2
Misc/NEWS.d/next/C API/2023-11-15-01-26-59.gh-issue-111545.iAoFtA.rst
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,2 @@ | ||
Add :c:func:`PyHash_Double` function to hash a C double number. Patch by | ||
Victor Stinner. |
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 = PyHash_Double(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