Skip to content

Commit b30e19a

Browse files
author
Marco Sulla
committed
Aligned all py versions
1 parent 07102a8 commit b30e19a

File tree

4 files changed

+692
-172
lines changed

4 files changed

+692
-172
lines changed

frozendict/src/3_6/frozendictobject.c

Lines changed: 173 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -656,12 +656,68 @@ static int frozendict_update_common(PyObject* self,
656656
return result;
657657
}
658658

659+
/* Forward */
660+
static PyObject *frozendictkeys_new(PyObject *, PyObject *);
661+
static PyObject *frozendictitems_new(PyObject *, PyObject *);
662+
static PyObject *frozendictvalues_new(PyObject *, PyObject *);
663+
664+
#define MINUSONE_HASH ((Py_hash_t) -1)
665+
666+
static Py_hash_t frozendict_hash(PyObject* self) {
667+
PyFrozenDictObject* frozen_self = (PyFrozenDictObject*) self;
668+
Py_hash_t hash;
669+
670+
if (frozen_self->ma_hash_calculated) {
671+
hash = frozen_self->ma_hash;
672+
673+
if (hash == MINUSONE_HASH) {
674+
PyErr_SetObject(PyExc_TypeError, Py_None);
675+
}
676+
}
677+
else {
678+
PyObject* frozen_items_tmp = frozendictitems_new(self, NULL);
679+
int save_hash = 1;
680+
681+
if (frozen_items_tmp == NULL) {
682+
hash = MINUSONE_HASH;
683+
save_hash = 0;
684+
}
685+
else {
686+
PyObject* frozen_items = PyFrozenSet_New(frozen_items_tmp);
687+
688+
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+
695+
hash = MINUSONE_HASH;
696+
}
697+
else {
698+
hash = PyFrozenSet_Type.tp_hash(frozen_items);
699+
}
700+
}
701+
702+
if (save_hash) {
703+
frozen_self->ma_hash = hash;
704+
frozen_self->ma_hash_calculated = 1;
705+
}
706+
}
707+
708+
return hash;
709+
}
710+
659711
static PyObject* frozendict_copy(PyObject* o, PyObject* Py_UNUSED(ignored)) {
660712
if (PyAnyFrozenDict_CheckExact(o)) {
661713
Py_INCREF(o);
662714
return o;
663715
}
664716

717+
if (! PyAnyFrozenDict_Check(o)) {
718+
Py_RETURN_NOTIMPLEMENTED;
719+
}
720+
665721
PyObject* args = PyTuple_New(1);
666722

667723
if (args == NULL) {
@@ -676,6 +732,110 @@ static PyObject* frozendict_copy(PyObject* o, PyObject* Py_UNUSED(ignored)) {
676732
return PyObject_Call((PyObject *) type, args, NULL);
677733
}
678734

735+
PyObject* frozendict_deepcopy(PyObject* self, PyObject* memo) {
736+
if (PyAnyFrozenDict_CheckExact(self)) {
737+
frozendict_hash(self);
738+
739+
if (PyErr_Occurred()) {
740+
PyErr_Clear();
741+
}
742+
else {
743+
Py_INCREF(self);
744+
return self;
745+
}
746+
}
747+
748+
if (! PyAnyFrozenDict_Check(self)) {
749+
Py_RETURN_NOTIMPLEMENTED;
750+
}
751+
752+
PyObject* d = PyDict_New();
753+
754+
if (d == NULL) {
755+
return NULL;
756+
}
757+
758+
PyObject* copy_module_name = NULL;
759+
PyObject* copy_module = NULL;
760+
PyObject* deepcopy_fun = NULL;
761+
PyObject* deep_args = NULL;
762+
PyObject* deep_d = NULL;
763+
PyObject* args = NULL;
764+
PyObject* res = NULL;
765+
int decref_d = 1;
766+
int decref_deep_d = 1;
767+
768+
if (PyDict_Merge(d, self, 1)) {
769+
goto end;
770+
}
771+
772+
copy_module_name = PyUnicode_FromString("copy");
773+
774+
if (copy_module_name == NULL) {
775+
goto end;
776+
}
777+
778+
copy_module = PyImport_Import(copy_module_name);
779+
780+
if (copy_module == NULL) {
781+
goto end;
782+
}
783+
784+
deepcopy_fun = PyObject_GetAttrString(copy_module, "deepcopy");
785+
786+
if (deepcopy_fun == NULL) {
787+
goto end;
788+
}
789+
790+
deep_args = PyTuple_New(2);
791+
792+
if (deep_args == NULL) {
793+
goto end;
794+
}
795+
796+
PyTuple_SET_ITEM(deep_args, 0, d);
797+
decref_d = 0;
798+
799+
Py_INCREF(memo);
800+
PyTuple_SET_ITEM(deep_args, 1, memo);
801+
802+
deep_d = PyObject_CallObject(deepcopy_fun, deep_args);
803+
804+
if (deep_d == NULL) {
805+
goto end;
806+
}
807+
808+
args = PyTuple_New(1);
809+
810+
if (args == NULL) {
811+
goto end;
812+
}
813+
814+
PyTuple_SET_ITEM(args, 0, deep_d);
815+
decref_deep_d = 0;
816+
817+
PyTypeObject* type = Py_TYPE(self);
818+
819+
res = PyObject_Call((PyObject *) type, args, NULL);
820+
821+
end:
822+
Py_XDECREF(args);
823+
Py_XDECREF(deep_args);
824+
Py_XDECREF(deepcopy_fun);
825+
Py_XDECREF(copy_module);
826+
Py_XDECREF(copy_module_name);
827+
828+
if (decref_d) {
829+
Py_DECREF(d);
830+
}
831+
832+
if (decref_deep_d) {
833+
Py_DECREF(deep_d);
834+
}
835+
836+
return res;
837+
}
838+
679839
static int frozendict_equal(PyDictObject* a, PyDictObject* b) {
680840
if (a == b) {
681841
return 1;
@@ -741,11 +901,6 @@ static Py_ssize_t dict_get_index(PyDictObject *self, PyObject *key) {
741901
return (self->ma_keys->dk_lookup) (self, key, hash, &val, NULL);
742902
}
743903

744-
/* Forward */
745-
static PyObject *frozendictkeys_new(PyObject *, PyObject *);
746-
static PyObject *frozendictitems_new(PyObject *, PyObject *);
747-
static PyObject *frozendictvalues_new(PyObject *, PyObject *);
748-
749904
static PyObject *
750905
frozendict_reduce(PyFrozenDictObject* mp, PyObject *Py_UNUSED(ignored))
751906
{
@@ -755,7 +910,10 @@ frozendict_reduce(PyFrozenDictObject* mp, PyObject *Py_UNUSED(ignored))
755910
return NULL;
756911
}
757912

758-
PyDict_Merge(d, (PyObject *)mp, 1);
913+
if (PyDict_Merge(d, (PyObject *)mp, 1)) {
914+
Py_DECREF(d);
915+
return NULL;
916+
}
759917

760918
return Py_BuildValue("O(N)", Py_TYPE(mp), d);
761919
}
@@ -946,6 +1104,10 @@ static PyMethodDef frozendict_mapp_methods[] = {
9461104
{"fromkeys", (PyCFunction)frozendict_fromkeys, METH_VARARGS|METH_CLASS, dict_fromkeys__doc__},
9471105
{"copy", (PyCFunction)frozendict_copy, METH_NOARGS,
9481106
copy__doc__},
1107+
{"__copy__", (PyCFunction)frozendict_copy, METH_NOARGS,
1108+
"Returns a copy of the object."},
1109+
{"__deepcopy__", (PyCFunction)frozendict_deepcopy, METH_O,
1110+
"Returns a deepcopy of the object."},
9491111
DICT___REVERSED___METHODDEF
9501112
{"__reduce__", (PyCFunction)(void(*)(void))frozendict_reduce, METH_NOARGS,
9511113
""},
@@ -980,6 +1142,10 @@ static PyMethodDef coold_mapp_methods[] = {
9801142
{"fromkeys", (PyCFunction)frozendict_fromkeys, METH_VARARGS|METH_CLASS, dict_fromkeys__doc__},
9811143
{"copy", (PyCFunction)frozendict_copy, METH_NOARGS,
9821144
copy__doc__},
1145+
{"__copy__", (PyCFunction)frozendict_copy, METH_NOARGS,
1146+
"Returns a copy of the object."},
1147+
{"__deepcopy__", (PyCFunction)frozendict_deepcopy, METH_O,
1148+
"Returns a deepcopy of the object."},
9831149
DICT___REVERSED___METHODDEF
9841150
{"__reduce__", (PyCFunction)(void(*)(void))frozendict_reduce, METH_NOARGS,
9851151
""},
@@ -1102,43 +1268,6 @@ static PyObject* frozendict_new(PyTypeObject* type, PyObject* args, PyObject* kw
11021268
return _frozendict_new(type, args, kwds, 1);
11031269
}
11041270

1105-
#define MINUSONE_HASH ((Py_hash_t) -1)
1106-
1107-
static Py_hash_t frozendict_hash(PyObject* self) {
1108-
PyFrozenDictObject* frozen_self = (PyFrozenDictObject*) self;
1109-
Py_hash_t hash;
1110-
1111-
if (frozen_self->ma_hash_calculated) {
1112-
hash = frozen_self->ma_hash;
1113-
1114-
if (hash == MINUSONE_HASH) {
1115-
PyErr_SetObject(PyExc_TypeError, Py_None);
1116-
}
1117-
}
1118-
else {
1119-
PyObject* frozen_items_tmp = frozendictitems_new(self, NULL);
1120-
1121-
if (frozen_items_tmp == NULL) {
1122-
hash = MINUSONE_HASH;
1123-
}
1124-
else {
1125-
PyObject* frozen_items = PyFrozenSet_New(frozen_items_tmp);
1126-
1127-
if (frozen_items == NULL) {
1128-
hash = MINUSONE_HASH;
1129-
}
1130-
else {
1131-
hash = PyFrozenSet_Type.tp_hash(frozen_items);
1132-
}
1133-
}
1134-
1135-
frozen_self->ma_hash = hash;
1136-
frozen_self->ma_hash_calculated = 1;
1137-
}
1138-
1139-
return hash;
1140-
}
1141-
11421271
static PyObject* frozendict_or(PyObject *self, PyObject *other) {
11431272
if (! PyAnyFrozenDict_Check(self) || ! PyAnyDict_Check(other)) {
11441273
Py_RETURN_NOTIMPLEMENTED;
@@ -1431,6 +1560,7 @@ static PyObject* frozendictiter_iternextitem(dictiterobject* di) {
14311560
assert(key != NULL);
14321561
assert(val != NULL);
14331562
di->di_pos++;
1563+
di->len--;
14341564
Py_INCREF(key);
14351565
Py_INCREF(val);
14361566

0 commit comments

Comments
 (0)