[Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.73,2.74

Guido van Rossum gvanrossum@users.sourceforge.net
Tue, 25 Sep 2001 09:26:00 -0700


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv12467/Objects

Modified Files:
	typeobject.c 
Log Message:
- 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.



Index: typeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v
retrieving revision 2.73
retrieving revision 2.74
diff -C2 -d -r2.73 -r2.74
*** typeobject.c	2001/09/25 03:56:29	2.73
--- typeobject.c	2001/09/25 16:25:58	2.74
***************
*** 54,57 ****
--- 54,74 ----
  }
  
+ 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)
***************
*** 94,98 ****
  PyGetSetDef type_getsets[] = {
  	{"__name__", (getter)type_name, NULL, NULL},
! 	{"__module__", (getter)type_module, NULL, NULL},
  	{"__dict__",  (getter)type_dict,  NULL, NULL},
  	{"__defined__",  (getter)type_defined,  NULL, NULL},
--- 111,115 ----
  PyGetSetDef type_getsets[] = {
  	{"__name__", (getter)type_name, NULL, NULL},
! 	{"__module__", (getter)type_module, (setter)type_set_module, NULL},
  	{"__dict__",  (getter)type_dict,  NULL, NULL},
  	{"__defined__",  (getter)type_defined,  NULL, NULL},
***************
*** 657,668 ****
  	}
  	dict = *dictptr;
! 	if (dict == NULL) {
! 		Py_INCREF(Py_None);
! 		return Py_None;
! 	}
! 	else {
! 		Py_INCREF(dict);
! 		return dict;
! 	}
  }
  
--- 674,681 ----
  	}
  	dict = *dictptr;
! 	if (dict == NULL)
! 		*dictptr = dict = PyDict_New();
! 	Py_XINCREF(dict);
! 	return dict;
  }
  
***************
*** 1284,1287 ****
--- 1297,1325 ----
  };
  
+ 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)
***************
*** 1313,1317 ****
  	0,					/* tp_iter */
  	0,					/* tp_iternext */
! 	0,					/* tp_methods */
  	0,					/* tp_members */
  	object_getsets,				/* tp_getset */
--- 1351,1355 ----
  	0,					/* tp_iter */
  	0,					/* tp_iternext */
! 	object_methods,				/* tp_methods */
  	0,					/* tp_members */
  	object_getsets,				/* tp_getset */
***************
*** 3010,3014 ****
  	else
  		res = PyObject_CallFunction(getattribute, "OO", self, name);
! 	if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
  		PyErr_Clear();
  		res = PyObject_CallFunction(getattr, "OO", self, name);
--- 3048,3053 ----
  	else
  		res = PyObject_CallFunction(getattribute, "OO", self, name);
! 	if (getattr != NULL &&
! 	    res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
  		PyErr_Clear();
  		res = PyObject_CallFunction(getattr, "OO", self, name);