Skip to content

Commit ddadbb5

Browse files
author
Marco Sulla
committed
if frozendict is not hashable, hash value is not cached anymore
1 parent 7844058 commit ddadbb5

File tree

11 files changed

+29
-106
lines changed

11 files changed

+29
-106
lines changed

frozendict/core.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def __new__(e4b37cdf_d78a_4632_bade_6f0579d8efac, *args, **kwargs):
5959
# empty singleton - end
6060

6161
if continue_creation:
62-
object.__setattr__(self, "_hash", None)
62+
object.__setattr__(self, "_hash", -1)
6363

6464
return self
6565

@@ -72,21 +72,14 @@ def __hash__(self, *args, **kwargs):
7272
TypeError.
7373
"""
7474

75-
if self._hash != None:
75+
if self._hash != -1:
7676
_hash = self._hash
7777
else:
78-
try:
79-
fs = frozenset(self.items())
80-
except TypeError:
81-
_hash = -1
82-
else:
83-
_hash = hash(fs)
78+
fs = frozenset(self.items())
79+
_hash = hash(fs)
8480

8581
object.__setattr__(self, "_hash", _hash)
8682

87-
if _hash == -1:
88-
raise TypeError("Not all values are hashable.")
89-
9083
return _hash
9184

9285
def __repr__(self, *args, **kwargs):

frozendict/src/3_10/Include/cpython/frozendictobject.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ typedef struct {
1111
PyObject** ma_values;
1212

1313
Py_hash_t ma_hash;
14-
short ma_hash_calculated;
1514
} PyFrozenDictObject;

frozendict/src/3_10/frozendictobject.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -655,12 +655,8 @@ static Py_hash_t frozendict_hash(PyObject* self) {
655655
PyFrozenDictObject* frozen_self = (PyFrozenDictObject*) self;
656656
Py_hash_t hash;
657657

658-
if (frozen_self->ma_hash_calculated) {
658+
if (frozen_self->ma_hash != MINUSONE_HASH) {
659659
hash = frozen_self->ma_hash;
660-
661-
if (hash == MINUSONE_HASH) {
662-
PyErr_SetObject(PyExc_TypeError, Py_None);
663-
}
664660
}
665661
else {
666662
PyObject* frozen_items_tmp = frozendictitems_new(self, NULL);
@@ -674,13 +670,8 @@ static Py_hash_t frozendict_hash(PyObject* self) {
674670
PyObject* frozen_items = PyFrozenSet_New(frozen_items_tmp);
675671

676672
if (frozen_items == NULL) {
677-
PyObject* err = PyErr_Occurred();
678-
679-
if (err == NULL || ! PyErr_GivenExceptionMatches(err, PyExc_TypeError)) {
680-
save_hash = 0;
681-
}
682-
683673
hash = MINUSONE_HASH;
674+
save_hash = 0;
684675
}
685676
else {
686677
hash = PyFrozenSet_Type.tp_hash(frozen_items);
@@ -689,7 +680,6 @@ static Py_hash_t frozendict_hash(PyObject* self) {
689680

690681
if (save_hash) {
691682
frozen_self->ma_hash = hash;
692-
frozen_self->ma_hash_calculated = 1;
693683
}
694684
}
695685

@@ -930,8 +920,7 @@ static PyObject* frozendict_clone(PyObject* self) {
930920
}
931921

932922
new_mp->ma_used = mp->ma_used;
933-
new_mp->ma_hash = -1;
934-
new_mp->ma_hash_calculated = 0;
923+
new_mp->ma_hash = MINUSONE_HASH;
935924
new_mp->ma_version_tag = DICT_NEXT_VERSION();
936925

937926
ASSERT_CONSISTENT(new_mp);
@@ -1090,8 +1079,7 @@ static PyObject* frozendict_del(PyObject* self,
10901079
assert(new_keys->dk_usable >= new_mp->ma_used);
10911080

10921081
new_mp->ma_keys = new_keys;
1093-
new_mp->ma_hash = -1;
1094-
new_mp->ma_hash_calculated = 0;
1082+
new_mp->ma_hash = MINUSONE_HASH;
10951083
new_mp->ma_version_tag = DICT_NEXT_VERSION();
10961084

10971085
PyObject* key;
@@ -1210,8 +1198,7 @@ static PyObject* frozendict_new_barebone(PyTypeObject* type) {
12101198
mp->ma_keys = NULL;
12111199
mp->ma_values = NULL;
12121200
mp->ma_used = 0;
1213-
mp->ma_hash = -1;
1214-
mp->ma_hash_calculated = 0;
1201+
mp->ma_hash = MINUSONE_HASH;
12151202

12161203
return self;
12171204
}

frozendict/src/3_6/Include/cpython/frozendictobject.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ typedef struct {
1111
PyObject** ma_values;
1212

1313
Py_hash_t ma_hash;
14-
short ma_hash_calculated;
1514
} PyFrozenDictObject;

frozendict/src/3_6/frozendictobject.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -667,12 +667,8 @@ static Py_hash_t frozendict_hash(PyObject* self) {
667667
PyFrozenDictObject* frozen_self = (PyFrozenDictObject*) self;
668668
Py_hash_t hash;
669669

670-
if (frozen_self->ma_hash_calculated) {
670+
if (frozen_self->ma_hash != MINUSONE_HASH) {
671671
hash = frozen_self->ma_hash;
672-
673-
if (hash == MINUSONE_HASH) {
674-
PyErr_SetObject(PyExc_TypeError, Py_None);
675-
}
676672
}
677673
else {
678674
PyObject* frozen_items_tmp = frozendictitems_new(self, NULL);
@@ -686,13 +682,8 @@ static Py_hash_t frozendict_hash(PyObject* self) {
686682
PyObject* frozen_items = PyFrozenSet_New(frozen_items_tmp);
687683

688684
if (frozen_items == NULL) {
689-
PyObject* err = PyErr_Occurred();
690-
691-
if (err == NULL || ! PyErr_GivenExceptionMatches(err, PyExc_TypeError)) {
692-
save_hash = 0;
693-
}
694-
695685
hash = MINUSONE_HASH;
686+
save_hash = 0;
696687
}
697688
else {
698689
hash = PyFrozenSet_Type.tp_hash(frozen_items);
@@ -701,7 +692,6 @@ static Py_hash_t frozendict_hash(PyObject* self) {
701692

702693
if (save_hash) {
703694
frozen_self->ma_hash = hash;
704-
frozen_self->ma_hash_calculated = 1;
705695
}
706696
}
707697

@@ -942,8 +932,7 @@ static PyObject* frozendict_clone(PyObject* self) {
942932
}
943933

944934
new_mp->ma_used = mp->ma_used;
945-
new_mp->ma_hash = -1;
946-
new_mp->ma_hash_calculated = 0;
935+
new_mp->ma_hash = MINUSONE_HASH;
947936
new_mp->ma_version_tag = DICT_NEXT_VERSION();
948937

949938
ASSERT_CONSISTENT(new_mp);
@@ -1087,8 +1076,7 @@ static PyObject* frozendict_del(PyObject* self,
10871076
assert(new_keys->dk_usable >= new_mp->ma_used);
10881077

10891078
new_mp->ma_keys = new_keys;
1090-
new_mp->ma_hash = -1;
1091-
new_mp->ma_hash_calculated = 0;
1079+
new_mp->ma_hash = MINUSONE_HASH;
10921080
new_mp->ma_version_tag = DICT_NEXT_VERSION();
10931081

10941082
PyObject* key;
@@ -1205,8 +1193,7 @@ static PyObject* frozendict_new_barebone(PyTypeObject* type) {
12051193
mp->ma_keys = NULL;
12061194
mp->ma_values = NULL;
12071195
mp->ma_used = 0;
1208-
mp->ma_hash = -1;
1209-
mp->ma_hash_calculated = 0;
1196+
mp->ma_hash = MINUSONE_HASH;
12101197

12111198
return self;
12121199
}

frozendict/src/3_7/Include/cpython/frozendictobject.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ typedef struct {
1111
PyObject** ma_values;
1212

1313
Py_hash_t ma_hash;
14-
short ma_hash_calculated;
1514
} PyFrozenDictObject;

frozendict/src/3_7/frozendictobject.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -661,12 +661,8 @@ static Py_hash_t frozendict_hash(PyObject* self) {
661661
PyFrozenDictObject* frozen_self = (PyFrozenDictObject*) self;
662662
Py_hash_t hash;
663663

664-
if (frozen_self->ma_hash_calculated) {
664+
if (frozen_self->ma_hash != MINUSONE_HASH) {
665665
hash = frozen_self->ma_hash;
666-
667-
if (hash == MINUSONE_HASH) {
668-
PyErr_SetObject(PyExc_TypeError, Py_None);
669-
}
670666
}
671667
else {
672668
PyObject* frozen_items_tmp = frozendictitems_new(self, NULL);
@@ -680,13 +676,8 @@ static Py_hash_t frozendict_hash(PyObject* self) {
680676
PyObject* frozen_items = PyFrozenSet_New(frozen_items_tmp);
681677

682678
if (frozen_items == NULL) {
683-
PyObject* err = PyErr_Occurred();
684-
685-
if (err == NULL || ! PyErr_GivenExceptionMatches(err, PyExc_TypeError)) {
686-
save_hash = 0;
687-
}
688-
689679
hash = MINUSONE_HASH;
680+
save_hash = 0;
690681
}
691682
else {
692683
hash = PyFrozenSet_Type.tp_hash(frozen_items);
@@ -695,7 +686,6 @@ static Py_hash_t frozendict_hash(PyObject* self) {
695686

696687
if (save_hash) {
697688
frozen_self->ma_hash = hash;
698-
frozen_self->ma_hash_calculated = 1;
699689
}
700690
}
701691

@@ -936,8 +926,7 @@ static PyObject* frozendict_clone(PyObject* self) {
936926
}
937927

938928
new_mp->ma_used = mp->ma_used;
939-
new_mp->ma_hash = -1;
940-
new_mp->ma_hash_calculated = 0;
929+
new_mp->ma_hash = MINUSONE_HASH;
941930
new_mp->ma_version_tag = DICT_NEXT_VERSION();
942931

943932
ASSERT_CONSISTENT(new_mp);
@@ -1096,8 +1085,7 @@ static PyObject* frozendict_del(PyObject* self,
10961085
assert(new_keys->dk_usable >= new_mp->ma_used);
10971086

10981087
new_mp->ma_keys = new_keys;
1099-
new_mp->ma_hash = -1;
1100-
new_mp->ma_hash_calculated = 0;
1088+
new_mp->ma_hash = MINUSONE_HASH;
11011089
new_mp->ma_version_tag = DICT_NEXT_VERSION();
11021090

11031091
PyObject* key;
@@ -1215,8 +1203,7 @@ static PyObject* frozendict_new_barebone(PyTypeObject* type) {
12151203
mp->ma_keys = NULL;
12161204
mp->ma_values = NULL;
12171205
mp->ma_used = 0;
1218-
mp->ma_hash = -1;
1219-
mp->ma_hash_calculated = 0;
1206+
mp->ma_hash = MINUSONE_HASH;
12201207

12211208
return self;
12221209
}

frozendict/src/3_8/Include/cpython/frozendictobject.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ typedef struct {
1111
PyObject** ma_values;
1212

1313
Py_hash_t ma_hash;
14-
short ma_hash_calculated;
1514
} PyFrozenDictObject;

frozendict/src/3_8/frozendictobject.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -661,12 +661,8 @@ static Py_hash_t frozendict_hash(PyObject* self) {
661661
PyFrozenDictObject* frozen_self = (PyFrozenDictObject*) self;
662662
Py_hash_t hash;
663663

664-
if (frozen_self->ma_hash_calculated) {
664+
if (frozen_self->ma_hash != MINUSONE_HASH) {
665665
hash = frozen_self->ma_hash;
666-
667-
if (hash == MINUSONE_HASH) {
668-
PyErr_SetObject(PyExc_TypeError, Py_None);
669-
}
670666
}
671667
else {
672668
PyObject* frozen_items_tmp = frozendictitems_new(self, NULL);
@@ -680,13 +676,8 @@ static Py_hash_t frozendict_hash(PyObject* self) {
680676
PyObject* frozen_items = PyFrozenSet_New(frozen_items_tmp);
681677

682678
if (frozen_items == NULL) {
683-
PyObject* err = PyErr_Occurred();
684-
685-
if (err == NULL || ! PyErr_GivenExceptionMatches(err, PyExc_TypeError)) {
686-
save_hash = 0;
687-
}
688-
689679
hash = MINUSONE_HASH;
680+
save_hash = 0;
690681
}
691682
else {
692683
hash = PyFrozenSet_Type.tp_hash(frozen_items);
@@ -695,7 +686,6 @@ static Py_hash_t frozendict_hash(PyObject* self) {
695686

696687
if (save_hash) {
697688
frozen_self->ma_hash = hash;
698-
frozen_self->ma_hash_calculated = 1;
699689
}
700690
}
701691

@@ -936,8 +926,7 @@ static PyObject* frozendict_clone(PyObject* self) {
936926
}
937927

938928
new_mp->ma_used = mp->ma_used;
939-
new_mp->ma_hash = -1;
940-
new_mp->ma_hash_calculated = 0;
929+
new_mp->ma_hash = MINUSONE_HASH;
941930
new_mp->ma_version_tag = DICT_NEXT_VERSION();
942931

943932
ASSERT_CONSISTENT(new_mp);
@@ -1096,8 +1085,7 @@ static PyObject* frozendict_del(PyObject* self,
10961085
assert(new_keys->dk_usable >= new_mp->ma_used);
10971086

10981087
new_mp->ma_keys = new_keys;
1099-
new_mp->ma_hash = -1;
1100-
new_mp->ma_hash_calculated = 0;
1088+
new_mp->ma_hash = MINUSONE_HASH;
11011089
new_mp->ma_version_tag = DICT_NEXT_VERSION();
11021090

11031091
PyObject* key;
@@ -1215,8 +1203,7 @@ static PyObject* frozendict_new_barebone(PyTypeObject* type) {
12151203
mp->ma_keys = NULL;
12161204
mp->ma_values = NULL;
12171205
mp->ma_used = 0;
1218-
mp->ma_hash = -1;
1219-
mp->ma_hash_calculated = 0;
1206+
mp->ma_hash = MINUSONE_HASH;
12201207

12211208
return self;
12221209
}

frozendict/src/3_9/Include/cpython/frozendictobject.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@ typedef struct {
1111
PyObject** ma_values;
1212

1313
Py_hash_t ma_hash;
14-
short ma_hash_calculated;
1514
} PyFrozenDictObject;

0 commit comments

Comments
 (0)