[Python-checkins] python/nondist/sandbox/datetime datetime.c,1.35,1.36 obj_date.c,1.16,1.17 obj_datetime.c,1.11,1.12

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Mon, 02 Dec 2002 18:27:04 -0800


Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv15088

Modified Files:
	datetime.c obj_date.c obj_datetime.c 
Log Message:
Following a suggestion from Fred, reworked pickling of date and datetime
objects to get the copy_reg module involved.  I'm not sure how much space
this saves -- the pickler function still needs to create a tuple with an
embedded tuple, and the name of the unpickler function gets stuffed into
the pickle too (hmm -- since the unpickler function is registered with
copy_reg, why does its name need to be repeated in the pickle?).  The
__reduce__ code is #if 0'ed out cuz I'm not sure this is an improvement.

No matter how I cut this, pickling is painful.


Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -d -r1.35 -r1.36
*** datetime.c	3 Dec 2002 00:20:47 -0000	1.35
--- datetime.c	3 Dec 2002 02:27:01 -0000	1.36
***************
*** 536,540 ****
  }
  
! static PyObject* three_ones = NULL;	/* an argument tuple for __reduce__ */
  
  /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
--- 536,545 ----
  }
  
! #if 0
! static PyObject *three_ones = NULL;	/* an argument tuple for __reduce__ */
! #endif
! 
! static PyObject *date_unpickler_object = NULL;
! static PyObject *datetime_unpickler_object = NULL;
  
  /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
***************
*** 567,570 ****
--- 572,583 ----
  #include "obj_datetime.c"
  
+ static PyMethodDef module_methods[] = {
+ 	{"_date_pickler",	(PyCFunction)date_pickler,	METH_O, NULL},
+ 	{"_date_unpickler",	(PyCFunction)date_unpickler, 	METH_O, NULL},
+ 	{"_datetime_pickler",	(PyCFunction)datetime_pickler,	METH_O, NULL},
+ 	{"_datetime_unpickler",	(PyCFunction)datetime_unpickler,METH_O, NULL},
+ 	{NULL, NULL}
+ };
+ 
  void
  init_datetime(void)
***************
*** 632,636 ****
  
  	/* module initialization */
! 	m = Py_InitModule3("_datetime", NULL,
  			   "Fast implementation of the datetime type.");
  	PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
--- 645,649 ----
  
  	/* module initialization */
! 	m = Py_InitModule3("_datetime", module_methods,
  			   "Fast implementation of the datetime type.");
  	PyModule_AddIntConstant(m, "MINYEAR", MINYEAR);
***************
*** 678,681 ****
--- 691,735 ----
  	us_per_week = PyLong_FromDouble(604800000000.0);
  
+ 	/* Pickling support, via registering functions with copy_reg. */
+ 	{
+ 		PyObject *temp;
+ 		PyObject *copyreg_pickle;
+ 		PyObject *pickler;
+ 
+ 		temp = PyImport_ImportModule("copy_reg");
+ 		assert(temp);
+ 		copyreg_pickle = PyObject_GetAttrString(temp, "pickle");
+ 		assert(copyreg_pickle);
+ 		Py_DECREF(temp);
+ 
+ 		pickler = PyObject_GetAttrString(m, "_date_pickler");
+ 		assert(pickler);
+ 		date_unpickler_object = PyObject_GetAttrString(m,
+ 						"_date_unpickler");
+ 		assert(date_unpickler_object);
+ 	    	temp = PyObject_CallFunction(copyreg_pickle, "OOO",
+ 	    				     &PyDateTime_DateType,
+ 	    				     pickler,
+ 		                             date_unpickler_object);
+ 		assert(temp);
+ 		Py_DECREF(temp);
+ 		Py_DECREF(pickler);
+ 
+ 		pickler = PyObject_GetAttrString(m, "_datetime_pickler");
+ 		assert(pickler);
+ 		datetime_unpickler_object = PyObject_GetAttrString(m,
+ 						"_datetime_unpickler");
+ 		assert(datetime_unpickler_object);
+ 	    	temp = PyObject_CallFunction(copyreg_pickle, "OOO",
+ 	    				     &PyDateTime_DateTimeType,
+ 	    				     pickler,
+ 		                             datetime_unpickler_object);
+ 		assert(temp);
+ 		Py_DECREF(temp);
+ 		Py_DECREF(pickler);
+ 
+ 		Py_DECREF(copyreg_pickle);
+ 	}
+ #if 0
  	{
  		/* Build (1, 1, 1) so __reduce__ for date-like objects
***************
*** 696,698 ****
--- 750,753 ----
  		Py_DECREF(one);
  	}
+ #endif
  }

Index: obj_date.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_date.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** obj_date.c	2 Dec 2002 22:07:16 -0000	1.16
--- obj_date.c	3 Dec 2002 02:27:01 -0000	1.17
***************
*** 406,410 ****
  }
  
! /* XXX This is a ridiculously inefficient way to pickle a short string. */
  static PyObject *
  date_reduce(PyDateTime_Date* self)
--- 406,410 ----
  }
  
