self.assertEqual(fd, frozendict(a=None, b=None, c=None))
self.assertEqual(type(fd), FrozenDictSubclass2)
+ # Dict subclass which overrides the constructor
+ class DictSubclass(dict):
+ def __new__(self):
+ return created
+
+ fd = DictSubclass.fromkeys("abc")
+ self.assertEqual(fd, frozendict(x=1, a=None, b=None, c=None))
+ self.assertEqual(type(fd), DictSubclass)
+ self.assertEqual(created, frozendict(x=1))
+
if __name__ == "__main__":
unittest.main()
// Forward declarations
static PyObject* frozendict_new(PyTypeObject *type, PyObject *args,
PyObject *kwds);
+static PyObject* dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static int dict_merge(PyObject *a, PyObject *b, int override);
return NULL;
}
- // If cls is a frozendict subclass with overridden constructor,
+ // If cls is a dict or frozendict subclass with overridden constructor,
// copy the frozendict.
PyTypeObject *cls_type = _PyType_CAST(cls);
- if (PyFrozenDict_Check(d)
- && PyObject_IsSubclass(cls, (PyObject*)&PyFrozenDict_Type)
- && cls_type->tp_new != frozendict_new)
- {
+ if (PyFrozenDict_Check(d) && cls_type->tp_new != frozendict_new) {
// Subclass-friendly copy
- PyObject *copy = frozendict_new(cls_type, NULL, NULL);
+ PyObject *copy;
+ if (PyObject_IsSubclass(cls, (PyObject*)&PyFrozenDict_Type)) {
+ copy = frozendict_new(cls_type, NULL, NULL);
+ }
+ else {
+ copy = dict_new(cls_type, NULL, NULL);
+ }
if (copy == NULL) {
Py_DECREF(d);
return NULL;