diff options
author | Guido van Rossum <guido@python.org> | 2001-09-25 16:25:58 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-09-25 16:25:58 (GMT) |
commit | 3926a63d0579bbeea6ab855a31dc38b9fa56b5e3 (patch) | |
tree | e8819c4a320d632f516cb269ebc28cd96793193f /Objects | |
parent | ad39aba2f67d3e7f4405f84167becab6d18ee9bc (diff) | |
download | cpython-3926a63d0579bbeea6ab855a31dc38b9fa56b5e3.zip cpython-3926a63d0579bbeea6ab855a31dc38b9fa56b5e3.tar.gz cpython-3926a63d0579bbeea6ab855a31dc38b9fa56b5e3.tar.bz2 |
- Provisional support for pickling new-style objects. (*)
- Made cls.__module__ writable.
- Ensure that obj.__dict__ is returned as {}, not None, even upon first
reference; it simply springs into life when you ask for it.
(*) The pickling support is provisional for the following reasons:
- It doesn't support classes with __slots__.
- It relies on additional support in copy_reg.py: the C method
__reduce__, defined in the object class, really calls calling
copy_reg._reduce(obj). Eventually the Python code in copy_reg.py
needs to be migrated to C, but I'd like to experiment with the
Python implementation first. The _reduce() code also relies on an
additional helper function, _reconstructor(), defined in
copy_reg.py; this should also be reimplemented in C.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 964164f..1354b81 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -53,6 +53,23 @@ type_module(PyTypeObject *type, void *context) return NULL; } +static int +type_set_module(PyTypeObject *type, PyObject *value, void *context) +{ + if (!(type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) || + strrchr(type->tp_name, '.')) { + PyErr_Format(PyExc_TypeError, + "can't set %s.__module__", type->tp_name); + return -1; + } + if (!value) { + PyErr_Format(PyExc_TypeError, + "can't delete %s.__module__", type->tp_name); + return -1; + } + return PyDict_SetItemString(type->tp_dict, "__module__", value); +} + static PyObject * type_dict(PyTypeObject *type, void *context) { @@ -93,7 +110,7 @@ type_dynamic(PyTypeObject *type, void *context) PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, - {"__module__", (getter)type_module, NULL, NULL}, + {"__module__", (getter)type_module, (setter)type_set_module, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, {"__defined__", (getter)type_defined, NULL, NULL}, {"__dynamic__", (getter)type_dynamic, NULL, NULL}, @@ -656,14 +673,10 @@ subtype_dict(PyObject *obj, void *context) return NULL; } dict = *dictptr; - if (dict == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - else { - Py_INCREF(dict); - return dict; - } + if (dict == NULL) + *dictptr = dict = PyDict_New(); + Py_XINCREF(dict); + return dict; } PyGetSetDef subtype_getsets[] = { @@ -1283,6 +1296,31 @@ static PyGetSetDef object_getsets[] = { {0} }; +static PyObject * +object_reduce(PyObject *self, PyObject *args) +{ + /* Call copy_reg._reduce(self) */ + static PyObject *copy_reg_str; + PyObject *copy_reg, *res; + + if (!copy_reg_str) { + copy_reg_str = PyString_InternFromString("copy_reg"); + if (copy_reg_str == NULL) + return NULL; + } + copy_reg = PyImport_Import(copy_reg_str); + if (!copy_reg) + return NULL; + res = PyEval_CallMethod(copy_reg, "_reduce", "(O)", self); + Py_DECREF(copy_reg); + return res; +} + +static PyMethodDef object_methods[] = { + {"__reduce__", object_reduce, METH_NOARGS, "helper for pickle"}, + {0} +}; + PyTypeObject PyBaseObject_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ @@ -1312,7 +1350,7 @@ PyTypeObject PyBaseObject_Type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + object_methods, /* tp_methods */ 0, /* tp_members */ object_getsets, /* tp_getset */ 0, /* tp_base */ @@ -3009,7 +3047,8 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name) res = PyObject_GenericGetAttr(self, name); else res = PyObject_CallFunction(getattribute, "OO", self, name); - if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + if (getattr != NULL && + res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); res = PyObject_CallFunction(getattr, "OO", self, name); } |