! #if 0
  static PyObject *
  date_reduce(PyDateTime_Date* self)
***************
*** 423,426 ****
--- 423,451 ----
  	return result;
  }
+ #endif
+ 
+ /* XXX This seems a ridiculously inefficient way to pickle a short string. */
+ static PyObject *
+ date_pickler(PyObject *module, PyDateTime_Date *date)
+ {
+ 	PyObject *state = date_getstate(date);
+ 	PyObject *tuple = Py_BuildValue("O(O)",
+ 		date_unpickler_object, state);
+ 	return tuple;
+ }
+ 
+ static PyObject *
+ date_unpickler(PyObject *module, PyObject *arg)
+ {
+ 	PyDateTime_Date *self;
+ 	PyObject *res;
+ 
+ 	self = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
+ 	if (self != NULL) {
+ 		res = date_setstate(self, arg);
+ 		Py_XDECREF(res);
+ 	}
+ 	return (PyObject *)self;
+ }
  
  static PyMethodDef date_methods[] = {
***************
*** 452,457 ****
--- 477,484 ----
  	{"__setstate__", (PyCFunction)date_setstate,	METH_O,
  	 	PyDoc_STR("__setstate__(state)")},
+ #if 0
  	{"__reduce__", (PyCFunction)date_reduce, 	METH_NOARGS,
  		NULL},
+ #endif
  	{"__getstate__", (PyCFunction)date_getstate,	METH_NOARGS,
  	 	PyDoc_STR("__getstate__() -> state")},

Index: obj_datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_datetime.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** obj_datetime.c	2 Dec 2002 23:28:13 -0000	1.11
--- obj_datetime.c	3 Dec 2002 02:27:01 -0000	1.12
***************
*** 420,424 ****
  }
  
! /* XXX This is a ridiculously inefficient way to pickle a short string. */
  static PyObject *
  datetime_reduce(PyDateTime_DateTime* self)
--- 420,424 ----
  }
  
! #if 0
  static PyObject *
  datetime_reduce(PyDateTime_DateTime* self)
***************
*** 437,440 ****
--- 437,465 ----
  	return result;
  }
+ #endif
+ 
+ /* XXX This seems a ridiculously inefficient way to pickle a short string. */
+ static PyObject *
+ datetime_pickler(PyObject *module, PyDateTime_DateTime *datetime)
+ {
+ 	PyObject *state = datetime_getstate(datetime);
+ 	PyObject *tuple = Py_BuildValue("O(O)",
+ 		datetime_unpickler_object, state);
+ 	return tuple;
+ }
+ 
+ static PyObject *
+ datetime_unpickler(PyObject *module, PyObject *arg)
+ {
+ 	PyDateTime_DateTime *self;
+ 	PyObject *res;
+ 
+ 	self = PyObject_New(PyDateTime_DateTime, &PyDateTime_DateTimeType);
+ 	if (self != NULL) {
+ 		res = datetime_setstate(self, arg);
+ 		Py_XDECREF(res);
+ 	}
+ 	return (PyObject *)self;
+ }
  
  static PyMethodDef datetime_methods[] = {
***************
*** 453,458 ****
--- 478,485 ----
  	{"__setstate__", (PyCFunction)datetime_setstate, METH_O,
  	 	PyDoc_STR("__setstate__(state)")},
+ #if 0
  	{"__reduce__", (PyCFunction)datetime_reduce,	METH_NOARGS,
  		NULL},
+ #endif
  	{"__getstate__", (PyCFunction)datetime_getstate, METH_NOARGS,
  	 	PyDoc_STR("__getstate__() -> state")},