Add functions PyUnicode_Append() and PyUnicode_AppendAndDel() that mirror
PyString_Concat() and PyString_ConcatAndDel() (the name PyUnicode_Concat()
was already taken).

Change PyObject_Repr() to always return a unicode object.

Update all repr implementations to return unicode objects.

Add a function PyObject_ReprStr8() that calls PyObject_Repr() and converts
the result to an 8bit string.

Use PyObject_ReprStr8() where using PyObject_Repr() can't be done
straightforward.
diff --git a/Objects/boolobject.c b/Objects/boolobject.c
index f98af9f..0a9f958 100644
--- a/Objects/boolobject.c
+++ b/Objects/boolobject.c
@@ -24,10 +24,10 @@
 
 	if (self == Py_True)
 		s = true_str ? true_str :
-			(true_str = PyString_InternFromString("True"));
+			(true_str = PyUnicode_FromString("True"));
 	else
 		s = false_str ? false_str :
-			(false_str = PyString_InternFromString("False"));
+			(false_str = PyUnicode_FromString("False"));
 	Py_XINCREF(s);
 	return s;
 }
diff --git a/Objects/bufferobject.c b/Objects/bufferobject.c
index eb02e32..dd25668 100644
--- a/Objects/bufferobject.c
+++ b/Objects/bufferobject.c
@@ -319,13 +319,13 @@
 	const char *status = self->b_readonly ? "read-only" : "read-write";
 
 	if ( self->b_base == NULL )
-		return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
+		return PyUnicode_FromFormat("<%s buffer ptr %p, size %zd at %p>",
 					   status,
 					   self->b_ptr,
 					   self->b_size,
 					   self);
 	else
-		return PyString_FromFormat(
+		return PyUnicode_FromFormat(
 			"<%s buffer for %p, size %zd, offset %zd at %p>",
 			status,
 			self->b_base,
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 2cdaf37..2a1dbcb 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -815,6 +815,7 @@
 static PyObject *
 bytes_repr(PyBytesObject *self)
 {
+    static const char *hexdigits = "0123456789abcdef";
     size_t newsize = 3 + 4 * self->ob_size;
     PyObject *v;
     if (newsize > PY_SSIZE_T_MAX || newsize / 4 != self->ob_size) {
@@ -822,23 +823,23 @@
             "bytes object is too large to make repr");
         return NULL;
     }
-    v = PyString_FromStringAndSize((char *)NULL, newsize);
+    v = PyUnicode_FromUnicode(NULL, newsize);
     if (v == NULL) {
         return NULL;
     }
     else {
         register Py_ssize_t i;
-        register char c;
-        register char *p;
+        register Py_UNICODE c;
+        register Py_UNICODE *p;
         int quote = '\'';
 
-        p = PyString_AS_STRING(v);
+        p = PyUnicode_AS_UNICODE(v);
         *p++ = 'b';
         *p++ = quote;
         for (i = 0; i < self->ob_size; i++) {
             /* There's at least enough room for a hex escape
                and a closing quote. */
-            assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
+            assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
             c = self->ob_bytes[i];
             if (c == quote || c == '\\')
                 *p++ = '\\', *p++ = c;
@@ -851,20 +852,21 @@
             else if (c == 0)
                 *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
             else if (c < ' ' || c >= 0x7f) {
-                /* For performance, we don't want to call
-                   PyOS_snprintf here (extra layers of
-                   function call). */
-                sprintf(p, "\\x%02x", c & 0xff);
-                                p += 4;
+                *p++ = '\\';
+                *p++ = 'x';
+                *p++ = hexdigits[(c & 0xf0) >> 4];
+                *p++ = hexdigits[c & 0xf];
             }
             else
                 *p++ = c;
         }
-        assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
+        assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
         *p++ = quote;
         *p = '\0';
-        _PyString_Resize(
-            &v, (p - PyString_AS_STRING(v)));
+        if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
+            Py_DECREF(v);
+            return NULL;
+        }
         return v;
     }
 }
diff --git a/Objects/cellobject.c b/Objects/cellobject.c
index 74fa247..1a19c6a 100644
--- a/Objects/cellobject.c
+++ b/Objects/cellobject.c
@@ -53,9 +53,9 @@
 cell_repr(PyCellObject *op)
 {
 	if (op->ob_ref == NULL)
-		return PyString_FromFormat("<cell at %p: empty>", op);
+		return PyUnicode_FromFormat("<cell at %p: empty>", op);
 
-	return PyString_FromFormat("<cell at %p: %.80s object at %p>",
+	return PyUnicode_FromFormat("<cell at %p: %.80s object at %p>",
 				   op, op->ob_ref->ob_type->tp_name,
 				   op->ob_ref);
 }
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 85826a9..e4687a3 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -258,23 +258,15 @@
 			sklassname = PyString_AS_STRING(klassname);
 	}
 	if (self == NULL)
-		result = PyString_FromFormat("<unbound method %s.%s>",
+		result = PyUnicode_FromFormat("<unbound method %s.%s>",
 					     sklassname, sfuncname);
 	else {
+		result = PyUnicode_FromFormat("<bound method %s.%s of ",
+		                              sklassname, sfuncname);
 		/* XXX Shouldn't use repr() here! */
-		PyObject *selfrepr = PyObject_Repr(self);
-		if (selfrepr == NULL)
-			goto fail;
-		if (!PyString_Check(selfrepr)) {
-			Py_DECREF(selfrepr);
-			goto fail;
-		}
-		result = PyString_FromFormat("<bound method %s.%s of %s>",
-					     sklassname, sfuncname,
-					     PyString_AS_STRING(selfrepr));
-		Py_DECREF(selfrepr);
+		PyUnicode_AppendAndDel(&result, PyObject_Repr(self));
+		PyUnicode_AppendAndDel(&result, PyUnicode_FromString(">"));
 	}
-  fail:
 	Py_XDECREF(funcname);
 	Py_XDECREF(klassname);
 	return result;
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 6d5daa8..fc7a7db 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -300,7 +300,7 @@
 	PyOS_snprintf(buf, sizeof(buf),
 		      "<code object %.100s at %p, file \"%.300s\", line %d>",
 		      name, co, filename, lineno);
-	return PyString_FromString(buf);
+	return PyUnicode_FromString(buf);
 }
 
 static PyObject *
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index b65a982..0d4b755 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -342,7 +342,7 @@
 {
 	char buf[100];
 	complex_to_buf(buf, sizeof(buf), v, PREC_REPR);
-	return PyString_FromString(buf);
+	return PyUnicode_FromString(buf);
 }
 
 static PyObject *
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index d6b789d..e9ccefa 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -24,35 +24,35 @@
 static PyObject *
 descr_repr(PyDescrObject *descr, char *format)
 {
-	return PyString_FromFormat(format, descr_name(descr),
+	return PyUnicode_FromFormat(format, descr_name(descr),
 				   descr->d_type->tp_name);
 }
 
 static PyObject *
 method_repr(PyMethodDescrObject *descr)
 {
-	return descr_repr((PyDescrObject *)descr, 
+	return descr_repr((PyDescrObject *)descr,
 			  "<method '%s' of '%s' objects>");
 }
 
 static PyObject *
 member_repr(PyMemberDescrObject *descr)
 {
-	return descr_repr((PyDescrObject *)descr, 
+	return descr_repr((PyDescrObject *)descr,
 			  "<member '%s' of '%s' objects>");
 }
 
 static PyObject *
 getset_repr(PyGetSetDescrObject *descr)
 {
-	return descr_repr((PyDescrObject *)descr, 
+	return descr_repr((PyDescrObject *)descr,
 			  "<attribute '%s' of '%s' objects>");
 }
 
 static PyObject *
 wrapperdescr_repr(PyWrapperDescrObject *descr)
 {
-	return descr_repr((PyDescrObject *)descr, 
+	return descr_repr((PyDescrObject *)descr,
 			  "<slot wrapper '%s' of '%s' objects>");
 }
 
@@ -917,7 +917,7 @@
 static PyObject *
 wrapper_repr(wrapperobject *wp)
 {
-	return PyString_FromFormat("<method-wrapper '%s' of %s object at %p>",
+	return PyUnicode_FromFormat("<method-wrapper '%s' of %s object at %p>",
 				   wp->descr->d_base->name,
 				   wp->self->ob_type->tp_name,
 				   wp->self);
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 1da24f4..b45a664 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -941,11 +941,11 @@
 
 	i = Py_ReprEnter((PyObject *)mp);
 	if (i != 0) {
-		return i > 0 ? PyString_FromString("{...}") : NULL;
+		return i > 0 ? PyUnicode_FromString("{...}") : NULL;
 	}
 
 	if (mp->ma_used == 0) {
-		result = PyString_FromString("{}");
+		result = PyUnicode_FromString("{}");
 		goto Done;
 	}
 
@@ -953,7 +953,7 @@
 	if (pieces == NULL)
 		goto Done;
 
-	colon = PyString_FromString(": ");
+	colon = PyUnicode_FromString(": ");
 	if (colon == NULL)
 		goto Done;
 
@@ -965,8 +965,8 @@
 		/* Prevent repr from deleting value during key format. */
 		Py_INCREF(value);
 		s = PyObject_Repr(key);
-		PyString_Concat(&s, colon);
-		PyString_ConcatAndDel(&s, PyObject_Repr(value));
+		PyUnicode_Append(&s, colon);
+		PyUnicode_AppendAndDel(&s, PyObject_Repr(value));
 		Py_DECREF(value);
 		if (s == NULL)
 			goto Done;
@@ -978,29 +978,29 @@
 
 	/* Add "{}" decorations to the first and last items. */
 	assert(PyList_GET_SIZE(pieces) > 0);
-	s = PyString_FromString("{");
+	s = PyUnicode_FromString("{");
 	if (s == NULL)
 		goto Done;
 	temp = PyList_GET_ITEM(pieces, 0);
-	PyString_ConcatAndDel(&s, temp);
+	PyUnicode_AppendAndDel(&s, temp);
 	PyList_SET_ITEM(pieces, 0, s);
 	if (s == NULL)
 		goto Done;
 
-	s = PyString_FromString("}");
+	s = PyUnicode_FromString("}");
 	if (s == NULL)
 		goto Done;
 	temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
-	PyString_ConcatAndDel(&temp, s);
+	PyUnicode_AppendAndDel(&temp, s);
 	PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
 	if (temp == NULL)
 		goto Done;
 
 	/* Paste them all together with ", " between. */
-	s = PyString_FromString(", ");
+	s = PyUnicode_FromString(", ");
 	if (s == NULL)
 		goto Done;
-	result = _PyString_Join(s, pieces);
+	result = PyUnicode_Join(s, pieces);
 	Py_DECREF(s);
 
 Done:
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 36e3795..f4c265a 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -111,13 +111,13 @@
     dot = strrchr(name, '.');
     if (dot != NULL) name = dot+1;
 
-    repr = PyString_FromString(name);
+    repr = PyUnicode_FromString(name);
     if (!repr) {
         Py_DECREF(repr_suffix);
         return NULL;
     }
 
-    PyString_ConcatAndDel(&repr, repr_suffix);
+    PyUnicode_AppendAndDel(&repr, repr_suffix);
     return repr;
 }
 
@@ -529,7 +529,7 @@
         if (!fmt)
             return NULL;
 
-        repr = PyObject_Repr(self->filename);
+        repr = PyObject_ReprStr8(self->filename);
         if (!repr) {
             Py_DECREF(fmt);
             return NULL;
@@ -760,7 +760,7 @@
         if (!fmt)
             return NULL;
 
-        repr = PyObject_Repr(self->filename);
+        repr = PyObject_ReprStr8(self->filename);
         if (!repr) {
             Py_DECREF(fmt);
             return NULL;
@@ -1134,7 +1134,7 @@
        If args is anything else, use the default BaseException__str__().
     */
     if (PyTuple_GET_SIZE(self->args) == 1) {
-        return PyObject_Repr(PyTuple_GET_ITEM(self->args, 0));
+        return PyObject_ReprStr8(PyTuple_GET_ITEM(self->args, 0));
     }
     return BaseException_str(self);
 }
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index e195450..7c8e2b2 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -406,7 +406,7 @@
 		PyObject *ret = NULL;
 		PyObject *name = PyUnicode_AsUnicodeEscapeString(f->f_name);
 		const char *name_str = name ? PyString_AsString(name) : "?";
-		ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>",
+		ret = PyUnicode_FromFormat("<%s file u'%s', mode '%s' at %p>",
 				   f->f_fp == NULL ? "closed" : "open",
 				   name_str,
 				   PyString_AsString(f->f_mode),
@@ -414,7 +414,7 @@
 		Py_XDECREF(name);
 		return ret;
 	} else {
-		return PyString_FromFormat("<%s file '%s', mode '%s' at %p>",
+		return PyUnicode_FromFormat("<%s file '%s', mode '%s' at %p>",
 				   f->f_fp == NULL ? "closed" : "open",
 				   PyString_AsString(f->f_name),
 				   PyString_AsString(f->f_mode),
@@ -2142,7 +2142,7 @@
                         value = PyObject_Str(v);
 	}
         else
-		value = PyObject_Repr(v);
+		value = PyObject_ReprStr8(v);
 	if (value == NULL) {
 		Py_DECREF(writer);
 		return -1;
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index fc6bedf..679e93e 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -302,7 +302,7 @@
 {
 	char buf[100];
 	format_float(buf, sizeof(buf), v, PREC_REPR);
-	return PyString_FromString(buf);
+	return PyUnicode_FromString(buf);
 }
 
 static PyObject *
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 0069fc1..6f17e7a 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -574,7 +574,7 @@
 static PyObject*
 func_repr(PyFunctionObject *op)
 {
-	return PyString_FromFormat("<function %s at %p>",
+	return PyUnicode_FromFormat("<function %s at %p>",
 				   PyString_AsString(op->func_name),
 				   op);
 }
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 5556c20..6c9745a 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -369,7 +369,7 @@
 		sobj = PyString_FromStringAndSize(s, slen);
 		if (sobj == NULL)
 			return NULL;
-		srepr = PyObject_Repr(sobj);
+		srepr = PyObject_ReprStr8(sobj);
 		Py_DECREF(sobj);
 		if (srepr == NULL)
 			return NULL;
@@ -433,7 +433,7 @@
 {
 	char buf[64];
 	PyOS_snprintf(buf, sizeof(buf), "%ld", v->ob_ival);
-	return PyString_FromString(buf);
+	return PyUnicode_FromString(buf);
 }
 
 static int
@@ -972,7 +972,7 @@
 			/* create a repr() of the input string,
 			 * just like PyInt_FromString does */
 			PyObject *srepr;
-			srepr = PyObject_Repr(x);
+			srepr = PyObject_ReprStr8(x);
 			if (srepr == NULL)
 				return NULL;
 			PyErr_Format(PyExc_ValueError,
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 0cb1a85..0180e89 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -308,11 +308,11 @@
 
 	i = Py_ReprEnter((PyObject*)v);
 	if (i != 0) {
-		return i > 0 ? PyString_FromString("[...]") : NULL;
+		return i > 0 ? PyUnicode_FromString("[...]") : NULL;
 	}
 
 	if (v->ob_size == 0) {
-		result = PyString_FromString("[]");
+		result = PyUnicode_FromString("[]");
 		goto Done;
 	}
 
@@ -335,29 +335,29 @@
 
 	/* Add "[]" decorations to the first and last items. */
 	assert(PyList_GET_SIZE(pieces) > 0);
-	s = PyString_FromString("[");
+	s = PyUnicode_FromString("[");
 	if (s == NULL)
 		goto Done;
 	temp = PyList_GET_ITEM(pieces, 0);
-	PyString_ConcatAndDel(&s, temp);
+	PyUnicode_AppendAndDel(&s, temp);
 	PyList_SET_ITEM(pieces, 0, s);
 	if (s == NULL)
 		goto Done;
 
-	s = PyString_FromString("]");
+	s = PyUnicode_FromString("]");
 	if (s == NULL)
 		goto Done;
 	temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1);
-	PyString_ConcatAndDel(&temp, s);
+	PyUnicode_AppendAndDel(&temp, s);
 	PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp);
 	if (temp == NULL)
 		goto Done;
 
 	/* Paste them all together with ", " between. */
-	s = PyString_FromString(", ");
+	s = PyUnicode_FromString(", ");
 	if (s == NULL)
 		goto Done;
-	result = _PyString_Join(s, pieces);
+	result = PyUnicode_Join(s, pieces);
 	Py_DECREF(s);
 
 Done:
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 61e5bed..d325b8e 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -1430,10 +1430,10 @@
 long_format(PyObject *aa, int base)
 {
 	register PyLongObject *a = (PyLongObject *)aa;
-	PyStringObject *str;
+	PyObject *str;
 	Py_ssize_t i, j, sz;
 	Py_ssize_t size_a;
-	char *p;
+	Py_UNICODE *p;
 	int bits;
 	char sign = '\0';
 
@@ -1459,10 +1459,10 @@
 				"int is too large to format");
 		return NULL;
 	}
-	str = (PyStringObject *) PyString_FromStringAndSize((char *)0, sz);
+	str = PyUnicode_FromUnicode(NULL, sz);
 	if (str == NULL)
 		return NULL;
-	p = PyString_AS_STRING(str) + sz;
+	p = PyUnicode_AS_UNICODE(str) + sz;
 	*p = '\0';
 	if (a->ob_size < 0)
 		sign = '-';
@@ -1486,7 +1486,7 @@
 			do {
 				char cdigit = (char)(accum & (base - 1));
 				cdigit += (cdigit < 10) ? '0' : 'a'-10;
-				assert(p > PyString_AS_STRING(str));
+				assert(p > PyUnicode_AS_UNICODE(str));
 				*--p = cdigit;
 				accumbits -= basebits;
 				accum >>= basebits;
@@ -1538,7 +1538,7 @@
 			do {
 				digit nextrem = (digit)(rem / base);
 				char c = (char)(rem - nextrem * base);
-				assert(p > PyString_AS_STRING(str));
+				assert(p > PyUnicode_AS_UNICODE(str));
 				c += (c < 10) ? '0' : 'a'-10;
 				*--p = c;
 				rem = nextrem;
@@ -1567,14 +1567,16 @@
 	}
 	if (sign)
 		*--p = sign;
-	if (p != PyString_AS_STRING(str)) {
-		char *q = PyString_AS_STRING(str);
+	if (p != PyUnicode_AS_UNICODE(str)) {
+		Py_UNICODE *q = PyUnicode_AS_UNICODE(str);
 		assert(p > q);
 		do {
 		} while ((*q++ = *p++) != '\0');
 		q--;
-		_PyString_Resize((PyObject **)&str,
-				 (Py_ssize_t) (q - PyString_AS_STRING(str)));
+		if (PyUnicode_Resize(&str, (Py_ssize_t) (q - PyUnicode_AS_UNICODE(str)))) {
+			Py_DECREF(str);
+			return NULL;
+		}
 	}
 	return (PyObject *)str;
 }
@@ -1928,7 +1930,7 @@
 	strobj = PyString_FromStringAndSize(orig_str, slen);
 	if (strobj == NULL)
 		return NULL;
-	strrepr = PyObject_Repr(strobj);
+	strrepr = PyObject_ReprStr8(strobj);
 	Py_DECREF(strobj);
 	if (strrepr == NULL)
 		return NULL;
@@ -3525,7 +3527,7 @@
 			/* create a repr() of the input string,
 			 * just like PyLong_FromString does. */
 			PyObject *srepr;
-			srepr = PyObject_Repr(x);
+			srepr = PyObject_ReprStr8(x);
 			if (srepr == NULL)
 				return NULL;
 			PyErr_Format(PyExc_ValueError,
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 4204db7..6199805 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -184,9 +184,9 @@
 meth_repr(PyCFunctionObject *m)
 {
 	if (m->m_self == NULL)
-		return PyString_FromFormat("<built-in function %s>",
+		return PyUnicode_FromFormat("<built-in function %s>",
 					   m->m_ml->ml_name);
-	return PyString_FromFormat("<built-in method %s of %s object at %p>",
+	return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
 				   m->m_ml->ml_name,
 				   m->m_self->ob_type->tp_name,
 				   m->m_self);
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index f188515..daf24eb 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -198,9 +198,9 @@
 	filename = PyModule_GetFilename((PyObject *)m);
 	if (filename == NULL) {
 		PyErr_Clear();
-		return PyString_FromFormat("<module '%s' (built-in)>", name);
+		return PyUnicode_FromFormat("<module '%s' (built-in)>", name);
 	}
-	return PyString_FromFormat("<module '%s' from '%s'>", name, filename);
+	return PyUnicode_FromFormat("<module '%s' from '%s'>", name, filename);
 }
 
 /* We only need a traverse function, no clear function: If the module
diff --git a/Objects/object.c b/Objects/object.c
index 4b210f1..be7d501 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -284,7 +284,7 @@
 			if (flags & Py_PRINT_RAW)
 				s = PyObject_Str(op);
 			else
-				s = PyObject_Repr(op);
+				s = PyObject_ReprStr8(op);
 			if (s == NULL)
 				ret = -1;
 			else {
@@ -343,6 +343,7 @@
 PyObject *
 PyObject_Repr(PyObject *v)
 {
+	PyObject *ress, *resu;
 	if (PyErr_CheckSignals())
 		return NULL;
 #ifdef USE_STACKCHECK
@@ -352,29 +353,48 @@
 	}
 #endif
 	if (v == NULL)
-		return PyString_FromString("<NULL>");
+		return PyUnicode_FromString("<NULL>");
 	else if (v->ob_type->tp_repr == NULL)
-		return PyString_FromFormat("<%s object at %p>",
-					   v->ob_type->tp_name, v);
+		return PyUnicode_FromFormat("<%s object at %p>", v->ob_type->tp_name, v);
 	else {
-		PyObject *res;
-		res = (*v->ob_type->tp_repr)(v);
-		if (res == NULL)
+		ress = (*v->ob_type->tp_repr)(v);
+		if (!ress)
 			return NULL;
-		if (PyUnicode_Check(res))
-			return res;
-		if (!PyString_Check(res)) {
+		if (PyUnicode_Check(ress))
+			return ress;
+		if (!PyString_Check(ress)) {
 			PyErr_Format(PyExc_TypeError,
 				     "__repr__ returned non-string (type %.200s)",
-				     res->ob_type->tp_name);
-			Py_DECREF(res);
+				     ress->ob_type->tp_name);
+			Py_DECREF(ress);
 			return NULL;
 		}
-		return res;
+		resu = PyUnicode_FromObject(ress);
+		Py_DECREF(ress);
+		return resu;
 	}
 }
 
 PyObject *
+PyObject_ReprStr8(PyObject *v)
+{
+	PyObject *resu = PyObject_Repr(v);
+	if (resu) {
+		PyObject *resb = PyUnicode_AsEncodedString(resu, NULL, NULL);
+		Py_DECREF(resu);
+		if (resb) {
+			PyObject *ress = PyString_FromStringAndSize(
+				PyBytes_AS_STRING(resb),
+				PyBytes_GET_SIZE(resb)
+			);
+			Py_DECREF(resb);
+			return ress;
+		}
+	}
+	return NULL;
+}
+
+PyObject *
 _PyObject_Str(PyObject *v)
 {
 	PyObject *res;
@@ -1509,7 +1529,7 @@
 static PyObject *
 none_repr(PyObject *op)
 {
-	return PyString_FromString("None");
+	return PyUnicode_FromString("None");
 }
 
 /* ARGUSED */
@@ -1551,7 +1571,7 @@
 static PyObject *
 NotImplemented_repr(PyObject *op)
 {
-	return PyString_FromString("NotImplemented");
+	return PyUnicode_FromString("NotImplemented");
 }
 
 static PyTypeObject PyNotImplemented_Type = {
diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c
index 8d71a90..c5355df 100644
--- a/Objects/rangeobject.c
+++ b/Objects/rangeobject.c
@@ -261,19 +261,19 @@
     }
 
     if (istart == 0 && istep == 1)
-        result = PyString_FromFormat("range(%s)",
-                                     PyString_AS_STRING(stop_str));
+        result = PyUnicode_FromFormat("range(%s)",
+                                      PyString_AS_STRING(stop_str));
     else if (istep == 1) {
         if (start_str)
-            result = PyString_FromFormat("range(%s, %s)",
-                                         PyString_AS_STRING(start_str),
-                                         PyString_AS_STRING(stop_str));
+            result = PyUnicode_FromFormat("range(%s, %s)",
+                                          PyString_AS_STRING(start_str),
+                                          PyString_AS_STRING(stop_str));
     }
     else if (start_str && step_str)
-        result = PyString_FromFormat("range(%s, %s, %s)",
-                                     PyString_AS_STRING(start_str),
-                                     PyString_AS_STRING(stop_str),
-                                     PyString_AS_STRING(step_str));
+        result = PyUnicode_FromFormat("range(%s, %s, %s)",
+                                      PyString_AS_STRING(start_str),
+                                      PyString_AS_STRING(stop_str),
+                                      PyString_AS_STRING(step_str));
     /* else result is NULL and an error should already be set. */
 
     Py_XDECREF(start_str);
diff --git a/Objects/setobject.c b/Objects/setobject.c
index 91f44d5..795efc5 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -613,18 +613,21 @@
 set_repr(PySetObject *so)
 {
 	PyObject *keys, *result=NULL, *listrepr;
+	int newsize;
+	Py_UNICODE *u;
+	const char *s;
 	int status = Py_ReprEnter((PyObject*)so);
 
 	if (status != 0) {
 		if (status < 0)
 			return NULL;
-		return PyString_FromFormat("%s(...)", so->ob_type->tp_name);
+		return PyUnicode_FromFormat("%s(...)", so->ob_type->tp_name);
 	}
 
 	/* shortcut for the empty set */
 	if (!so->used) {
 		Py_ReprLeave((PyObject*)so);
-		return PyString_FromFormat("%s()", so->ob_type->tp_name);
+		return PyUnicode_FromFormat("%s()", so->ob_type->tp_name);
 	}
 
 	keys = PySequence_List((PyObject *)so);
@@ -635,14 +638,28 @@
 	if (listrepr == NULL)
 		goto done;
 
-	if (so->ob_type == &PySet_Type) {
-		char *s = PyString_AS_STRING(listrepr);
-		s += 1;
-		s[strlen(s)-1] = 0;
-		result = PyString_FromFormat("{%s}", s);
-	} else {
-		result = PyString_FromFormat("%s(%s)", so->ob_type->tp_name,
-			 	PyString_AS_STRING(listrepr));
+	newsize = PyUnicode_GET_SIZE(listrepr);
+	if (so->ob_type != &PySet_Type)
+		newsize += strlen(so->ob_type->tp_name)+2;
+	result = PyUnicode_FromUnicode(NULL, newsize);
+	if (result) {
+		u = PyUnicode_AS_UNICODE(result);
+		if (so->ob_type != &PySet_Type) {
+			for (s = so->ob_type->tp_name; *s;)
+				*u++ = *s++;
+			*u++ = '(';
+			Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr),
+									 PyUnicode_GET_SIZE(listrepr));
+			u += PyUnicode_GET_SIZE(listrepr);
+			*u++ = ')';
+		} else {
+			*u++ = '{';
+			/* Omit the brackets from the listrepr */
+			Py_UNICODE_COPY(u, PyUnicode_AS_UNICODE(listrepr)+1,
+									 PyUnicode_GET_SIZE(listrepr)-2);
+			u += PyUnicode_GET_SIZE(listrepr)-2;
+			*u++ = '}';
+		}
 	}
 	Py_DECREF(listrepr);
 done:
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index d56d69b..d526a07 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -19,7 +19,7 @@
 static PyObject *
 ellipsis_repr(PyObject *op)
 {
-	return PyString_FromString("Ellipsis");
+	return PyUnicode_FromString("Ellipsis");
 }
 
 static PyTypeObject PyEllipsis_Type = {
@@ -228,14 +228,14 @@
 {
 	PyObject *s, *comma;
 
-	s = PyString_FromString("slice(");
-	comma = PyString_FromString(", ");
-	PyString_ConcatAndDel(&s, PyObject_Repr(r->start));
-	PyString_Concat(&s, comma);
-	PyString_ConcatAndDel(&s, PyObject_Repr(r->stop));
-	PyString_Concat(&s, comma);
-	PyString_ConcatAndDel(&s, PyObject_Repr(r->step));
-	PyString_ConcatAndDel(&s, PyString_FromString(")"));
+	s = PyUnicode_FromString("slice(");
+	comma = PyUnicode_FromString(", ");
+	PyUnicode_AppendAndDel(&s, PyObject_Repr(r->start));
+	PyUnicode_Append(&s, comma);
+	PyUnicode_AppendAndDel(&s, PyObject_Repr(r->stop));
+	PyUnicode_Append(&s, comma);
+	PyUnicode_AppendAndDel(&s, PyObject_Repr(r->step));
+	PyUnicode_AppendAndDel(&s, PyUnicode_FromString(")"));
 	Py_DECREF(comma);
 	return s;
 }
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 4fbb1a9..98fb0bd 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -822,36 +822,46 @@
 PyObject *
 PyString_Repr(PyObject *obj, int smartquotes)
 {
+	static const char *hexdigits = "0123456789abcdef";
 	register PyStringObject* op = (PyStringObject*) obj;
+	Py_ssize_t length = PyUnicode_GET_SIZE(op);
 	size_t newsize = 2 + 4 * op->ob_size;
 	PyObject *v;
 	if (newsize > PY_SSIZE_T_MAX || newsize / 4 != op->ob_size) {
 		PyErr_SetString(PyExc_OverflowError,
 			"string is too large to make repr");
 	}
-	v = PyString_FromStringAndSize((char *)NULL, newsize);
+	v = PyUnicode_FromUnicode(NULL, newsize);
 	if (v == NULL) {
 		return NULL;
 	}
 	else {
 		register Py_ssize_t i;
-		register char c;
-		register char *p;
+		register Py_UNICODE c;
+		register Py_UNICODE *p = PyUnicode_AS_UNICODE(v);
 		int quote;
 
 		/* figure out which quote to use; single is preferred */
 		quote = '\'';
-		if (smartquotes &&
-		    memchr(op->ob_sval, '\'', op->ob_size) &&
-		    !memchr(op->ob_sval, '"', op->ob_size))
-			quote = '"';
+		if (smartquotes) {
+			Py_UNICODE *test;
+			for (test = p; test < p+length; ++test) {
+				if (*test == '"') {
+					quote = '\''; /* switch back to single quote */
+					goto decided;
+				}
+				else if (*test == '\'')
+					quote = '"';
+			}
+			decided:
+			;
+		}
 
-		p = PyString_AS_STRING(v);
 		*p++ = quote;
 		for (i = 0; i < op->ob_size; i++) {
 			/* There's at least enough room for a hex escape
 			   and a closing quote. */
-			assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
+			assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
 			c = op->ob_sval[i];
 			if (c == quote || c == '\\')
 				*p++ = '\\', *p++ = c;
@@ -862,20 +872,21 @@
 			else if (c == '\r')
 				*p++ = '\\', *p++ = 'r';
 			else if (c < ' ' || c >= 0x7f) {
-				/* For performance, we don't want to call
-				   PyOS_snprintf here (extra layers of
-				   function call). */
-				sprintf(p, "\\x%02x", c & 0xff);
-                                p += 4;
+				*p++ = '\\';
+				*p++ = 'x';
+				*p++ = hexdigits[(c & 0xf0) >> 4];
+				*p++ = hexdigits[c & 0xf];
 			}
 			else
 				*p++ = c;
 		}
-		assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
+		assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
 		*p++ = quote;
 		*p = '\0';
-		_PyString_Resize(
-			&v, (p - PyString_AS_STRING(v)));
+		if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
+			Py_DECREF(v);
+			return NULL;
+		}
 		return v;
 	}
 }
@@ -4613,7 +4624,7 @@
 				/* Fall through */
 			case 'r':
 				if (c == 'r')
-					temp = PyObject_Repr(v);
+					temp = PyObject_ReprStr8(v);
 				if (temp == NULL)
 					goto error;
 				if (!PyString_Check(temp)) {
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index dacc3ee..fb5c246 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -210,7 +210,7 @@
 
 	n = v->ob_size;
 	if (n == 0)
-		return PyString_FromString("()");
+		return PyUnicode_FromString("()");
 
 	pieces = PyTuple_New(n);
 	if (pieces == NULL)
@@ -226,29 +226,29 @@
 
 	/* Add "()" decorations to the first and last items. */
 	assert(n > 0);
-	s = PyString_FromString("(");
+	s = PyUnicode_FromString("(");
 	if (s == NULL)
 		goto Done;
 	temp = PyTuple_GET_ITEM(pieces, 0);
-	PyString_ConcatAndDel(&s, temp);
+	PyUnicode_AppendAndDel(&s, temp);
 	PyTuple_SET_ITEM(pieces, 0, s);
 	if (s == NULL)
 		goto Done;
 
-	s = PyString_FromString(n == 1 ? ",)" : ")");
+	s = PyUnicode_FromString(n == 1 ? ",)" : ")");
 	if (s == NULL)
 		goto Done;
 	temp = PyTuple_GET_ITEM(pieces, n-1);
-	PyString_ConcatAndDel(&temp, s);
+	PyUnicode_AppendAndDel(&temp, s);
 	PyTuple_SET_ITEM(pieces, n-1, temp);
 	if (temp == NULL)
 		goto Done;
 
 	/* Paste them all together with ", " between. */
-	s = PyString_FromString(", ");
+	s = PyUnicode_FromString(", ");
 	if (s == NULL)
 		goto Done;
-	result = _PyString_Join(s, pieces);
+	result = PyUnicode_Join(s, pieces);
 	Py_DECREF(s);	
 
 Done:
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index f6ae69b..bc8f9bd 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -385,13 +385,13 @@
 		kind = "type";
 
 	if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__")) {
-		rtn = PyString_FromFormat("<%s '%s.%s'>",
+		rtn = PyUnicode_FromFormat("<%s '%s.%s'>",
 					  kind,
 					  PyString_AS_STRING(mod),
 					  PyString_AS_STRING(name));
 	}
 	else
-		rtn = PyString_FromFormat("<%s '%s'>", kind, type->tp_name);
+		rtn = PyUnicode_FromFormat("<%s '%s'>", kind, type->tp_name);
 
 	Py_XDECREF(mod);
 	Py_DECREF(name);
@@ -1006,7 +1006,7 @@
 	if (name == NULL) {
 		PyErr_Clear();
 		Py_XDECREF(name);
-		name = PyObject_Repr(cls);
+		name = PyObject_ReprStr8(cls);
 	}
 	if (name == NULL)
 		return NULL;
@@ -2481,12 +2481,12 @@
 	if (name == NULL)
 		return NULL;
 	if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__"))
-		rtn = PyString_FromFormat("<%s.%s object at %p>",
+		rtn = PyUnicode_FromFormat("<%s.%s object at %p>",
 					  PyString_AS_STRING(mod),
 					  PyString_AS_STRING(name),
 					  self);
 	else
-		rtn = PyString_FromFormat("<%s object at %p>",
+		rtn = PyUnicode_FromFormat("<%s object at %p>",
 					  type->tp_name, self);
 	Py_XDECREF(mod);
 	Py_DECREF(name);
@@ -4645,7 +4645,7 @@
 		return res;
 	}
 	PyErr_Clear();
-	return PyString_FromFormat("<%s object at %p>",
+	return PyUnicode_FromFormat("<%s object at %p>",
 				   self->ob_type->tp_name, self);
 }
 
@@ -4662,8 +4662,14 @@
 		return res;
 	}
 	else {
+		PyObject *ress;
 		PyErr_Clear();
-		return slot_tp_repr(self);
+		res = slot_tp_repr(self);
+		if (!res)
+			return NULL;
+		ress = _PyUnicode_AsDefaultEncodedString(res, NULL);
+		Py_DECREF(res);
+		return ress;
 	}
 }
 
@@ -5692,12 +5698,12 @@
 	superobject *su = (superobject *)self;
 
 	if (su->obj_type)
-		return PyString_FromFormat(
+		return PyUnicode_FromFormat(
 			"<super: <class '%s'>, <%s object>>",
 			su->type ? su->type->tp_name : "NULL",
 			su->obj_type->tp_name);
 	else
-		return PyString_FromFormat(
+		return PyUnicode_FromFormat(
 			"<super: <class '%s'>, NULL>",
 			su->type ? su->type->tp_name : "NULL");
 }
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index e77b65d..b46093e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -5854,6 +5854,29 @@
     return NULL;
 }
 
+void
+PyUnicode_Append(PyObject **pleft, PyObject *right)
+{
+	PyObject *new;
+	if (*pleft == NULL)
+		return;
+	if (right == NULL || !PyUnicode_Check(*pleft)) {
+		Py_DECREF(*pleft);
+		*pleft = NULL;
+		return;
+	}
+	new = PyUnicode_Concat(*pleft, right);
+	Py_DECREF(*pleft);
+	*pleft = new;
+}
+
+void
+PyUnicode_AppendAndDel(PyObject **pleft, PyObject *right)
+{
+	PyUnicode_Append(pleft, right);
+	Py_XDECREF(right);
+}
+
 PyDoc_STRVAR(count__doc__,
 "S.count(sub[, start[, end]]) -> int\n\
 \n\
@@ -6749,7 +6772,7 @@
 PyObject *unicode_repr(PyObject *unicode)
 {
     PyObject *repr;
-    char *p;
+    Py_UNICODE *p;
     Py_UNICODE *s = PyUnicode_AS_UNICODE(unicode);
     Py_ssize_t size = PyUnicode_GET_SIZE(unicode);
 
@@ -6771,7 +6794,7 @@
        escape.
     */
 
-    repr = PyString_FromStringAndSize(NULL,
+    repr = PyUnicode_FromUnicode(NULL,
         2 /* quotes */
 #ifdef Py_UNICODE_WIDE
         + 10*size
@@ -6782,7 +6805,7 @@
     if (repr == NULL)
         return NULL;
 
-    p = PyString_AS_STRING(repr);
+    p = PyUnicode_AS_UNICODE(repr);
 
     /* Add quote */
     *p++ = (findchar(s, size, '\'') &&
@@ -6791,9 +6814,9 @@
         Py_UNICODE ch = *s++;
 
         /* Escape quotes and backslashes */
-        if ((ch == (Py_UNICODE) PyString_AS_STRING(repr)[0]) || (ch == '\\')) {
+        if ((ch == PyUnicode_AS_UNICODE(repr)[0]) || (ch == '\\')) {
             *p++ = '\\';
-            *p++ = (char) ch;
+            *p++ = ch;
             continue;
         }
 
@@ -6877,10 +6900,10 @@
             *p++ = (char) ch;
     }
     /* Add quote */
-    *p++ = PyString_AS_STRING(repr)[0];
+    *p++ = PyUnicode_AS_UNICODE(repr)[0];
 
     *p = '\0';
-    _PyString_Resize(&repr, p - PyString_AS_STRING(repr));
+    _PyUnicode_Resize(&repr, p - PyUnicode_AS_UNICODE(repr));
     return repr;
 }
 
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 7b5b561..d30b90f 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -177,7 +177,7 @@
 		      name);
 	Py_XDECREF(nameobj);
     }
-    return PyString_FromString(buffer);
+    return PyUnicode_FromString(buffer);
 }
 
 /* Weak references only support equality, not ordering. Two weak references
@@ -451,7 +451,7 @@
 		  "<weakproxy at %p to %.100s at %p>", proxy,
 		  PyWeakref_GET_OBJECT(proxy)->ob_type->tp_name,
 		  PyWeakref_GET_OBJECT(proxy));
-    return PyString_FromString(buf);
+    return PyUnicode_FromString(buf);
 }