Merging the py3k-pep3137 branch back into the py3k branch.
No detailed change log; just check out the change log for the py3k-pep3137
branch.  The most obvious changes:

  - str8 renamed to bytes (PyString at the C level);
  - bytes renamed to buffer (PyBytes at the C level);
  - PyString and PyUnicode are no longer compatible.

I.e. we now have an immutable bytes type and a mutable bytes type.

The behavior of PyString was modified quite a bit, to make it more
bytes-like.  Some changes are still on the to-do list.
diff --git a/Python/ast.c b/Python/ast.c
index 485dafb..0afb408 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -3147,9 +3147,8 @@
                     Py_DECREF(u);
                     return NULL;
                 }
-                assert(PyBytes_Check(w));
-                r = PyBytes_AsString(w);
-                rn = PyBytes_Size(w);
+                r = PyString_AS_STRING(w);
+                rn = Py_Size(w);
                 assert(rn % 2 == 0);
                 for (i = 0; i < rn; i += 2) {
                     sprintf(p, "\\u%02x%02x",
@@ -3174,7 +3173,7 @@
 }
 
 /* s is a Python string literal, including the bracketing quote characters,
- * and r &/or u prefixes (if any), and embedded escape sequences (if any).
+ * and r &/or b prefixes (if any), and embedded escape sequences (if any).
  * parsestr parses it, and returns the decoded Python string object.
  */
 static PyObject *
@@ -3186,7 +3185,7 @@
     int rawmode = 0;
     int need_encoding;
 
-    if (isalpha(quote) || quote == '_') {
+    if (isalpha(quote)) {
         if (quote == 'b' || quote == 'B') {
             quote = *++s;
             *bytesmode = 1;
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index ecc84b5..7973fcb 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1875,7 +1875,8 @@
 	SETBUILTIN("True",		Py_True);
 	SETBUILTIN("bool",		&PyBool_Type);
 	SETBUILTIN("memoryview",        &PyMemoryView_Type);
-	SETBUILTIN("bytes",		&PyBytes_Type);
+	SETBUILTIN("buffer",		&PyBytes_Type);
+	SETBUILTIN("bytes",		&PyString_Type);
 	SETBUILTIN("classmethod",	&PyClassMethod_Type);
 #ifndef WITHOUT_COMPLEX
 	SETBUILTIN("complex",		&PyComplex_Type);
@@ -1894,7 +1895,6 @@
 	SETBUILTIN("slice",		&PySlice_Type);
 	SETBUILTIN("staticmethod",	&PyStaticMethod_Type);
 	SETBUILTIN("str",		&PyUnicode_Type);
-	SETBUILTIN("str8",		&PyString_Type);
 	SETBUILTIN("super",		&PySuper_Type);
 	SETBUILTIN("tuple",		&PyTuple_Type);
 	SETBUILTIN("type",		&PyType_Type);
diff --git a/Python/ceval.c b/Python/ceval.c
index ae8434d..c0e0993 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -119,8 +119,8 @@
 static void set_exc_info(PyThreadState *, PyObject *, PyObject *, PyObject *);
 static void reset_exc_info(PyThreadState *);
 static void format_exc_check_arg(PyObject *, const char *, PyObject *);
-static PyObject * string_concatenate(PyObject *, PyObject *,
-				    PyFrameObject *, unsigned char *);
+static PyObject * unicode_concatenate(PyObject *, PyObject *,
+                                      PyFrameObject *, unsigned char *);
 
 #define NAME_ERROR_MSG \
 	"name '%.200s' is not defined"
@@ -1127,10 +1127,10 @@
 					goto slow_add;
 				x = PyInt_FromLong(i);
 			}
-			else if (PyString_CheckExact(v) &&
-				 PyString_CheckExact(w)) {
-				x = string_concatenate(v, w, f, next_instr);
-				/* string_concatenate consumed the ref to v */
+			else if (PyUnicode_CheckExact(v) &&
+				 PyUnicode_CheckExact(w)) {
+				x = unicode_concatenate(v, w, f, next_instr);
+				/* unicode_concatenate consumed the ref to v */
 				goto skip_decref_vx;
 			}
 			else {
@@ -1328,10 +1328,10 @@
 					goto slow_iadd;
 				x = PyInt_FromLong(i);
 			}
-			else if (PyString_CheckExact(v) &&
-				 PyString_CheckExact(w)) {
-				x = string_concatenate(v, w, f, next_instr);
-				/* string_concatenate consumed the ref to v */
+			else if (PyUnicode_CheckExact(v) &&
+				 PyUnicode_CheckExact(w)) {
+				x = unicode_concatenate(v, w, f, next_instr);
+				/* unicode_concatenate consumed the ref to v */
 				goto skip_decref_v;
 			}
 			else {
@@ -1564,8 +1564,7 @@
 				break;
 			}
 			PyErr_Format(PyExc_SystemError,
-				     "no locals found when storing %s",
-				     PyObject_REPR(w));
+				     "no locals found when storing %R", w);
 			break;
 
 		case DELETE_NAME:
@@ -1578,8 +1577,7 @@
 				break;
 			}
 			PyErr_Format(PyExc_SystemError,
-				     "no locals when deleting %s",
-				     PyObject_REPR(w));
+				     "no locals when deleting %R", w);
 			break;
 
 		PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
@@ -1668,8 +1666,7 @@
 			w = GETITEM(names, oparg);
 			if ((v = f->f_locals) == NULL) {
 				PyErr_Format(PyExc_SystemError,
-					     "no locals when loading %s",
-					     PyObject_REPR(w));
+					     "no locals when loading %R", w);
 				break;
 			}
 			if (PyDict_CheckExact(v)) {
@@ -1854,19 +1851,6 @@
 			PUSH(x);
 			if (x != NULL) continue;
 			break;
-		
-		case MAKE_BYTES:
-			w = POP();
-			if (PyString_Check(w))
-				x = PyBytes_FromStringAndSize(
-					PyString_AS_STRING(w),
-					PyString_GET_SIZE(w));
-			else
-				x = NULL;
-			Py_DECREF(w);
-			PUSH(x);
-			if (x != NULL) continue;
-			break;
 
 		case LOAD_ATTR:
 			w = GETITEM(names, oparg);
@@ -3961,13 +3945,13 @@
 }
 
 static PyObject *
-string_concatenate(PyObject *v, PyObject *w,
+unicode_concatenate(PyObject *v, PyObject *w,
 		   PyFrameObject *f, unsigned char *next_instr)
 {
 	/* This function implements 'variable += expr' when both arguments
-	   are strings. */
-	Py_ssize_t v_len = PyString_GET_SIZE(v);
-	Py_ssize_t w_len = PyString_GET_SIZE(w);
+	   are (Unicode) strings. */
+	Py_ssize_t v_len = PyUnicode_GET_SIZE(v);
+	Py_ssize_t w_len = PyUnicode_GET_SIZE(w);
 	Py_ssize_t new_len = v_len + w_len;
 	if (new_len < 0) {
 		PyErr_SetString(PyExc_OverflowError,
@@ -4016,12 +4000,12 @@
 		}
 	}
 
-	if (v->ob_refcnt == 1 && !PyString_CHECK_INTERNED(v)) {
+	if (v->ob_refcnt == 1 && !PyUnicode_CHECK_INTERNED(v)) {
 		/* Now we own the last reference to 'v', so we can resize it
 		 * in-place.
 		 */
-		if (_PyString_Resize(&v, new_len) != 0) {
-			/* XXX if _PyString_Resize() fails, 'v' has been
+		if (PyUnicode_Resize(&v, new_len) != 0) {
+			/* XXX if PyUnicode_Resize() fails, 'v' has been
 			 * deallocated so it cannot be put back into
 			 * 'variable'.  The MemoryError is raised when there
 			 * is no value in 'variable', which might (very
@@ -4030,14 +4014,15 @@
 			return NULL;
 		}
 		/* copy 'w' into the newly allocated area of 'v' */
-		memcpy(PyString_AS_STRING(v) + v_len,
-		       PyString_AS_STRING(w), w_len);
+		memcpy(PyUnicode_AS_UNICODE(v) + v_len,
+		       PyUnicode_AS_UNICODE(w), w_len*sizeof(Py_UNICODE));
 		return v;
 	}
 	else {
 		/* When in-place resizing is not an option. */
-		PyString_Concat(&v, w);
-		return v;
+		w = PyUnicode_Concat(v, w);
+                Py_DECREF(v);
+		return w;
 	}
 }
 
diff --git a/Python/codecs.c b/Python/codecs.c
index 4b24676..c8926fc 100644
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -14,7 +14,7 @@
 /* --- Codec Registry ----------------------------------------------------- */
 
 /* Import the standard encodings package which will register the first
-   codec search function. 
+   codec search function.
 
    This is done in a lazy way so that the Unicode implementation does
    not downgrade startup time of scripts not needing it.
@@ -87,7 +87,7 @@
    characters. This makes encodings looked up through this mechanism
    effectively case-insensitive.
 
-   If no codec is found, a LookupError is set and NULL returned. 
+   If no codec is found, a LookupError is set and NULL returned.
 
    As side effect, this tries to load the encodings package, if not
    yet done. This is part of the lazy load strategy for the encodings
@@ -125,7 +125,7 @@
 	Py_DECREF(v);
 	return result;
     }
-    
+
     /* Next, scan the search functions in order of registration */
     args = PyTuple_New(1);
     if (args == NULL)
@@ -144,7 +144,7 @@
 
     for (i = 0; i < len; i++) {
 	PyObject *func;
-	
+
 	func = PyList_GetItem(interp->codec_search_path, i);
 	if (func == NULL)
 	    goto onError;
@@ -188,7 +188,7 @@
 		     const char *errors)
 {
     PyObject *args;
-    
+
     args = PyTuple_New(1 + (errors != NULL));
     if (args == NULL)
 	return NULL;
@@ -196,7 +196,7 @@
     PyTuple_SET_ITEM(args,0,object);
     if (errors) {
 	PyObject *v;
-	
+
 	v = PyUnicode_FromString(errors);
 	if (v == NULL) {
 	    Py_DECREF(args);
@@ -271,10 +271,10 @@
     return streamcodec;
 }
 
-/* Convenience APIs to query the Codec registry. 
-   
+/* Convenience APIs to query the Codec registry.
+
    All APIs return a codec object with incremented refcount.
-   
+
  */
 
 PyObject *PyCodec_Encoder(const char *encoding)
@@ -324,7 +324,7 @@
 {
     PyObject *encoder = NULL;
     PyObject *args = NULL, *result = NULL;
-    PyObject *v;
+    PyObject *v = NULL;
 
     encoder = PyCodec_Encoder(encoding);
     if (encoder == NULL)
@@ -333,31 +333,43 @@
     args = args_tuple(object, errors);
     if (args == NULL)
 	goto onError;
-    
-    result = PyEval_CallObject(encoder,args);
+
+    result = PyEval_CallObject(encoder, args);
     if (result == NULL)
 	goto onError;
 
-    if (!PyTuple_Check(result) || 
+    if (!PyTuple_Check(result) ||
 	PyTuple_GET_SIZE(result) != 2) {
 	PyErr_SetString(PyExc_TypeError,
-			"encoder must return a tuple (object,integer)");
+			"encoder must return a tuple (object, integer)");
 	goto onError;
     }
-    v = PyTuple_GET_ITEM(result,0);
-    Py_INCREF(v);
+    v = PyTuple_GET_ITEM(result, 0);
+    if (PyBytes_Check(v)) {
+        char msg[100];
+        PyOS_snprintf(msg, sizeof(msg),
+                      "encoder %s returned buffer instead of bytes",
+                      encoding);
+        if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) {
+            v = NULL;
+            goto onError;
+        }
+        v = PyString_FromStringAndSize(PyBytes_AS_STRING(v), Py_Size(v));
+    }
+    else if (PyString_Check(v))
+        Py_INCREF(v);
+    else {
+        PyErr_SetString(PyExc_TypeError,
+                        "encoding must return a tuple(bytes, integer)");
+        v = NULL;
+    }
     /* We don't check or use the second (integer) entry. */
 
-    Py_DECREF(args);
-    Py_DECREF(encoder);
-    Py_DECREF(result);
-    return v;
-	
  onError:
     Py_XDECREF(result);
     Py_XDECREF(args);
     Py_XDECREF(encoder);
-    return NULL;
+    return v;
 }
 
 /* Decode an object (usually a Python string) using the given encoding
@@ -380,11 +392,11 @@
     args = args_tuple(object, errors);
     if (args == NULL)
 	goto onError;
-    
+
     result = PyEval_CallObject(decoder,args);
     if (result == NULL)
 	goto onError;
-    if (!PyTuple_Check(result) || 
+    if (!PyTuple_Check(result) ||
 	PyTuple_GET_SIZE(result) != 2) {
 	PyErr_SetString(PyExc_TypeError,
 			"decoder must return a tuple (object,integer)");
@@ -398,7 +410,7 @@
     Py_DECREF(decoder);
     Py_DECREF(result);
     return v;
-	
+
  onError:
     Py_XDECREF(args);
     Py_XDECREF(decoder);
diff --git a/Python/compile.c b/Python/compile.c
index 93087db..80c97eb 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -787,8 +787,6 @@
 			return 1-oparg;
 		case BUILD_MAP:
 			return 1;
-		case MAKE_BYTES:
-			return 0;
 		case LOAD_ATTR:
 			return 0;
 		case COMPARE_OP:
@@ -3222,7 +3220,6 @@
 		break;
 	case Bytes_kind:
 		ADDOP_O(c, LOAD_CONST, e->v.Bytes.s, consts);
-		ADDOP(c, MAKE_BYTES);
 		break;
 	case Ellipsis_kind:
 		ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts);
diff --git a/Python/getargs.c b/Python/getargs.c
index 0b25d4b..d268104 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -7,7 +7,7 @@
 
 
 #ifdef __cplusplus
-extern "C" { 
+extern "C" {
 #endif
 int PyArg_Parse(PyObject *, const char *, ...);
 int PyArg_ParseTuple(PyObject *, const char *, ...);
@@ -37,7 +37,7 @@
 /* Forward */
 static int vgetargs1(PyObject *, const char *, va_list *, int);
 static void seterror(int, const char *, int *, const char *, const char *);
-static char *convertitem(PyObject *, const char **, va_list *, int, int *, 
+static char *convertitem(PyObject *, const char **, va_list *, int, int *,
                          char *, size_t, PyObject **);
 static char *converttuple(PyObject *, const char **, va_list *, int,
 			  int *, char *, size_t, int, PyObject **);
@@ -54,7 +54,7 @@
 {
 	int retval;
 	va_list va;
-	
+
 	va_start(va, format);
 	retval = vgetargs1(args, format, &va, FLAG_COMPAT);
 	va_end(va);
@@ -66,7 +66,7 @@
 {
 	int retval;
 	va_list va;
-	
+
 	va_start(va, format);
 	retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
 	va_end(va);
@@ -79,7 +79,7 @@
 {
 	int retval;
 	va_list va;
-	
+
 	va_start(va, format);
 	retval = vgetargs1(args, format, &va, 0);
 	va_end(va);
@@ -91,7 +91,7 @@
 {
 	int retval;
 	va_list va;
-	
+
 	va_start(va, format);
 	retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
 	va_end(va);
@@ -240,15 +240,15 @@
 			break;
 		}
 	}
-	
+
 	if (level != 0)
 		Py_FatalError(/* '(' */ "missing ')' in getargs format");
-	
+
 	if (min < 0)
 		min = max;
-	
+
 	format = formatsave;
-	
+
 	if (compat) {
 		if (max == 0) {
 			if (args == NULL)
@@ -269,7 +269,7 @@
 				PyErr_SetString(PyExc_TypeError, msgbuf);
 				return 0;
 			}
-			msg = convertitem(args, &format, p_va, flags, levels, 
+			msg = convertitem(args, &format, p_va, flags, levels,
 					  msgbuf, sizeof(msgbuf), &freelist);
 			if (msg == NULL)
 				return cleanreturn(1, freelist);
@@ -282,15 +282,15 @@
 			return 0;
 		}
 	}
-	
+
 	if (!PyTuple_Check(args)) {
 		PyErr_SetString(PyExc_SystemError,
 		    "new style getargs format but argument is not a tuple");
 		return 0;
 	}
-	
+
 	len = PyTuple_GET_SIZE(args);
-	
+
 	if (len < min || max < len) {
 		if (message == NULL) {
 			PyOS_snprintf(msgbuf, sizeof(msgbuf),
@@ -308,12 +308,12 @@
 		PyErr_SetString(PyExc_TypeError, message);
 		return 0;
 	}
-	
+
 	for (i = 0; i < len; i++) {
 		if (*format == '|')
 			format++;
 		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
-				  flags, levels, msgbuf, 
+				  flags, levels, msgbuf,
 				  sizeof(msgbuf), &freelist);
 		if (msg) {
 			seterror(i+1, msg, levels, fname, message);
@@ -328,7 +328,7 @@
 			     "bad format string: %.200s", formatsave);
 		return cleanreturn(0, freelist);
 	}
-	
+
 	return cleanreturn(1, freelist);
 }
 
@@ -392,14 +392,14 @@
 
 static char *
 converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
-             int *levels, char *msgbuf, size_t bufsize, int toplevel, 
+             int *levels, char *msgbuf, size_t bufsize, int toplevel,
              PyObject **freelist)
 {
 	int level = 0;
 	int n = 0;
 	const char *format = *p_format;
 	int i;
-	
+
 	for (;;) {
 		int c = *format++;
 		if (c == '(') {
@@ -417,17 +417,17 @@
 		else if (level == 0 && isalpha(Py_CHARMASK(c)))
 			n++;
 	}
-	
+
 	if (!PySequence_Check(arg) || PyString_Check(arg)) {
 		levels[0] = 0;
 		PyOS_snprintf(msgbuf, bufsize,
 			      toplevel ? "expected %d arguments, not %.50s" :
 			              "must be %d-item sequence, not %.50s",
-			      n, 
+			      n,
 			      arg == Py_None ? "None" : arg->ob_type->tp_name);
 		return msgbuf;
 	}
-	
+
 	if ((i = PySequence_Size(arg)) != n) {
 		levels[0] = 0;
 		PyOS_snprintf(msgbuf, bufsize,
@@ -449,7 +449,7 @@
 			strncpy(msgbuf, "is not retrievable", bufsize);
 			return msgbuf;
 		}
-		msg = convertitem(item, &format, p_va, flags, levels+1, 
+		msg = convertitem(item, &format, p_va, flags, levels+1,
 				  msgbuf, bufsize, freelist);
 		/* PySequence_GetItem calls tp->sq_item, which INCREFs */
 		Py_XDECREF(item);
@@ -472,16 +472,16 @@
 {
 	char *msg;
 	const char *format = *p_format;
-	
+
 	if (*format == '(' /* ')' */) {
 		format++;
-		msg = converttuple(arg, &format, p_va, flags, levels, msgbuf, 
+		msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
 				   bufsize, 0, freelist);
 		if (msg == NULL)
 			format++;
 	}
 	else {
-		msg = convertsimple(arg, &format, p_va, flags, 
+		msg = convertsimple(arg, &format, p_va, flags,
 				    msgbuf, bufsize, freelist);
 		if (msg != NULL)
 			levels[0] = 0;
@@ -502,7 +502,7 @@
 converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
 {
 	assert(expected != NULL);
-	assert(arg != NULL); 
+	assert(arg != NULL);
 	PyOS_snprintf(msgbuf, bufsize,
 		      "must be %.50s, not %.50s", expected,
 		      arg == Py_None ? "None" : arg->ob_type->tp_name);
@@ -548,9 +548,9 @@
 	const char *format = *p_format;
 	char c = *format++;
 	PyObject *uarg;
-	
+
 	switch (c) {
-	
+
 	case 'b': { /* unsigned byte -- very short int */
 		char *p = va_arg(*p_va, char *);
 		long ival;
@@ -573,9 +573,9 @@
 			*p = (unsigned char) ival;
 		break;
 	}
-	
+
 	case 'B': {/* byte sized bitfield - both signed and unsigned
-		      values allowed */  
+		      values allowed */
 		char *p = va_arg(*p_va, char *);
 		long ival;
 		if (float_argument_error(arg))
@@ -587,7 +587,7 @@
 			*p = (unsigned char) ival;
 		break;
 	}
-	
+
 	case 'h': {/* signed short int */
 		short *p = va_arg(*p_va, short *);
 		long ival;
@@ -610,9 +610,9 @@
 			*p = (short) ival;
 		break;
 	}
-	
+
 	case 'H': { /* short int sized bitfield, both signed and
-		       unsigned allowed */ 
+		       unsigned allowed */
 		unsigned short *p = va_arg(*p_va, unsigned short *);
 		long ival;
 		if (float_argument_error(arg))
@@ -649,7 +649,7 @@
 	}
 
 	case 'I': { /* int sized bitfield, both signed and
-		       unsigned allowed */ 
+		       unsigned allowed */
 		unsigned int *p = va_arg(*p_va, unsigned int *);
 		unsigned int ival;
 		if (float_argument_error(arg))
@@ -661,7 +661,7 @@
 			*p = ival;
 		break;
 	}
-	
+
 	case 'n': /* Py_ssize_t */
 #if SIZEOF_SIZE_T != SIZEOF_LONG
 	{
@@ -703,7 +703,7 @@
 		*p = ival;
 		break;
 	}
-	
+
 #ifdef HAVE_LONG_LONG
 	case 'L': {/* PY_LONG_LONG */
 		PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
@@ -727,7 +727,7 @@
 		break;
 	}
 #endif
-	
+
 	case 'f': {/* float */
 		float *p = va_arg(*p_va, float *);
 		double dval = PyFloat_AsDouble(arg);
@@ -737,7 +737,7 @@
 			*p = (float) dval;
 		break;
 	}
-	
+
 	case 'd': {/* double */
 		double *p = va_arg(*p_va, double *);
 		double dval = PyFloat_AsDouble(arg);
@@ -747,7 +747,7 @@
 			*p = dval;
 		break;
 	}
-	
+
 #ifndef WITHOUT_COMPLEX
 	case 'D': {/* complex double */
 		Py_complex *p = va_arg(*p_va, Py_complex *);
@@ -760,7 +760,7 @@
 		break;
 	}
 #endif /* WITHOUT_COMPLEX */
-	
+
 	case 'c': {/* char */
 		char *p = va_arg(*p_va, char *);
 		if (PyString_Check(arg) && PyString_Size(arg) == 1)
@@ -773,7 +773,7 @@
 			return converterr("char < 256", arg, msgbuf, bufsize);
 		break;
 	}
-	
+
 	case 'C': {/* unicode char */
 		int *p = va_arg(*p_va, int *);
 		if (PyString_Check(arg) && PyString_Size(arg) == 1)
@@ -785,17 +785,16 @@
 			return converterr("char", arg, msgbuf, bufsize);
 		break;
 	}
-	
-	case 's': {/* string */
+
+	/* XXX WAAAAH!  's', 'y', 'z', 'u', 'Z', 'e', 'w', 't' codes all
+	   need to be cleaned up! */
+
+	case 's': {/* text string */
 		if (*format == '#') {
 			void **p = (void **)va_arg(*p_va, char **);
 			FETCH_SIZE;
-			
-			if (PyString_Check(arg)) {
-				*p = PyString_AS_STRING(arg);
-				STORE_SIZE(PyString_GET_SIZE(arg));
-			}
-			else if (PyUnicode_Check(arg)) {
+
+			if (PyUnicode_Check(arg)) {
 				uarg = UNICODE_DEFAULT_ENCODING(arg);
 				if (uarg == NULL)
 					return converterr(CONV_UNICODE,
@@ -804,6 +803,7 @@
 				STORE_SIZE(PyString_GET_SIZE(uarg));
 			}
 			else { /* any buffer-like object */
+				/* XXX Really? */
 				char *buf;
 				Py_ssize_t count = convertbuffer(arg, p, &buf);
 				if (count < 0)
@@ -813,10 +813,8 @@
 			format++;
 		} else {
 			char **p = va_arg(*p_va, char **);
-			
-			if (PyString_Check(arg))
-				*p = PyString_AS_STRING(arg);
-			else if (PyUnicode_Check(arg)) {
+
+			if (PyUnicode_Check(arg)) {
 				uarg = UNICODE_DEFAULT_ENCODING(arg);
 				if (uarg == NULL)
 					return converterr(CONV_UNICODE,
@@ -832,45 +830,29 @@
 		break;
 	}
 
-	case 'y': {/* bytes */
+	case 'y': {/* any buffer-like object, but not PyUnicode */
+		void **p = (void **)va_arg(*p_va, char **);
+		char *buf;
+		Py_ssize_t count = convertbuffer(arg, p, &buf);
+		if (count < 0)
+			return converterr(buf, arg, msgbuf, bufsize);
 		if (*format == '#') {
-			void **p = (void **)va_arg(*p_va, char **);
 			FETCH_SIZE;
-			
-			if (PyBytes_Check(arg)) {
-				*p = PyBytes_AS_STRING(arg);
-				STORE_SIZE(PyBytes_GET_SIZE(arg));
-			}
-			else
-				return converterr("bytes", arg, msgbuf, bufsize);
+			STORE_SIZE(count);
 			format++;
-		} else {
-			char **p = va_arg(*p_va, char **);
-			
-			if (PyBytes_Check(arg))
-				*p = PyBytes_AS_STRING(arg);
-			else
-				return converterr("bytes", arg, msgbuf, bufsize);
-			if ((Py_ssize_t)strlen(*p) != PyBytes_Size(arg))
-				return converterr("bytes without null bytes",
-						  arg, msgbuf, bufsize);
 		}
 		break;
 	}
 
-	case 'z': {/* string, may be NULL (None) */
+	case 'z': {/* like 's' or 's#', but None is okay, stored as NULL */
 		if (*format == '#') { /* any buffer-like object */
 			void **p = (void **)va_arg(*p_va, char **);
 			FETCH_SIZE;
-			
+
 			if (arg == Py_None) {
 				*p = 0;
 				STORE_SIZE(0);
 			}
-			else if (PyString_Check(arg)) {
-				*p = PyString_AS_STRING(arg);
-				STORE_SIZE(PyString_GET_SIZE(arg));
-			}
 			else if (PyUnicode_Check(arg)) {
 				uarg = UNICODE_DEFAULT_ENCODING(arg);
 				if (uarg == NULL)
@@ -880,6 +862,7 @@
 				STORE_SIZE(PyString_GET_SIZE(uarg));
 			}
 			else { /* any buffer-like object */
+				/* XXX Really? */
 				char *buf;
 				Py_ssize_t count = convertbuffer(arg, p, &buf);
 				if (count < 0)
@@ -889,7 +872,7 @@
 			format++;
 		} else {
 			char **p = va_arg(*p_va, char **);
-			
+
 			if (arg == Py_None)
 				*p = 0;
 			else if (PyString_Check(arg))
@@ -902,31 +885,33 @@
 				*p = PyString_AS_STRING(uarg);
 			}
 			else
-				return converterr("string or None", 
+				return converterr("string or None",
 						  arg, msgbuf, bufsize);
 			if (*format == '#') {
 				FETCH_SIZE;
 				assert(0); /* XXX redundant with if-case */
-				if (arg == Py_None)
-					*q = 0;
-				else
-					*q = PyString_Size(arg);
+				if (arg == Py_None) {
+					STORE_SIZE(0);
+				}
+				else {
+					STORE_SIZE(PyString_Size(arg));
+				}
 				format++;
 			}
 			else if (*p != NULL &&
 				 (Py_ssize_t)strlen(*p) != PyString_Size(arg))
 				return converterr(
-					"string without null bytes or None", 
+					"string without null bytes or None",
 					arg, msgbuf, bufsize);
 		}
 		break;
 	}
-	
+
 	case 'Z': {/* unicode, may be NULL (None) */
 		if (*format == '#') { /* any buffer-like object */
 			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
 			FETCH_SIZE;
-			
+
 			if (arg == Py_None) {
 				*p = 0;
 				STORE_SIZE(0);
@@ -938,18 +923,18 @@
 			format++;
 		} else {
 			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
-			
+
 			if (arg == Py_None)
 				*p = 0;
 			else if (PyUnicode_Check(arg))
 				*p = PyUnicode_AS_UNICODE(arg);
 			else
-				return converterr("string or None", 
+				return converterr("string or None",
 						  arg, msgbuf, bufsize);
 		}
 		break;
 	}
-	
+
 	case 'e': {/* encoded string */
 		char **buffer;
 		const char *encoding;
@@ -962,10 +947,10 @@
 		encoding = (const char *)va_arg(*p_va, const char *);
 		if (encoding == NULL)
 			encoding = PyUnicode_GetDefaultEncoding();
-			
+
 		/* Get output buffer parameter:
 		   's' (recode all objects via Unicode) or
-		   't' (only recode non-string objects) 
+		   't' (only recode non-string objects)
 		*/
 		if (*format == 's')
 			recode_strings = 1;
@@ -978,9 +963,9 @@
 		buffer = (char **)va_arg(*p_va, char **);
 		format++;
 		if (buffer == NULL)
-			return converterr("(buffer is NULL)", 
+			return converterr("(buffer is NULL)",
 					  arg, msgbuf, bufsize);
-			
+
 		/* Encode object */
 		if (!recode_strings &&
                     (PyString_Check(arg) || PyBytes_Check(arg))) {
@@ -997,9 +982,9 @@
 			u = PyUnicode_FromObject(arg);
 			if (u == NULL)
 				return converterr(
-					"string or unicode or text buffer", 
+					"string or unicode or text buffer",
 					arg, msgbuf, bufsize);
-			
+
 			/* Encode object; use default error handling */
 			s = PyUnicode_AsEncodedString(u,
 						      encoding,
@@ -1008,28 +993,28 @@
 			if (s == NULL)
 				return converterr("(encoding failed)",
 						  arg, msgbuf, bufsize);
-			if (!PyBytes_Check(s)) {
+			if (!PyString_Check(s)) {
 				Py_DECREF(s);
 				return converterr(
 					"(encoder failed to return bytes)",
 					arg, msgbuf, bufsize);
 			}
-			size = PyBytes_GET_SIZE(s);
-			ptr = PyBytes_AS_STRING(s);
+			size = PyString_GET_SIZE(s);
+			ptr = PyString_AS_STRING(s);
 			if (ptr == NULL)
 				ptr = "";
 		}
 
 		/* Write output; output is guaranteed to be 0-terminated */
-		if (*format == '#') { 
+		if (*format == '#') {
 			/* Using buffer length parameter '#':
-				   
+
 			   - if *buffer is NULL, a new buffer of the
 			   needed size is allocated and the data
 			   copied into it; *buffer is updated to point
 			   to the new buffer; the caller is
 			   responsible for PyMem_Free()ing it after
-			   usage 
+			   usage
 
 			   - if *buffer is not NULL, the data is
 			   copied to *buffer; *buffer_len has to be
@@ -1037,11 +1022,11 @@
 			   buffer overflow is signalled with an error;
 			   buffer has to provide enough room for the
 			   encoded string plus the trailing 0-byte
-			   
+
 			   - in both cases, *buffer_len is updated to
 			   the size of the buffer /excluding/ the
-			   trailing 0-byte 
-			   
+			   trailing 0-byte
+
 			*/
 			FETCH_SIZE;
 
@@ -1070,7 +1055,7 @@
 				if (size + 1 > BUFFER_LEN) {
 					Py_DECREF(s);
 					return converterr(
-						"(buffer overflow)", 
+						"(buffer overflow)",
 						arg, msgbuf, bufsize);
 				}
 			}
@@ -1078,10 +1063,10 @@
 			STORE_SIZE(size);
 		} else {
 			/* Using a 0-terminated buffer:
-				   
+
 			   - the encoded string has to be 0-terminated
 			   for this variant to work; if it is not, an
-			   error raised 
+			   error raised
 
 			   - a new buffer of the needed size is
 			   allocated and the data copied into it;
@@ -1114,55 +1099,45 @@
 	}
 
 	case 'u': {/* raw unicode buffer (Py_UNICODE *) */
-		if (*format == '#') { /* any buffer-like object */
-			void **p = (void **)va_arg(*p_va, char **);
+		Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+		if (!PyUnicode_Check(arg))
+			return converterr("str", arg, msgbuf, bufsize);
+		*p = PyUnicode_AS_UNICODE(arg);
+		if (*format == '#') { /* store pointer and size */
 			FETCH_SIZE;
-			if (PyUnicode_Check(arg)) {
-			    	*p = PyUnicode_AS_UNICODE(arg);
-				STORE_SIZE(PyUnicode_GET_SIZE(arg));
-			}
-			else {
-				return converterr("cannot convert raw buffers",
-						  arg, msgbuf, bufsize);
-			}
+			STORE_SIZE(PyUnicode_GET_SIZE(arg));
 			format++;
-		} else {
-			Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
-			if (PyUnicode_Check(arg))
-				*p = PyUnicode_AS_UNICODE(arg);
-			else
-				return converterr("unicode", arg, msgbuf, bufsize);
 		}
 		break;
 	}
 
-	case 'S': { /* string object */
+	case 'S': { /* PyString object */
 		PyObject **p = va_arg(*p_va, PyObject **);
-		if (PyString_Check(arg) || PyUnicode_Check(arg))
-			*p = arg;
-		else
-			return converterr("string", arg, msgbuf, bufsize);
-		break;
-	}
-
-	case 'Y': { /* bytes object */
-		PyObject **p = va_arg(*p_va, PyObject **);
-		if (PyBytes_Check(arg))
+		if (PyString_Check(arg))
 			*p = arg;
 		else
 			return converterr("bytes", arg, msgbuf, bufsize);
 		break;
 	}
-	
-	case 'U': { /* Unicode object */
+
+	case 'Y': { /* PyBytes object */
+		PyObject **p = va_arg(*p_va, PyObject **);
+		if (PyBytes_Check(arg))
+			*p = arg;
+		else
+			return converterr("buffer", arg, msgbuf, bufsize);
+		break;
+	}
+
+	case 'U': { /* PyUnicode object */
 		PyObject **p = va_arg(*p_va, PyObject **);
 		if (PyUnicode_Check(arg))
 			*p = arg;
 		else
-			return converterr("unicode", arg, msgbuf, bufsize);
+			return converterr("str", arg, msgbuf, bufsize);
 		break;
 	}
-	
+
 	case 'O': { /* object */
 		PyTypeObject *type;
 		PyObject **p;
@@ -1180,12 +1155,12 @@
 			inquiry pred = va_arg(*p_va, inquiry);
 			p = va_arg(*p_va, PyObject **);
 			format++;
-			if ((*pred)(arg)) 
+			if ((*pred)(arg))
 				*p = arg;
 			else
-				return converterr("(unspecified)", 
+				return converterr("(unspecified)",
 						  arg, msgbuf, bufsize);
-				
+
 		}
 		else if (*format == '&') {
 			typedef int (*converter)(PyObject *, void *);
@@ -1193,7 +1168,7 @@
 			void *addr = va_arg(*p_va, void *);
 			format++;
 			if (! (*convert)(arg, addr))
-				return converterr("(unspecified)", 
+				return converterr("(unspecified)",
 						  arg, msgbuf, bufsize);
 		}
 		else {
@@ -1202,27 +1177,27 @@
 		}
 		break;
 	}
-		
-		
+
+
 	case 'w': { /* memory buffer, read-write access */
 		void **p = va_arg(*p_va, void **);
 		PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
 		int count;
                 int temp=-1;
                 Py_buffer view;
-			
-		if (pb == NULL || 
+
+		if (pb == NULL ||
 		    pb->bf_getbuffer == NULL ||
-                    ((temp = (*pb->bf_getbuffer)(arg, &view, 
+                    ((temp = (*pb->bf_getbuffer)(arg, &view,
                                                  PyBUF_SIMPLE)) != 0) ||
                     view.readonly == 1) {
                         if (temp==0 && pb->bf_releasebuffer != NULL) {
                                 (*pb->bf_releasebuffer)(arg, &view);
                         }
-			return converterr("single-segment read-write buffer", 
+			return converterr("single-segment read-write buffer",
 					  arg, msgbuf, bufsize);
                 }
-                        
+
                 if ((count = view.len) < 0)
 			return converterr("(unspecified)", arg, msgbuf, bufsize);
                 *p = view.buf;
@@ -1243,17 +1218,17 @@
 		PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
 		int count;
                 Py_buffer view;
-		
+
 		if (*format++ != '#')
 			return converterr(
-				"invalid use of 't' format character", 
+				"invalid use of 't' format character",
 				arg, msgbuf, bufsize);
 		if (pb == NULL || pb->bf_getbuffer == NULL)
 			return converterr(
 				"bytes or read-only character buffer",
 				arg, msgbuf, bufsize);
 
-		if ((*pb->bf_getbuffer)(arg, &view, PyBUF_SIMPLE) != 0) 
+		if ((*pb->bf_getbuffer)(arg, &view, PyBUF_SIMPLE) != 0)
 			return converterr("string or single-segment read-only buffer",
                                           arg, msgbuf, bufsize);
 
@@ -1261,7 +1236,7 @@
                 *p = view.buf;
                 /* XXX : shouldn't really release buffer, but it should be O.K.
                 */
-                if (pb->bf_releasebuffer != NULL) 
+                if (pb->bf_releasebuffer != NULL)
                         (*pb->bf_releasebuffer)(arg, &view);
 		if (count < 0)
 			return converterr("(unspecified)", arg, msgbuf, bufsize);
@@ -1274,9 +1249,9 @@
 
 	default:
 		return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
-	
+
 	}
-	
+
 	*p_format = format;
 	return NULL;
 }
@@ -1314,7 +1289,7 @@
 int
 PyArg_ParseTupleAndKeywords(PyObject *args,
 			    PyObject *keywords,
-			    const char *format, 
+			    const char *format,
 			    char **kwlist, ...)
 {
 	int retval;
@@ -1330,7 +1305,7 @@
 	}
 
 	va_start(va, kwlist);
-	retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);	
+	retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
 	va_end(va);
 	return retval;
 }
@@ -1338,7 +1313,7 @@
 int
 _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
 				  PyObject *keywords,
-				  const char *format, 
+				  const char *format,
 				  char **kwlist, ...)
 {
 	int retval;
@@ -1354,7 +1329,7 @@
 	}
 
 	va_start(va, kwlist);
-	retval = vgetargskeywords(args, keywords, format, 
+	retval = vgetargskeywords(args, keywords, format,
 				  kwlist, &va, FLAG_SIZE_T);
 	va_end(va);
 	return retval;
@@ -1364,7 +1339,7 @@
 int
 PyArg_VaParseTupleAndKeywords(PyObject *args,
                               PyObject *keywords,
-                              const char *format, 
+                              const char *format,
                               char **kwlist, va_list va)
 {
 	int retval;
@@ -1389,14 +1364,14 @@
 #endif
 #endif
 
-	retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);	
+	retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
 	return retval;
 }
 
 int
 _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
 				    PyObject *keywords,
-				    const char *format, 
+				    const char *format,
 				    char **kwlist, va_list va)
 {
 	int retval;
@@ -1421,7 +1396,7 @@
 #endif
 #endif
 
-	retval = vgetargskeywords(args, keywords, format, 
+	retval = vgetargskeywords(args, keywords, format,
 				  kwlist, &lva, FLAG_SIZE_T);
 	return retval;
 }
@@ -1504,7 +1479,7 @@
 	nkeywords = keywords == NULL ? 0 : PyDict_Size(keywords);
 
 	/* make sure there are no duplicate values for an argument;
-	   its not clear when to use the term "keyword argument vs. 
+	   its not clear when to use the term "keyword argument vs.
 	   keyword parameter in messages */
 	if (nkeywords > 0) {
 		for (i = 0; i < nargs; i++) {
@@ -1523,7 +1498,7 @@
 		}
 	}
 
-	/* required arguments missing from args can be supplied by keyword 
+	/* required arguments missing from args can be supplied by keyword
 	   arguments; set len to the number of positional arguments, and,
 	   if that's less than the minimum required, add in the number of
 	   required arguments that are supplied by keywords */
@@ -1540,7 +1515,7 @@
 	/* make sure we got an acceptable number of arguments; the message
 	   is a little confusing with keywords since keyword arguments
 	   which are supplied, but don't match the required arguments
-	   are not included in the "%d given" part of the message 
+	   are not included in the "%d given" part of the message
 	   XXX and this isn't a bug!? */
 	if (len < min || max < len) {
 		if (message == NULL) {
@@ -1565,7 +1540,7 @@
 		if (*format == '|')
 			format++;
 		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
-				  flags, levels, msgbuf, sizeof(msgbuf), 
+				  flags, levels, msgbuf, sizeof(msgbuf),
 				  &freelist);
 		if (msg) {
 			seterror(i+1, msg, levels, fname, message);
@@ -1573,11 +1548,11 @@
 		}
 	}
 
-	/* handle no keyword parameters in call */	
+	/* handle no keyword parameters in call */
 	if (nkeywords == 0)
 		return cleanreturn(1, freelist);
 
-	/* convert the keyword arguments; this uses the format 
+	/* convert the keyword arguments; this uses the format
 	   string where it was left after processing args */
 	for (i = nargs; i < max; i++) {
 		PyObject *item;
@@ -1586,7 +1561,7 @@
 		item = PyDict_GetItemString(keywords, kwlist[i]);
 		if (item != NULL) {
 			Py_INCREF(item);
-			msg = convertitem(item, &format, p_va, flags, levels, 
+			msg = convertitem(item, &format, p_va, flags, levels,
 					  msgbuf, sizeof(msgbuf), &freelist);
 			Py_DECREF(item);
 			if (msg) {
@@ -1617,7 +1592,7 @@
 			int match = 0;
 			char *ks;
 			if (!PyString_Check(key) && !PyUnicode_Check(key)) {
-				PyErr_SetString(PyExc_TypeError, 
+				PyErr_SetString(PyExc_TypeError,
 					        "keywords must be strings");
 				return cleanreturn(0, freelist);
 			}
@@ -1647,7 +1622,7 @@
 {
         const char *format = *p_format;
 	char c = *format++;
-	
+
 	switch (c) {
 
 	/* simple codes
@@ -1681,9 +1656,9 @@
 			(void) va_arg(*p_va, Py_ssize_t *);
 			break;
 		}
-	
+
 	/* string codes */
-		
+
 	case 'e': /* string with encoding */
 		{
 			(void) va_arg(*p_va, const char *);
@@ -1693,7 +1668,7 @@
 			format++;
 			/* explicit fallthrough to string cases */
 		}
-	
+
 	case 's': /* string */
 	case 'z': /* string or None */
 	case 'y': /* bytes */
@@ -1721,7 +1696,7 @@
 			(void) va_arg(*p_va, PyObject **);
 			break;
 		}
-	
+
 	case 'O': /* object */
 		{
 			if (*format == '!') {
@@ -1750,16 +1725,16 @@
 			}
 			break;
 		}
-	
+
 	default:
 err:
 		return "impossible<bad format char>";
-	
+
 	}
 
 	/* The "(...)" format code for tuples is not handled here because
 	 * it is not allowed with keyword args. */
-	
+
 	*p_format = format;
 	return NULL;
 }
@@ -1784,19 +1759,19 @@
 		PyErr_SetString(PyExc_SystemError,
 		    "PyArg_UnpackTuple() argument list is not a tuple");
 		return 0;
-	}	
+	}
 	l = PyTuple_GET_SIZE(args);
 	if (l < min) {
 		if (name != NULL)
 			PyErr_Format(
 			    PyExc_TypeError,
-			    "%s expected %s%zd arguments, got %zd", 
+			    "%s expected %s%zd arguments, got %zd",
 			    name, (min == max ? "" : "at least "), min, l);
 		else
 			PyErr_Format(
 			    PyExc_TypeError,
 			    "unpacked tuple should have %s%zd elements,"
-			    " but has %zd", 
+			    " but has %zd",
 			    (min == max ? "" : "at least "), min, l);
 		va_end(vargs);
 		return 0;
@@ -1805,13 +1780,13 @@
 		if (name != NULL)
 			PyErr_Format(
 			    PyExc_TypeError,
-			    "%s expected %s%zd arguments, got %zd", 
+			    "%s expected %s%zd arguments, got %zd",
 			    name, (min == max ? "" : "at most "), max, l);
 		else
 			PyErr_Format(
 			    PyExc_TypeError,
 			    "unpacked tuple should have %s%zd elements,"
-			    " but has %zd", 
+			    " but has %zd",
 			    (min == max ? "" : "at most "), max, l);
 		va_end(vargs);
 		return 0;
@@ -1827,7 +1802,7 @@
 
 /* For type constructors that don't take keyword args
  *
- * Sets a TypeError and returns 0 if the kwds dict is 
+ * Sets a TypeError and returns 0 if the kwds dict is
  * not empty, returns 1 otherwise
  */
 int
@@ -1841,8 +1816,8 @@
 	}
 	if (PyDict_Size(kw) == 0)
 		return 1;
-	
-	PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments", 
+
+	PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
 			funcname);
 	return 0;
 }
diff --git a/Python/import.c b/Python/import.c
index a096519..289a1fb 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -76,9 +76,10 @@
 		      3060 (PEP 3115 metaclass syntax)
 		      3070 (PEP 3109 raise changes)
 		      3080 (PEP 3137 make __file__ and __name__ unicode)
+		      3090 (kill str8 interning)
 .
 */
-#define MAGIC (3080 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (3090 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
 /* Magic word as global; note that _PyImport_Init() can change the
    value of this global to accommodate for alterations of how the
@@ -2212,14 +2213,14 @@
 							      PyUnicode_GetSize(item),
 							      NULL);
 			} else {
-				item8 = PyUnicode_AsEncodedString(item, 
-				Py_FileSystemDefaultEncoding, NULL);
+				item8 = PyUnicode_AsEncodedString(item,
+					Py_FileSystemDefaultEncoding, NULL);
 			}
 			if (!item8) {
 				PyErr_SetString(PyExc_ValueError, "Cannot encode path item");
 				return 0;
 			}
-			subname = PyBytes_AsString(item8);
+			subname = PyString_AS_STRING(item8);
 			if (buflen + strlen(subname) >= MAXPATHLEN) {
 				PyErr_SetString(PyExc_ValueError,
 						"Module name too long");
diff --git a/Python/mactoolboxglue.c b/Python/mactoolboxglue.c
index 0714cff..454553e 100644
--- a/Python/mactoolboxglue.c
+++ b/Python/mactoolboxglue.c
@@ -194,7 +194,7 @@
 PyMac_BuildOSType(OSType t)
 {
 	uint32_t tmp = htonl((uint32_t)t);
-	return PyBytes_FromStringAndSize((char *)&tmp, 4);
+	return PyString_FromStringAndSize((char *)&tmp, 4);
 }
 
 /* Convert an NumVersion value to a 4-element tuple */
diff --git a/Python/marshal.c b/Python/marshal.c
index 5cc0fb8..a40aecc 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -36,8 +36,6 @@
 #define TYPE_BINARY_COMPLEX	'y'
 #define TYPE_LONG		'l'
 #define TYPE_STRING		's'
-#define TYPE_INTERNED		't'
-#define TYPE_STRINGREF		'R'
 #define TYPE_TUPLE		'('
 #define TYPE_LIST		'['
 #define TYPE_DICT		'{'
@@ -231,31 +229,7 @@
 	}
 #endif
 	else if (PyString_Check(v)) {
-		if (p->strings && PyString_CHECK_INTERNED(v)) {
-			PyObject *o = PyDict_GetItem(p->strings, v);
-			if (o) {
-				long w = PyInt_AsLong(o);
-				w_byte(TYPE_STRINGREF, p);
-				w_long(w, p);
-				goto exit;
-			}
-			else {
-				int ok;
-				o = PyInt_FromSsize_t(PyDict_Size(p->strings));
-				ok = o &&
-				     PyDict_SetItem(p->strings, v, o) >= 0;
-				Py_XDECREF(o);
-				if (!ok) {
-					p->depth--;
-					p->error = 1;
-					return;
-				}
-				w_byte(TYPE_INTERNED, p);
-			}
-		}
-		else {
-			w_byte(TYPE_STRING, p);
-		}
+		w_byte(TYPE_STRING, p);
 		n = PyString_GET_SIZE(v);
 		if (n > INT_MAX) {
 			/* huge strings are not supported */
@@ -275,14 +249,14 @@
 			return;
 		}
 		w_byte(TYPE_UNICODE, p);
-		n = PyBytes_GET_SIZE(utf8);
+		n = PyString_GET_SIZE(utf8);
 		if (n > INT_MAX) {
 			p->depth--;
 			p->error = 1;
 			return;
 		}
 		w_long((long)n, p);
-		w_string(PyBytes_AS_STRING(utf8), (int)n, p);
+		w_string(PyString_AS_STRING(utf8), (int)n, p);
 		Py_DECREF(utf8);
 	}
 	else if (PyTuple_Check(v)) {
@@ -389,7 +363,6 @@
 		w_byte(TYPE_UNKNOWN, p);
 		p->error = 1;
 	}
-   exit:
 	p->depth--;
 }
 
@@ -703,7 +676,6 @@
 		}
 #endif
 
-	case TYPE_INTERNED:
 	case TYPE_STRING:
 		n = r_long(p);
 		if (n < 0 || n > INT_MAX) {
@@ -723,25 +695,6 @@
 			retval = NULL;
 			break;
 		}
-		if (type == TYPE_INTERNED) {
-			PyString_InternInPlace(&v);
-			if (PyList_Append(p->strings, v) < 0) {
-				retval = NULL;
-				break;
-			}
-		}
-		retval = v;
-		break;
-
-	case TYPE_STRINGREF:
-		n = r_long(p);
-		if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {
-			PyErr_SetString(PyExc_ValueError, "bad marshal data");
-			retval = NULL;
-			break;
-		}
-		v = PyList_GET_ITEM(p->strings, n);
-		Py_INCREF(v);
 		retval = v;
 		break;
 
diff --git a/Python/modsupport.c b/Python/modsupport.c
index 8f25ed2..144fb4f 100644
--- a/Python/modsupport.c
+++ b/Python/modsupport.c
@@ -504,7 +504,7 @@
 					}
 					n = (Py_ssize_t)m;
 				}
-				v = PyBytes_FromStringAndSize(str, n);
+				v = PyString_FromStringAndSize(str, n);
 			}
 			return v;
 		}
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index ec9ed02..0b3935a 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -75,6 +75,7 @@
 int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */
 int Py_InspectFlag; /* Needed to determine whether to exit at SystemError */
 int Py_NoSiteFlag; /* Suppress 'import site' */
+int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */
 int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */
 int Py_FrozenFlag; /* Needed by getpath.c */
 int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
@@ -234,6 +235,7 @@
 	if (pstderr == NULL)
 		Py_FatalError("Py_Initialize: can't set preliminary stderr");
 	PySys_SetObject("stderr", pstderr);
+	PySys_SetObject("__stderr__", pstderr);
 
 	_PyImport_Init();
 
@@ -261,8 +263,28 @@
 #endif /* WITH_THREAD */
 
 	warnings_module = PyImport_ImportModule("warnings");
-	if (!warnings_module)
+	if (!warnings_module) {
 		PyErr_Clear();
+	}
+	else {
+		PyObject *o;
+		char *action[8];
+
+		if (Py_BytesWarningFlag > 1)
+			*action = "error";
+		else if (Py_BytesWarningFlag)
+			*action = "default";
+		else
+			*action = "ignore";
+
+		o = PyObject_CallMethod(warnings_module,
+					"simplefilter", "sO",
+					*action, PyExc_BytesWarning);
+		if (o == NULL)
+			Py_FatalError("Py_Initialize: can't initialize"
+				      "warning filter for BytesWarning.");
+		Py_DECREF(o);
+        }
 
 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
 	/* On Unix, set the file system encoding according to the
@@ -743,6 +765,7 @@
 	PySys_SetObject("stdout", std);
 	Py_DECREF(std);
 
+#if 1 /* Disable this if you have trouble debugging bootstrap stuff */
 	/* Set sys.stderr, replaces the preliminary stderr */
 	if (!(std = PyFile_FromFd(fileno(stderr), "<stderr>", "w", -1,
 				  NULL, "\n", 0))) {
@@ -751,6 +774,7 @@
         PySys_SetObject("__stderr__", std);
 	PySys_SetObject("stderr", std);
 	Py_DECREF(std);
+#endif
 
         if (0) {
   error:
@@ -1339,7 +1363,7 @@
 	PyArena *arena = PyArena_New();
 	if (arena == NULL)
 		return NULL;
-	
+
 	mod = PyParser_ASTFromString(str, "<string>", start, flags, arena);
 	if (mod != NULL)
 		ret = run_mod(mod, "<string>", globals, locals, flags, arena);
@@ -1356,7 +1380,7 @@
 	PyArena *arena = PyArena_New();
 	if (arena == NULL)
 		return NULL;
-	
+
 	mod = PyParser_ASTFromFile(fp, filename, NULL, start, 0, 0,
 				   flags, NULL, arena);
 	if (closeit)
@@ -1705,7 +1729,7 @@
 static void
 call_py_exitfuncs(void)
 {
-	if (pyexitfunc == NULL) 
+	if (pyexitfunc == NULL)
 		return;
 
 	(*pyexitfunc)();
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index d140fe3..ffaa596 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -225,14 +225,9 @@
 sys_intern(PyObject *self, PyObject *args)
 {
 	PyObject *s;
-	if (!PyArg_ParseTuple(args, "S:intern", &s))
+	if (!PyArg_ParseTuple(args, "U:intern", &s))
 		return NULL;
-	if (PyString_CheckExact(s)) {
-		Py_INCREF(s);
-		PyString_InternInPlace(&s);
-		return s;
-	}
-	else if (PyUnicode_CheckExact(s)) {
+	if (PyUnicode_CheckExact(s)) {
 		Py_INCREF(s);
 		PyUnicode_InternInPlace(&s);
 		return s;