From bce56a6c5ba368c3cb84da315266ce975005f82c Mon Sep 17 00:00:00 2001
From: Guido van Rossum <guido@python.org>
Date: Thu, 10 May 2007 18:04:33 +0000
Subject: Fix some miscellaneous places that incorrectly insisted on str8.

---
 Modules/_csv.c           | 24 ++++++++++++------------
 Modules/datetimemodule.c | 22 +++++++++++++---------
 Modules/posixmodule.c    | 15 +++++++++------
 3 files changed, 34 insertions(+), 27 deletions(-)

diff --git a/Modules/_csv.c b/Modules/_csv.c
index e99acf9..e3dca2c 100644
--- a/Modules/_csv.c
+++ b/Modules/_csv.c
@@ -235,19 +235,19 @@ _set_char(const char *name, char *target, PyObject *src, char dflt)
 	if (src == NULL)
 		*target = dflt;
 	else {
-		if (src == Py_None || PyString_Size(src) == 0)
-			*target = '\0';
-		else if (!PyString_Check(src) || PyString_Size(src) != 1) {
-			PyErr_Format(PyExc_TypeError, 
-				     "\"%s\" must be an 1-character string", 
-				     name);
-			return -1;
-		}
-		else {
-			char *s = PyString_AsString(src);
-			if (s == NULL)
+		*target = '\0';
+		if (src != Py_None) {
+			const char *buf;
+			Py_ssize_t len;
+			if (PyObject_AsCharBuffer(src, &buf, &len) < 0 ||
+				len > 1) {
+				PyErr_Format(PyExc_TypeError,
+					"\"%s\" must be an 1-character string",
+					     name);
 				return -1;
-			*target = s[0];
+			}
+			if (len > 0)
+				*target = buf[0];
 		}
 	}
         return 0;
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index 96263f8..9872685 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -1144,7 +1144,8 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
 	PyObject *zreplacement = NULL;	/* py string, replacement for %z */
 	PyObject *Zreplacement = NULL;	/* py string, replacement for %Z */
 
-	char *pin;	/* pointer to next char in input format */
+	const char *pin;/* pointer to next char in input format */
+        Py_ssize_t flen;/* length of input format */
 	char ch;	/* next char in input format */
 
 	PyObject *newfmt = NULL;	/* py string, the output format */
@@ -1153,11 +1154,15 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
 			   exclusive of trailing \0 */
 	int usednew;	/* number bytes used so far in output format buffer */
 
-	char *ptoappend; /* pointer to string to append to output buffer */
+	const char *ptoappend;/* pointer to string to append to output buffer */
 	int ntoappend;	/* # of bytes to append to output buffer */
 
 	assert(object && format && timetuple);
-	assert(PyString_Check(format));
+	assert(PyString_Check(format) || PyUnicode_Check(format));
+
+        /* Convert the input format to a C string and size */
+        if (PyObject_AsCharBuffer(format, &pin, &flen) < 0)
+		return NULL;
 
 	/* Give up if the year is before 1900.
 	 * Python strftime() plays games with the year, and different
@@ -1188,13 +1193,12 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
 	 * a new format.  Since computing the replacements for those codes
 	 * is expensive, don't unless they're actually used.
 	 */
-	totalnew = PyString_Size(format) + 1;	/* realistic if no %z/%Z */
+	totalnew = flen + 1;	/* realistic if no %z/%Z */
 	newfmt = PyString_FromStringAndSize(NULL, totalnew);
 	if (newfmt == NULL) goto Done;
 	pnew = PyString_AsString(newfmt);
 	usednew = 0;
 
-	pin = PyString_AsString(format);
 	while ((ch = *pin++) != '\0') {
 		if (ch != '%') {
 			ptoappend = pin - 1;
@@ -2441,8 +2445,8 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
 	PyObject *tuple;
 	static char *keywords[] = {"format", NULL};
 
-	if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
-					  &PyString_Type, &format))
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "S:strftime", keywords,
+					  &format))
 		return NULL;
 
 	tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()");
@@ -3174,8 +3178,8 @@ time_strftime(PyDateTime_Time *self, PyObject *args, PyObject *kw)
 	PyObject *tuple;
 	static char *keywords[] = {"format", NULL};
 
-	if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:strftime", keywords,
-					  &PyString_Type, &format))
+	if (! PyArg_ParseTupleAndKeywords(args, kw, "S:strftime", keywords,
+					  &format))
 		return NULL;
 
 	/* Python's strftime does insane things with the year part of the
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index f5106e1..425fa5a 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -6966,13 +6966,19 @@ conv_confname(PyObject *arg, int *valuep, struct constdef *table,
         *valuep = PyInt_AS_LONG(arg);
         return 1;
     }
-    if (PyString_Check(arg)) {
+    else {
         /* look up the value in the table using a binary search */
         size_t lo = 0;
 		size_t mid;
         size_t hi = tablesize;
         int cmp;
-        char *confname = PyString_AS_STRING(arg);
+        const char *confname;
+        Py_ssize_t namelen;
+        if (PyObject_AsCharBuffer(arg, &confname, &namelen) < 0) {
+            PyErr_SetString(PyExc_TypeError,
+                            "configuration names must be strings or integers");
+            return 0;
+        }
         while (lo < hi) {
             mid = (lo + hi) / 2;
             cmp = strcmp(confname, table[mid].name);
@@ -6986,11 +6992,8 @@ conv_confname(PyObject *arg, int *valuep, struct constdef *table,
             }
         }
         PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
+        return 0;
     }
-    else
-        PyErr_SetString(PyExc_TypeError,
-                        "configuration names must be strings or integers");
-    return 0;
 }
 
 
-- 
cgit v0.12

