[Python-checkins] python/dist/src/Modules datetimemodule.c,1.55,1.56

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Fri, 31 Jan 2003 20:40:07 -0800


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv16118/Modules

Modified Files:
	datetimemodule.c 
Log Message:
New functions alloc_{time,datetime}.  Got rid of all setstate-like
functions.  Reworked {time,datetime}_new() to do what their corresponding
setstates used to do in their state-tuple-input paths, but directly,
without constructing an object with throwaway state first.  Tightened
the "is this a state tuple input?" paths to check the presumed state
string-length too, and to raise an exception if the optional second state
element isn't a tzinfo instance (IOW, check these paths for type errors
as carefully as the normal paths).


Index: datetimemodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -C2 -d -r1.55 -r1.56
*** datetimemodule.c	1 Feb 2003 02:54:15 -0000	1.55
--- datetimemodule.c	1 Feb 2003 04:40:04 -0000	1.56
***************
*** 1226,1229 ****
--- 1226,1265 ----
  
  /* ---------------------------------------------------------------------------
+  * Basic object allocation.  These allocate Python objects of the right
+  * size and type, and do the Python object-initialization bit.  If there's
+  * not enough memory, they return NULL after setting MemoryError.  All
+  * data members remain uninitialized trash.
+  */
+ static PyDateTime_Time *
+ alloc_time(int aware)
+ {
+ 	PyDateTime_Time *self;
+ 
+ 	self = (PyDateTime_Time *)
+ 		PyObject_MALLOC(aware ?
+ 				sizeof(PyDateTime_Time) :
+ 				sizeof(_PyDateTime_BaseTime));
+ 	if (self == NULL)
+ 		return (PyDateTime_Time *)PyErr_NoMemory();
+ 	PyObject_INIT(self, &PyDateTime_TimeType);
+ 	return self;
+ }
+ 
+ static PyDateTime_DateTime *
+ alloc_datetime(int aware)
+ {
+ 	PyDateTime_DateTime *self;
+ 
+ 	self = (PyDateTime_DateTime *)
+ 		PyObject_MALLOC(aware ?
+ 				sizeof(PyDateTime_DateTime) :
+ 				sizeof(_PyDateTime_BaseDateTime));
+ 	if (self == NULL)
+ 		return (PyDateTime_DateTime *)PyErr_NoMemory();
+ 	PyObject_INIT(self, &PyDateTime_DateTimeType);
+ 	return self;
+ }
+ 
+ /* ---------------------------------------------------------------------------
   * Helpers for setting object fields.  These work on pointers to the
   * appropriate base class.
***************
*** 1264,1283 ****
  	char aware = tzinfo != Py_None;
  
! 	self = (PyDateTime_DateTime *)PyObject_MALLOC(aware ?
! 					sizeof(PyDateTime_DateTime) :
! 					sizeof(_PyDateTime_BaseDateTime));
! 	if (self == NULL)
! 		return PyErr_NoMemory();
! 	self->hastzinfo = aware;
! 	set_date_fields((PyDateTime_Date *)self, year, month, day);
! 	DATE_SET_HOUR(self, hour);
! 	DATE_SET_MINUTE(self, minute);
! 	DATE_SET_SECOND(self, second);
! 	DATE_SET_MICROSECOND(self, usecond);
! 	if (aware) {
! 		Py_INCREF(tzinfo);
! 		self->tzinfo = tzinfo;
  	}
! 	return (PyObject *)PyObject_INIT(self, &PyDateTime_DateTimeType);
  }
  
--- 1300,1317 ----
  	char aware = tzinfo != Py_None;
  
! 	self = alloc_datetime(aware);
! 	if (self != NULL) {
! 		self->hastzinfo = aware;
! 		set_date_fields((PyDateTime_Date *)self, year, month, day);
! 		DATE_SET_HOUR(self, hour);
! 		DATE_SET_MINUTE(self, minute);
! 		DATE_SET_SECOND(self, second);
! 		DATE_SET_MICROSECOND(self, usecond);
! 		if (aware) {
! 			Py_INCREF(tzinfo);
! 			self->tzinfo = tzinfo;
! 		}
  	}
! 	return (PyObject *)self;
  }
  
***************
*** 1289,1308 ****
  	char aware = tzinfo != Py_None;
  
! 	self = (PyDateTime_Time *)PyObject_MALLOC(aware ?
! 				sizeof(PyDateTime_Time) :
! 				sizeof(_PyDateTime_BaseTime));
! 	if (self == NULL)
! 		return PyErr_NoMemory();
! 	self->hastzinfo = aware;
! 	self->hashcode = -1;
! 	TIME_SET_HOUR(self, hour);
! 	TIME_SET_MINUTE(self, minute);
! 	TIME_SET_SECOND(self, second);
! 	TIME_SET_MICROSECOND(self, usecond);
! 	if (aware) {
! 		Py_INCREF(tzinfo);
! 		self->tzinfo = tzinfo;
  	}
! 	return (PyObject *)PyObject_INIT(self, &PyDateTime_TimeType);
  }
  
--- 1323,1340 ----
  	char aware = tzinfo != Py_None;
  
! 	self = alloc_time(aware);
! 	if (self != NULL) {
! 		self->hastzinfo = aware;
! 		self->hashcode = -1;
! 		TIME_SET_HOUR(self, hour);
! 		TIME_SET_MINUTE(self, minute);
! 		TIME_SET_SECOND(self, second);
! 		TIME_SET_MICROSECOND(self, usecond);
! 		if (aware) {
! 			Py_INCREF(tzinfo);
! 			self->tzinfo = tzinfo;
! 		}
  	}
! 	return (PyObject *)self;
  }
  
***************
*** 2109,2146 ****
  static char *date_kws[] = {"year", "month", "day", NULL};
  
- /* __setstate__ isn't exposed. */
- static PyObject *
- date_setstate(PyDateTime_Date *self, PyObject *arg)
- {
- 	PyObject *state;
- 	int len;
- 	unsigned char *pdata;
- 
- 	if (!PyTuple_Check(arg) || PyTuple_GET_SIZE(arg) != 1)
- 		goto error;
- 	state = PyTuple_GET_ITEM(arg, 0);
- 	if (!PyString_Check(state))
- 		goto error;
- 
- 	len = PyString_Size(state);
- 	if (len != _PyDateTime_DATE_DATASIZE)
- 		goto error;
- 
- 	pdata = (unsigned char*)PyString_AsString(state);
- 	memcpy(self->data, pdata, _PyDateTime_DATE_DATASIZE);
- 	self->hashcode = -1;
- 
- 	Py_INCREF(Py_None);
- 	return Py_None;
-  error:
- 	PyErr_SetString(PyExc_TypeError,
- 			"bad argument to date.__setstate__");
- 	return NULL;
- }
- 
  static PyObject *
  date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  {
  	PyObject *self = NULL;
  	int year;
  	int month;
--- 2141,2149 ----
  static char *date_kws[] = {"year", "month", "day", NULL};
  
  static PyObject *
  date_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  {
  	PyObject *self = NULL;
+ 	PyObject *state;
  	int year;
  	int month;
***************
*** 2149,2166 ****
  	/* Check for invocation from pickle with __getstate__ state */
  	if (PyTuple_GET_SIZE(args) == 1 &&
! 	    PyString_Check(PyTuple_GET_ITEM(args, 0)))
  	{
! 		self = new_date(1, 1, 1);
! 		if (self != NULL) {
! 			PyObject *res = date_setstate(
! 				(PyDateTime_Date *)self, args);
! 			if (res == Py_None)
! 				Py_DECREF(res);
! 			else {
! 				Py_DECREF(self);
! 				self = NULL;
! 			}
  		}
! 		return self;
  	}
  
--- 2152,2167 ----
  	/* Check for invocation from pickle with __getstate__ state */
  	if (PyTuple_GET_SIZE(args) == 1 &&
! 	    PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
! 	    PyString_GET_SIZE(state) == _PyDateTime_DATE_DATASIZE)
  	{
! 	    	PyDateTime_Date *me;
! 
! 		me = PyObject_New(PyDateTime_Date, &PyDateTime_DateType);
! 		if (me != NULL) {
! 			char *pdata = PyString_AS_STRING(state);
! 			memcpy(me->data, pdata, _PyDateTime_DATE_DATASIZE);
! 			me->hashcode = -1;
  		}
! 		return (PyObject *)me;
  	}
  
***************
*** 2970,3013 ****
  			   "tzinfo", NULL};
  
- /* __setstate__ isn't exposed. */
- static PyObject *
- time_setstate(PyDateTime_Time *self, PyObject *state)
- {
- 	PyObject *basestate;
- 	PyObject *tzinfo = Py_None;
- 
- 	if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
- 			       &PyString_Type, &basestate,
- 			       &tzinfo))
- 		return NULL;
- 	if (PyString_Size(basestate) !=  _PyDateTime_TIME_DATASIZE ||
- 	    check_tzinfo_subclass(tzinfo) < 0) {
- 		PyErr_SetString(PyExc_TypeError,
- 				"bad argument to time.__setstate__");
- 		return NULL;
- 	}
- 	if (tzinfo != Py_None && ! HASTZINFO(self)) {
- 		PyErr_SetString(PyExc_ValueError, "time.__setstate__ can't "
- 				"add a non-None tzinfo to a time object that "
- 				"doesn't have one already");
- 		return NULL;
- 	}
- 	memcpy((char *)self->data,
- 	       PyString_AsString(basestate),
- 	       _PyDateTime_TIME_DATASIZE);
- 	self->hashcode = -1;
- 	if (HASTZINFO(self)) {
- 		Py_INCREF(tzinfo);
- 		Py_XDECREF(self->tzinfo);
- 		self->tzinfo = tzinfo;
- 	}
- 	Py_INCREF(Py_None);
- 	return Py_None;
- }
- 
  static PyObject *
  time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  {
  	PyObject *self = NULL;
  	int hour = 0;
  	int minute = 0;
--- 2971,2979 ----
  			   "tzinfo", NULL};
  
  static PyObject *
  time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  {
  	PyObject *self = NULL;
+ 	PyObject *state;
  	int hour = 0;
  	int minute = 0;
***************
*** 3019,3038 ****
  	if (PyTuple_GET_SIZE(args) >= 1 &&
  	    PyTuple_GET_SIZE(args) <= 2 &&
! 	    PyString_Check(PyTuple_GET_ITEM(args, 0)))
  	{
! 		if (PyTuple_GET_SIZE(args) == 2)
  			tzinfo = PyTuple_GET_ITEM(args, 1);
! 		self = new_time(0, 0, 0, 0, tzinfo);
! 		if (self != NULL) {
! 			PyObject *res = time_setstate(
! 				(PyDateTime_Time *)self, args);
! 			if (res == Py_None)
! 				Py_DECREF(res);
! 			else {
! 				Py_DECREF(self);
! 				self = NULL;
  			}
  		}
! 		return self;
  	}
  
--- 2985,3016 ----
  	if (PyTuple_GET_SIZE(args) >= 1 &&
  	    PyTuple_GET_SIZE(args) <= 2 &&
! 	    PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
! 	    PyString_GET_SIZE(state) == _PyDateTime_TIME_DATASIZE)
  	{
! 		PyDateTime_Time *me;
! 		char aware;
! 
! 		if (PyTuple_GET_SIZE(args) == 2) {
  			tzinfo = PyTuple_GET_ITEM(args, 1);
! 			if (check_tzinfo_subclass(tzinfo) < 0) {
! 				PyErr_SetString(PyExc_TypeError, "bad "
! 					"tzinfo state arg");
! 				return NULL;
  			}
  		}
! 		aware = (char)(tzinfo != Py_None);
! 		me = alloc_time(aware);
! 		if (me != NULL) {
! 			char *pdata = PyString_AS_STRING(state);
! 
! 			memcpy(me->data, pdata, _PyDateTime_TIME_DATASIZE);
! 			me->hashcode = -1;
! 			me->hastzinfo = aware;
! 			if (aware) {
! 				Py_INCREF(tzinfo);
! 				me->tzinfo = tzinfo;
! 			}
! 		}
! 		return (PyObject *)me;
  	}
  
***************
*** 3509,3552 ****
  };
  
- /* __setstate__ isn't exposed. */
- static PyObject *
- datetime_setstate(PyDateTime_DateTime *self, PyObject *state)
- {
- 	PyObject *basestate;
- 	PyObject *tzinfo = Py_None;
- 
- 	if (! PyArg_ParseTuple(state, "O!|O:__setstate__",
- 			       &PyString_Type, &basestate,
- 			       &tzinfo))
- 		return NULL;
- 	if (PyString_Size(basestate) !=  _PyDateTime_DATETIME_DATASIZE ||
- 	    check_tzinfo_subclass(tzinfo) < 0) {
- 		PyErr_SetString(PyExc_TypeError,
- 				"bad argument to datetime.__setstate__");
- 		return NULL;
- 	}
- 	if (tzinfo != Py_None && ! HASTZINFO(self)) {
- 		PyErr_SetString(PyExc_ValueError, "datetime.__setstate__ "
- 				"can't add a non-None tzinfo to a datetime "
- 				"object that doesn't have one already");
- 		return NULL;
- 	}
- 	memcpy((char *)self->data,
- 	       PyString_AsString(basestate),
- 	       _PyDateTime_DATETIME_DATASIZE);
- 	self->hashcode = -1;
- 	if (HASTZINFO(self)) {
- 		Py_INCREF(tzinfo);
- 		Py_XDECREF(self->tzinfo);
- 		self->tzinfo = tzinfo;
- 	}
- 	Py_INCREF(Py_None);
- 	return Py_None;
- }
- 
  static PyObject *
  datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  {
  	PyObject *self = NULL;
  	int year;
  	int month;
--- 3487,3495 ----
  };
  
  static PyObject *
  datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  {
  	PyObject *self = NULL;
+ 	PyObject *state;
  	int year;
  	int month;
***************
*** 3561,3580 ****
  	if (PyTuple_GET_SIZE(args) >= 1 &&
  	    PyTuple_GET_SIZE(args) <= 2 &&
! 	    PyString_Check(PyTuple_GET_ITEM(args, 0)))
  	{
! 		if (PyTuple_GET_SIZE(args) == 2)
  			tzinfo = PyTuple_GET_ITEM(args, 1);
! 		self = new_datetime(1, 1, 1, 0, 0, 0, 0, tzinfo);
! 		if (self != NULL) {
! 			PyObject *res = datetime_setstate(
! 				(PyDateTime_DateTime *)self, args);
! 			if (res == Py_None)
! 				Py_DECREF(res);
! 			else {
! 				Py_DECREF(self);
! 				self = NULL;
  			}
  		}
! 		return self;
  	}
  
--- 3504,3535 ----
  	if (PyTuple_GET_SIZE(args) >= 1 &&
  	    PyTuple_GET_SIZE(args) <= 2 &&
! 	    PyString_Check(state = PyTuple_GET_ITEM(args, 0)) &&
! 	    PyString_GET_SIZE(state) == _PyDateTime_DATETIME_DATASIZE)
  	{
! 		PyDateTime_DateTime *me;
! 		char aware;
! 
! 		if (PyTuple_GET_SIZE(args) == 2) {
  			tzinfo = PyTuple_GET_ITEM(args, 1);
! 			if (check_tzinfo_subclass(tzinfo) < 0) {
! 				PyErr_SetString(PyExc_TypeError, "bad "
! 					"tzinfo state arg");
! 				return NULL;
  			}
  		}
! 		aware = (char)(tzinfo != Py_None);
! 		me = alloc_datetime(aware);
! 		if (me != NULL) {
! 			char *pdata = PyString_AS_STRING(state);
! 
! 			memcpy(me->data, pdata, _PyDateTime_DATETIME_DATASIZE);
! 			me->hashcode = -1;
! 			me->hastzinfo = aware;
! 			if (aware) {
! 				Py_INCREF(tzinfo);
! 				me->tzinfo = tzinfo;
! 			}
! 		}
! 		return (PyObject *)me;
  	}