Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

GH-84783: Make the slice object hashable#101264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
rhettinger merged 15 commits intopython:mainfromfurkanonder:issue-84783
Feb 19, 2023
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
15 commits
Select commitHold shift + click to select a range
61c8048
fix the typo in the tuplehash func's comment
furkanonderJan 23, 2023
ef22a92
make hashable the slice
furkanonderJan 23, 2023
12c2488
Merge branch 'main' into issue-84783
furkanonderJan 23, 2023
6dd9926
Merge branch 'main' into issue-84783
furkanonderJan 25, 2023
886bfff
fix failed slice's test cases
furkanonderFeb 11, 2023
2971147
Merge branch 'main' into issue-84783
furkanonderFeb 11, 2023
093bf38
📜🤖 Added by blurb_it.
blurb-it[bot]Feb 11, 2023
159f3f2
Add version changed to slice's doc
furkanonderFeb 11, 2023
0c78cfc
Update test_doctest.py
OTheDevFeb 12, 2023
cff08dd
Update Doc/library/functions.rst
furkanonderFeb 12, 2023
ea55931
Merge branch 'main' into issue-84783
furkanonderFeb 12, 2023
f0302bf
Update version changed to slice's doc
furkanonderFeb 12, 2023
2c76491
Merge pull request #1 from OTheDev/patch-1
furkanonderFeb 12, 2023
cbd1527
Add more testcases for slice's hash
furkanonderFeb 12, 2023
9f55e46
update testcases for slice's hash
furkanonderFeb 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletionsDoc/library/functions.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1635,6 +1635,9 @@ are always available. They are listed here in alphabetical order.
example: ``a[start:stop:step]`` or ``a[start:stop, i]``. See
:func:`itertools.islice` for an alternate version that returns an iterator.

.. versionchanged:: 3.12
Slice objects are now :term:`hashable` (provided :attr:`~slice.start`,
:attr:`~slice.stop`, and :attr:`~slice.step` are hashable).

.. function:: sorted(iterable, /, *, key=None, reverse=False)

Expand Down
7 changes: 1 addition & 6 deletionsLib/test/test_capi/test_misc.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -415,11 +415,6 @@ def __setitem__(self, index, value):
with self.assertRaises(TypeError):
_testcapi.sequence_set_slice(None, 1, 3, 'xy')

mapping = {1: 'a', 2: 'b', 3: 'c'}
with self.assertRaises(TypeError):
_testcapi.sequence_set_slice(mapping, 1, 3, 'xy')
self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})

def test_sequence_del_slice(self):
# Correct case:
data = [1, 2, 3, 4, 5]
Expand DownExpand Up@@ -455,7 +450,7 @@ def __delitem__(self, index):
_testcapi.sequence_del_slice(None, 1, 3)

mapping = {1: 'a', 2: 'b', 3: 'c'}
with self.assertRaises(TypeError):
with self.assertRaises(KeyError):
_testcapi.sequence_del_slice(mapping, 1, 3)
self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'})

Expand Down
2 changes: 1 addition & 1 deletionLib/test/test_doctest.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -707,7 +707,7 @@ def non_Python_modules(): r"""

>>> import builtins
>>> tests = doctest.DocTestFinder().find(builtins)
>>>825 < len(tests) <845 # approximate number of objects with docstrings
>>>830 < len(tests) <850 # approximate number of objects with docstrings
True
>>> real_tests = [t for t in tests if len(t.examples) > 0]
>>> len(real_tests) # objects that actually have doctests
Expand Down
12 changes: 9 additions & 3 deletionsLib/test/test_slice.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -80,10 +80,16 @@ def test_repr(self):
self.assertEqual(repr(slice(1, 2, 3)), "slice(1, 2, 3)")

def test_hash(self):
# Verify clearing of SF bug #800796
self.assertRaises(TypeError, hash, slice(5))
self.assertEqual(hash(slice(5)), slice(5).__hash__())
self.assertEqual(hash(slice(1, 2)), slice(1, 2).__hash__())
self.assertEqual(hash(slice(1, 2, 3)), slice(1, 2, 3).__hash__())
self.assertNotEqual(slice(5), slice(6))

with self.assertRaises(TypeError):
hash(slice(1, 2, []))

with self.assertRaises(TypeError):
slice(5).__hash__()
hash(slice(4, {}))

def test_cmp(self):
s1 = slice(1, 2, 3)
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
Make the slice object hashable.
38 changes: 37 additions & 1 deletionObjects/sliceobject.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -628,6 +628,42 @@ slice_traverse(PySliceObject *v, visitproc visit, void *arg)
return 0;
}

/* code based on tuplehash() of Objects/tupleobject.c */
#if SIZEOF_PY_UHASH_T > 4
#define _PyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL)
#define _PyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL)
#define _PyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL)
#define _PyHASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */
#else
#define _PyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL)
#define _PyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL)
#define _PyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL)
#define _PyHASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */
#endif

static Py_hash_t
slicehash(PySliceObject *v)
{
Py_uhash_t acc = _PyHASH_XXPRIME_5;
#define _PyHASH_SLICE_PART(com) { \
Py_uhash_t lane = PyObject_Hash(v->com); \
if(lane == (Py_uhash_t)-1) { \
return -1; \
} \
acc += lane * _PyHASH_XXPRIME_2; \
acc = _PyHASH_XXROTATE(acc); \
acc *= _PyHASH_XXPRIME_1; \
}
_PyHASH_SLICE_PART(start);
_PyHASH_SLICE_PART(stop);
_PyHASH_SLICE_PART(step);
#undef _PyHASH_SLICE_PART
if(acc == (Py_uhash_t)-1) {
return 1546275796;
}
return acc;
}

PyTypeObject PySlice_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"slice", /* Name of this type */
Expand All@@ -642,7 +678,7 @@ PyTypeObject PySlice_Type = {
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
PyObject_HashNotImplemented, /* tp_hash */
(hashfunc)slicehash, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
Expand Down
2 changes: 1 addition & 1 deletionObjects/tupleobject.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -288,7 +288,7 @@ tuplerepr(PyTupleObject *v)

/* Hash for tuples. This is a slightly simplified version of the xxHash
non-cryptographic hash:
- we do not use anyparallellism, there is only 1 accumulator.
- we do not use anyparallelism, there is only 1 accumulator.
- we drop the final mixing since this is just a permutation of the
output space: it does not help against collisions.
- at the end, we mangle the length with a single constant.
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp