[Python-checkins] python/nondist/sandbox/datetime datetime.c,1.54,1.55 datetime.h,1.14,1.15 doc.txt,1.43,1.44 obj_time.c,1.6,1.7 obj_timetz.c,1.2,1.3

tim_one@users.sourceforge.net tim_one@users.sourceforge.net
Wed, 11 Dec 2002 10:54:13 -0800


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

Modified Files:
	datetime.c datetime.h doc.txt obj_time.c obj_timetz.c 
Log Message:
Moving timetz a little closer to being usable.


Index: datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -C2 -d -r1.54 -r1.55
*** datetime.c	11 Dec 2002 01:47:20 -0000	1.54
--- datetime.c	11 Dec 2002 18:54:10 -0000	1.55
***************
*** 548,551 ****
--- 548,592 ----
  static PyObject *seconds_per_day = NULL; /* 3600*24 as Python int */
  
+ /* Ensure that p is None or of a tzinfo subclass.  Return 0 if OK; if not
+  * raise TypeError and return -1.
+  */
+ static int
+ check_tzinfo_subclass(PyObject *p, const char *msg)
+ {
+ 	if (p == Py_None || PyTZInfo_Check(p))
+ 		return 0;
+ 	PyErr_Format(PyExc_TypeError,
+ 		     "%s must be None or of a tzinfo subclass, "
+ 		     "not type '%s'",
+ 		     msg, p->ob_type->tp_name);
+ 	return -1;
+ }
+ 
+ /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
+  * The comparisons here all most naturally compute a cmp()-like result.
+  * This little helper turns that into a bool result for rich comparisons.
+  */
+ static PyObject *
+ diff_to_bool(long diff, int op)
+ {
+ 	PyObject *result;
+ 	int istrue;
+ 
+ 	switch (op) {
+ 		case Py_EQ: istrue = diff == 0; break;
+ 		case Py_NE: istrue = diff != 0; break;
+ 		case Py_LE: istrue = diff <= 0; break;
+ 		case Py_GE: istrue = diff >= 0; break;
+ 		case Py_LT: istrue = diff < 0; break;
+ 		case Py_GT: istrue = diff > 0; break;
+ 		default:
+ 			assert(! "op unknown");
+ 			istrue = 0; /* To shut up compiler */
+ 	}
+ 	result = istrue ? Py_True : Py_False;
+ 	Py_INCREF(result);
+ 	return result;
+ }
+ 
  /* Create a date instance with no range checking. */
  static PyObject *
***************
*** 585,588 ****
--- 626,639 ----
  }
  
+ static void
+ set_time_fields(PyDateTime_Time *self, int h, int m, int s, int us)
+ {
+ 	self->hashcode = -1;
+ 	TIME_SET_HOUR(self, h);
+ 	TIME_SET_MINUTE(self, m);
+ 	TIME_SET_SECOND(self, s);
+ 	TIME_SET_MICROSECOND(self, us);
+ }
+ 
  /* Create a time instance with no range checking. */
  static PyObject *
***************
*** 592,601 ****
  
  	self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
  	if (self != NULL) {
! 		self->hashcode = -1;
! 		TIME_SET_HOUR(self, hour);
! 		TIME_SET_MINUTE(self, minute);
! 		TIME_SET_SECOND(self, second);
! 		TIME_SET_MICROSECOND(self, usecond);
  	}
  	return (PyObject *) self;
--- 643,663 ----
  
  	self = PyObject_New(PyDateTime_Time, &PyDateTime_TimeType);
+ 	if (self != NULL)
+ 		set_time_fields(self, hour, minute, second, usecond);
+ 	return (PyObject *) self;
+ }
+ 
+ /* Create a timetz instance with no range checking. */
+ static PyObject *
+ new_timetz(int hour, int minute, int second, int usecond, PyObject *tzinfo)
+ {
+ 	PyDateTime_TimeTZ *self;
+ 
+ 	self = PyObject_New(PyDateTime_TimeTZ, &PyDateTime_TimeTZType);
  	if (self != NULL) {
! 		set_time_fields((PyDateTime_Time *)self,
! 				hour, minute, second, usecond);
! 		Py_INCREF(tzinfo);
! 		self->tzinfo = tzinfo;
  	}
  	return (PyObject *) self;
***************
*** 635,664 ****
  static PyObject *time_unpickler_object = NULL;
  static PyObject *timetz_unpickler_object = NULL;
- 
- /* For obscure reasons, we need to use tp_richcompare instead of tp_compare.
-  * The comparisons here all most naturally compute a cmp()-like result.
-  * This little helper turns that into a bool result for rich comparisons.
-  */
- static PyObject *
- diff_to_bool(long diff, int op)
- {
- 	PyObject *result;
- 	int istrue;
- 
- 	switch (op) {
- 		case Py_EQ: istrue = diff == 0; break;
- 		case Py_NE: istrue = diff != 0; break;
- 		case Py_LE: istrue = diff <= 0; break;
- 		case Py_GE: istrue = diff >= 0; break;
- 		case Py_LT: istrue = diff < 0; break;
- 		case Py_GT: istrue = diff > 0; break;
- 		default:
- 			assert(! "op unknown");
- 			istrue = 0; /* To shut up compiler */
- 	}
- 	result = istrue ? Py_True : Py_False;
- 	Py_INCREF(result);
- 	return result;
- }
  
  #include "obj_delta.c"
--- 697,700 ----

Index: datetime.h
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** datetime.h	11 Dec 2002 01:47:20 -0000	1.14
--- datetime.h	11 Dec 2002 18:54:10 -0000	1.15
***************
*** 96,98 ****
--- 96,100 ----
            ((PyDateTime_Time*)o)->data[5])
  
+ #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
+ 
  #endif

Index: doc.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v
retrieving revision 1.43
retrieving revision 1.44
diff -C2 -d -r1.43 -r1.44
*** doc.txt	11 Dec 2002 01:47:20 -0000	1.43
--- doc.txt	11 Dec 2002 18:54:10 -0000	1.44
***************
*** 68,75 ****
  
  
! Docs
! ====
  The datetime module supplies a number of classes for manipulating dates
! and times, in both simple and complex ways.
  
  class date
--- 68,77 ----
  
  
! Overview
! ========
  The datetime module supplies a number of classes for manipulating dates
! and times, in both simple and complex ways.  While date and time
! arithmetic is supported, the focus of the implementation is on efficient
! field extraction, for output formatting and manipulation.
  
  class date
***************
*** 772,773 ****
--- 774,780 ----
          PyDateTime_TIME_GET_SECOND(o)
          PyDateTime_TIME_GET_MICROSECOND(o)
+ 
+     For checking whether an object is a tzinfo instance; however,
+     note that Py_None is almost always allowed when a tzinfo argument
+     is expected:
+         PyTZInfo_Check(op)

Index: obj_time.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_time.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** obj_time.c	9 Dec 2002 19:50:33 -0000	1.6
--- obj_time.c	11 Dec 2002 18:54:10 -0000	1.7
***************
*** 39,50 ****
  /* Constructors. */
  
  static PyObject *
  time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  {
  	PyObject *self = NULL;
! 	long hour = 0;
! 	long minute = 0;
! 	long second = 0;
! 	long usecond = 0;
  
  	static char *keywords[] = {
--- 39,79 ----
  /* Constructors. */
  
+ /* Check that time arguments are in range.  Return 0 if they are.  If they
+  * aren't, raise ValueError and return -1.
+  */
+ static int
+ time_check_time_args(int h, int m, int s, int us)
+ {
+ 	if (h < 0 || h > 23) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 				"hour must be in 0..23");
+ 		return -1;
+ 	}
+ 	if (m < 0 || m > 59) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 				"minute must be in 0..59");
+ 		return -1;
+ 	}
+ 	if (s < 0 || s > 59) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 				"second must be in 0..59");
+ 		return -1;
+ 	}
+ 	if (us < 0 || us > 999999) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 				"microsecond must be in 0..999999");
+ 		return -1;
+ 	}
+ 	return 0;
+ }
+ 
  static PyObject *
  time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  {
  	PyObject *self = NULL;
! 	int hour = 0;
! 	int minute = 0;
! 	int second = 0;
! 	int usecond = 0;
  
  	static char *keywords[] = {
***************
*** 52,77 ****
  	};
  
! 	if (PyArg_ParseTupleAndKeywords(args, kw, "|llll", keywords,
  					&hour, &minute, &second, &usecond)) {
! 		if (hour < 0 || hour > 23) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"hour must be in 0..23");
! 			return NULL;
! 		}
! 		if (minute < 0 || minute > 59) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"minute must be in 0..59");
! 			return NULL;
! 		}
! 		if (second < 0 || second > 59) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"second must be in 0..59");
! 			return NULL;
! 		}
! 		if (usecond < 0 || usecond > 999999) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"microsecond must be in 0..999999");
  			return NULL;
- 		}
  		self = new_time(hour, minute, second, usecond);
  	}
--- 81,88 ----
  	};
  
! 	if (PyArg_ParseTupleAndKeywords(args, kw, "|iiii", keywords,
  					&hour, &minute, &second, &usecond)) {
! 		if (time_check_time_args(hour, minute, second, usecond) < 0)
  			return NULL;
  		self = new_time(hour, minute, second, usecond);
  	}

Index: obj_timetz.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_timetz.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** obj_timetz.c	11 Dec 2002 00:11:15 -0000	1.2
--- obj_timetz.c	11 Dec 2002 18:54:10 -0000	1.3
***************
*** 47,82 ****
  {
  	PyObject *self = NULL;
! 	long hour = 0;
! 	long minute = 0;
! 	long second = 0;
! 	long usecond = 0;
  
  	static char *keywords[] = {
! 		"hour", "minute", "second", "microsecond", NULL
  	};
  
! 	if (PyArg_ParseTupleAndKeywords(args, kw, "|llll", keywords,
! 					&hour, &minute, &second, &usecond)) {
! 		if (hour < 0 || hour > 23) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"hour must be in 0..23");
! 			return NULL;
! 		}
! 		if (minute < 0 || minute > 59) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"minute must be in 0..59");
! 			return NULL;
! 		}
! 		if (second < 0 || second > 59) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"second must be in 0..59");
  			return NULL;
! 		}
! 		if (usecond < 0 || usecond > 999999) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"microsecond must be in 0..999999");
  			return NULL;
! 		}
! 		self = new_time(hour, minute, second, usecond);
  	}
  	return self;
--- 47,68 ----
  {
  	PyObject *self = NULL;
! 	int hour = 0;
! 	int minute = 0;
! 	int second = 0;
! 	int usecond = 0;
! 	PyObject *tzinfo = Py_None;
  
  	static char *keywords[] = {
! 		"hour", "minute", "second", "microsecond", "tzinfo", NULL
  	};
  
! 	if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO", keywords,
! 					&hour, &minute, &second, &usecond,
! 					&tzinfo)) {
! 		if (time_check_time_args(hour, minute, second, usecond) < 0)
  			return NULL;
! 		if (check_tzinfo_subclass(tzinfo, "tzinfo argument") < 0)
  			return NULL;
! 		self = new_timetz(hour, minute, second, usecond, tzinfo);
  	}
  	return self;