Make identifiers str (not str8) objects throughout.
This affects the parser, various object implementations,
and all places that put identifiers into C string literals.

In testing, a number of crashes occurred as code would
fail when the recursion limit was reached (such as the
Unicode interning dictionary having key/value pairs where
key is not value). To solve these, I added an overflowed
flag, which allows for 50 more recursions after the
limit was reached and the exception was raised, and
a recursion_critical flag, which indicates that recursion
absolutely must be allowed, i.e. that a certain call
must not cause a stack overflow exception.

There are still some places where both str and str8 are
accepted as identifiers; these should eventually be
removed.
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 791b32d..18c2eb5 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -3280,3 +3280,5 @@
     init_types();
     return ast2obj_mod(t);
 }
+
+
diff --git a/Python/ast.c b/Python/ast.c
index e0bd18e..b34411b 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -48,7 +48,8 @@
 
 static identifier
 new_identifier(const char* n, PyArena *arena) {
-    PyObject* id = PyString_InternFromString(n);
+    PyObject* id = PyUnicode_DecodeUTF8(n, strlen(n), NULL);
+    PyUnicode_InternInPlace(&id);
     PyArena_AddPyObject(arena, id);
     return id;
 }
@@ -334,12 +335,10 @@
 static int
 forbidden_name(expr_ty e, const node *n)
 {
-    const char *id;
     const char **p;
-    assert(PyString_Check(e->v.Name.id));
-    id = PyString_AS_STRING(e->v.Name.id);
+    assert(PyUnicode_Check(e->v.Name.id));
     for (p = FORBIDDEN; *p; p++) {
-        if (strcmp(*p, id) == 0) {
+        if (PyUnicode_CompareWithASCIIString(e->v.Name.id, *p) == 0) {
             ast_error(n, "assignment to keyword");
             return 1;
         }
@@ -375,7 +374,7 @@
     switch (e->kind) {
         case Attribute_kind:
             if (ctx == Store &&
-                !strcmp(PyString_AS_STRING(e->v.Attribute.attr), "None")) {
+                !PyUnicode_CompareWithASCIIString(e->v.Attribute.attr, "None")) {
                 return ast_error(n, "assignment to None");
             }
             e->v.Attribute.ctx = ctx;
@@ -2235,6 +2234,7 @@
                 int i;
                 size_t len;
                 char *s;
+		PyObject *uni;
 
                 len = 0;
                 for (i = 0; i < NCH(n); i += 2)
@@ -2255,13 +2255,20 @@
                 }
                 --s;
                 *s = '\0';
-                PyString_InternInPlace(&str);
+		uni = PyUnicode_DecodeUTF8(PyString_AS_STRING(str),
+					   PyString_GET_SIZE(str), 
+					   NULL);
+		Py_DECREF(str);
+		if (!uni)
+		    return NULL;
+		str = uni;
+                PyUnicode_InternInPlace(&str);
                 PyArena_AddPyObject(c->c_arena, str);
                 return alias(str, NULL, c->c_arena);
             }
             break;
         case STAR:
-            str = PyString_InternFromString("*");
+            str = PyUnicode_InternFromString("*");
             PyArena_AddPyObject(c->c_arena, str);
             return alias(str, NULL, c->c_arena);
         default:
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 97b2c5e..d4c8a74 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -48,7 +48,7 @@
 	}
 	func = PyTuple_GET_ITEM(args, 0); /* Better be callable */
 	name = PyTuple_GET_ITEM(args, 1);
-	if (!PyString_Check(name)) {
+	if ((!PyString_Check(name) && !PyUnicode_Check(name))) {
 		PyErr_SetString(PyExc_TypeError,
 				"__build_class__: name is not a string");
 		return NULL;
@@ -835,20 +835,23 @@
 static PyObject *
 builtin_getattr(PyObject *self, PyObject *args)
 {
-	PyObject *v, *result, *dflt = NULL;
+	PyObject *v, *result, *dflt = NULL, *release = NULL;
 	PyObject *name;
 
 	if (!PyArg_UnpackTuple(args, "getattr", 2, 3, &v, &name, &dflt))
 		return NULL;
-	if (PyUnicode_Check(name)) {
-		name = _PyUnicode_AsDefaultEncodedString(name, NULL);
-		if (name == NULL)
+
+	if (PyString_Check(name)) {
+		release = PyString_AsDecodedObject(name, NULL, NULL);
+		if (!release)
 			return NULL;
+		name = release;
 	}
 
-	if (!PyString_Check(name)) {
+	if (!PyUnicode_Check(name)) {
 		PyErr_SetString(PyExc_TypeError,
 				"getattr(): attribute name must be string");
+		Py_XDECREF(release);
 		return NULL;
 	}
 	result = PyObject_GetAttr(v, name);
@@ -859,6 +862,7 @@
 		Py_INCREF(dflt);
 		result = dflt;
 	}
+	Py_XDECREF(release);
 	return result;
 }
 
@@ -894,13 +898,7 @@
 
 	if (!PyArg_UnpackTuple(args, "hasattr", 2, 2, &v, &name))
 		return NULL;
-	if (PyUnicode_Check(name)) {
-		name = _PyUnicode_AsDefaultEncodedString(name, NULL);
-		if (name == NULL)
-			return NULL;
-	}
-
-	if (!PyString_Check(name)) {
+	if (!PyUnicode_Check(name)) {
 		PyErr_SetString(PyExc_TypeError,
 				"hasattr(): attribute name must be string");
 		return NULL;
diff --git a/Python/ceval.c b/Python/ceval.c
index 710a0d1..bb05a16 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -454,8 +454,19 @@
 		return -1;
 	}
 #endif
+	if (tstate->recursion_critical)
+		/* Somebody asked that we don't check for recursion. */
+		return 0;
+	if (tstate->overflowed) {
+		if (tstate->recursion_depth > recursion_limit + 50) {
+			/* Overflowing while handling an overflow. Give up. */
+			Py_FatalError("Cannot recover from stack overflow.");
+		}
+		return 0;
+	}
 	if (tstate->recursion_depth > recursion_limit) {
 		--tstate->recursion_depth;
+		tstate->overflowed = 1;
 		PyErr_Format(PyExc_RuntimeError,
 			     "maximum recursion depth exceeded%s",
 			     where);
@@ -2759,7 +2770,7 @@
 	   vars into frame.  This isn't too efficient right now. */
 	if (PyTuple_GET_SIZE(co->co_cellvars)) {
 		int i, j, nargs, found;
-		char *cellname, *argname;
+		Py_UNICODE *cellname, *argname;
 		PyObject *c;
 
 		nargs = co->co_argcount;
@@ -2776,13 +2787,13 @@
 		   list so that we can march over it more efficiently?
 		*/
 		for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
-			cellname = PyString_AS_STRING(
+			cellname = PyUnicode_AS_UNICODE(
 				PyTuple_GET_ITEM(co->co_cellvars, i));
 			found = 0;
 			for (j = 0; j < nargs; j++) {
-				argname = PyString_AS_STRING(
+				argname = PyUnicode_AS_UNICODE(
 					PyTuple_GET_ITEM(co->co_varnames, j));
-				if (strcmp(cellname, argname) == 0) {
+				if (Py_UNICODE_strcmp(cellname, argname) == 0) {
 					c = PyCell_New(GETLOCAL(j));
 					if (c == NULL)
 						goto fail;
@@ -3428,7 +3439,7 @@
 	if (PyMethod_Check(func))
 		return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func));
 	else if (PyFunction_Check(func))
-		return PyString_AsString(((PyFunctionObject*)func)->func_name);
+		return PyUnicode_AsString(((PyFunctionObject*)func)->func_name);
 	else if (PyCFunction_Check(func))
 		return ((PyCFunctionObject*)func)->m_ml->ml_name;
 	else
@@ -4052,8 +4063,8 @@
 			break;
 		}
 		if (skip_leading_underscores &&
-		    PyString_Check(name) &&
-		    PyString_AS_STRING(name)[0] == '_')
+		    PyUnicode_Check(name) &&
+		    PyUnicode_AS_UNICODE(name)[0] == '_')
 		{
 			Py_DECREF(name);
 			continue;
diff --git a/Python/compile.c b/Python/compile.c
index 359de58..fde4591 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -194,16 +194,16 @@
 {
 	/* Name mangling: __private becomes _classname__private.
 	   This is independent from how the name is used. */
-	const char *p, *name = PyString_AsString(ident);
-	char *buffer;
+	const Py_UNICODE *p, *name = PyUnicode_AS_UNICODE(ident);
+	Py_UNICODE *buffer;
 	size_t nlen, plen;
-	if (privateobj == NULL || !PyString_Check(privateobj) ||
+	if (privateobj == NULL || !PyUnicode_Check(privateobj) ||
 	    name == NULL || name[0] != '_' || name[1] != '_') {
 		Py_INCREF(ident);
 		return ident;
 	}
-	p = PyString_AsString(privateobj);
-	nlen = strlen(name);
+	p = PyUnicode_AS_UNICODE(privateobj);
+	nlen = Py_UNICODE_strlen(name);
 	/* Don't mangle __id__ or names with dots.
 
 	   The only time a name with a dot can occur is when
@@ -214,26 +214,26 @@
 	   mangling of the module name, e.g. __M.X.
 	*/
 	if ((name[nlen-1] == '_' && name[nlen-2] == '_') 
-	    || strchr(name, '.')) {
+	    || Py_UNICODE_strchr(name, '.')) {
 		Py_INCREF(ident);
 		return ident; /* Don't mangle __whatever__ */
 	}
 	/* Strip leading underscores from class name */
 	while (*p == '_')
 		p++;
-	if (*p == '\0') {
+	if (*p == 0) {
 		Py_INCREF(ident);
 		return ident; /* Don't mangle if class is just underscores */
 	}
-	plen = strlen(p);
-	ident = PyString_FromStringAndSize(NULL, 1 + nlen + plen);
+	plen = Py_UNICODE_strlen(p);
+	ident = PyUnicode_FromStringAndSize(NULL, 1 + nlen + plen);
 	if (!ident)
 		return 0;
 	/* ident = "_" + p[:plen] + name # i.e. 1+plen+nlen bytes */
-	buffer = PyString_AS_STRING(ident);
+	buffer = PyUnicode_AS_UNICODE(ident);
 	buffer[0] = '_';
-	strncpy(buffer+1, p, plen);
-	strcpy(buffer+1+plen, name);
+	Py_UNICODE_strncpy(buffer+1, p, plen);
+	Py_UNICODE_strcpy(buffer+1+plen, name);
 	return ident;
 }
 
@@ -259,7 +259,7 @@
 	int merged;
 
 	if (!__doc__) {
-		__doc__ = PyString_InternFromString("__doc__");
+		__doc__ = PyUnicode_InternFromString("__doc__");
 		if (!__doc__)
 			return NULL;
 	}
@@ -551,7 +551,7 @@
 {
 	char tmpname[256];
 	PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++c->u->u_tmpname);
-	return PyString_FromString(tmpname);
+	return PyUnicode_FromString(tmpname);
 }
 
 /* Allocate a new block and return a pointer to it.
@@ -1143,7 +1143,7 @@
 	int addNone = 1;
 	static PyObject *module;
 	if (!module) {
-		module = PyString_FromString("<module>");
+		module = PyUnicode_FromString("<module>");
 		if (!module)
 			return NULL;
 	}
@@ -1362,7 +1362,7 @@
 		goto error;
 
 	if (!return_str) {
-		return_str = PyString_InternFromString("return");
+		return_str = PyUnicode_InternFromString("return");
 		if (!return_str)
 			goto error;
 	}
@@ -1488,12 +1488,12 @@
 
 	/* initialize statics */
 	if (build_class == NULL) {
-		build_class = PyString_FromString("__build_class__");
+		build_class = PyUnicode_FromString("__build_class__");
 		if (build_class == NULL)
 			return 0;
 	}
 	if (locals == NULL) {
-		locals = PyString_FromString("__locals__");
+		locals = PyUnicode_FromString("__locals__");
 		if (locals == NULL)
 			return 0;
 	}
@@ -1533,7 +1533,7 @@
 		/* ... and store it into f_locals */
 		ADDOP_IN_SCOPE(c, STORE_LOCALS);
 		/* load __name__ ... */
-		str = PyString_InternFromString("__name__");
+		str = PyUnicode_InternFromString("__name__");
 		if (!str || !compiler_nameop(c, str, Load)) {
 			Py_XDECREF(str);
 			compiler_exit_scope(c);
@@ -1541,7 +1541,7 @@
 		}
 		Py_DECREF(str);
 		/* ... and store it as __module__ */
-		str = PyString_InternFromString("__module__");
+		str = PyUnicode_InternFromString("__module__");
 		if (!str || !compiler_nameop(c, str, Store)) {
 			Py_XDECREF(str);
 			compiler_exit_scope(c);
@@ -1627,7 +1627,7 @@
 	assert(e->kind == Lambda_kind);
 
 	if (!name) {
-		name = PyString_InternFromString("<lambda>");
+		name = PyUnicode_InternFromString("<lambda>");
 		if (!name)
 			return 0;
 	}
@@ -2027,17 +2027,17 @@
 	   If there is a dot in name, we need to split it and emit a 
 	   LOAD_ATTR for each name.
 	*/
-	const char *src = PyString_AS_STRING(name);
-	const char *dot = strchr(src, '.');
+	const Py_UNICODE *src = PyUnicode_AS_UNICODE(name);
+	const Py_UNICODE *dot = Py_UNICODE_strchr(src, '.');
 	if (dot) {
 		/* Consume the base module name to get the first attribute */
 		src = dot + 1;
 		while (dot) {
 			/* NB src is only defined when dot != NULL */
 			PyObject *attr;
-			dot = strchr(src, '.');
-			attr = PyString_FromStringAndSize(src, 
-					    dot ? dot - src : strlen(src));
+			dot = Py_UNICODE_strchr(src, '.');
+			attr = PyUnicode_FromUnicode(src, 
+					    dot ? dot - src : Py_UNICODE_strlen(src));
 			if (!attr)
 				return -1;
 			ADDOP_O(c, LOAD_ATTR, attr, names);
@@ -2081,11 +2081,11 @@
 		}
 		else {
 			identifier tmp = alias->name;
-			const char *base = PyString_AS_STRING(alias->name);
-			char *dot = strchr(base, '.');
+			const Py_UNICODE *base = PyUnicode_AS_UNICODE(alias->name);
+			Py_UNICODE *dot = Py_UNICODE_strchr(base, '.');
 			if (dot)
-				tmp = PyString_FromStringAndSize(base, 
-								 dot - base);
+				tmp = PyUnicode_FromUnicode(base, 
+							    dot - base);
 			r = compiler_nameop(c, tmp, Store);
 			if (dot) {
 				Py_DECREF(tmp);
@@ -2122,8 +2122,8 @@
 	}
 
 	if (s->lineno > c->c_future->ff_lineno) {
-		if (!strcmp(PyString_AS_STRING(s->v.ImportFrom.module),
-			    "__future__")) {
+		if (!PyUnicode_CompareWithASCIIString(s->v.ImportFrom.module,
+						      "__future__")) {
 			Py_DECREF(level);
 			Py_DECREF(names);
 			return compiler_error(c, 
@@ -2142,7 +2142,7 @@
 		alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
 		identifier store_name;
 
-		if (i == 0 && *PyString_AS_STRING(alias->name) == '*') {
+		if (i == 0 && *PyUnicode_AS_UNICODE(alias->name) == '*') {
 			assert(n == 1);
 			ADDOP(c, IMPORT_STAR);
 			return 1;
@@ -2172,7 +2172,7 @@
 	if (Py_OptimizeFlag)
 		return 1;
 	if (assertion_error == NULL) {
-		assertion_error = PyString_FromString("AssertionError");
+		assertion_error = PyUnicode_FromString("AssertionError");
 		if (assertion_error == NULL)
 			return 0;
 	}
@@ -2417,7 +2417,7 @@
 
 	/* First check for assignment to __debug__. Param? */
 	if ((ctx == Store || ctx == AugStore || ctx == Del)
-	    && !strcmp(PyString_AS_STRING(name), "__debug__")) {
+	    && !PyUnicode_CompareWithASCIIString(name, "__debug__")) {
 		return compiler_error(c, "can not assign to __debug__");
 	}
 
@@ -2455,7 +2455,7 @@
 	}
 
 	/* XXX Leave assert here, but handle __doc__ and the like better */
-	assert(scope || PyString_AS_STRING(name)[0] == '_');
+	assert(scope || PyUnicode_AS_UNICODE(name)[0] == '_');
 
 	switch (optype) {
 	case OP_DEREF:
@@ -2889,7 +2889,7 @@
 {
 	static identifier name;
 	if (!name) {
-		name = PyString_FromString("<genexp>");
+		name = PyUnicode_FromString("<genexp>");
 		if (!name)
 			return 0;
 	}
@@ -2904,7 +2904,7 @@
 {
 	static identifier name;
 	if (!name) {
-		name = PyString_FromString("<listcomp>");
+		name = PyUnicode_FromString("<listcomp>");
 		if (!name)
 			return 0;
 	}
@@ -2919,7 +2919,7 @@
 {
 	static identifier name;
 	if (!name) {
-		name = PyString_FromString("<setcomp>");
+		name = PyUnicode_FromString("<setcomp>");
 		if (!name)
 			return 0;
 	}
@@ -2957,8 +2957,8 @@
 	case Name_kind:
 		/* __debug__ is not assignable, so we can optimize
 		 * it away in if and while statements */
-		if (strcmp(PyString_AS_STRING(e->v.Name.id),
-			   "__debug__") == 0)
+		if (PyUnicode_CompareWithASCIIString(e->v.Name.id,
+						     "__debug__") == 0)
 			   return ! Py_OptimizeFlag;
 		/* fall through */
 	default:
@@ -2999,12 +2999,12 @@
     assert(s->kind == With_kind);
 
     if (!enter_attr) {
-	enter_attr = PyString_InternFromString("__enter__");
+	enter_attr = PyUnicode_InternFromString("__enter__");
 	if (!enter_attr)
 	    return 0;
     }
     if (!exit_attr) {
-	exit_attr = PyString_InternFromString("__exit__");
+	exit_attr = PyUnicode_InternFromString("__exit__");
 	if (!exit_attr)
 	    return 0;
     }
diff --git a/Python/future.c b/Python/future.c
index d6f11a4..2092f58 100644
--- a/Python/future.c
+++ b/Python/future.c
@@ -55,7 +55,7 @@
 
 	static PyObject *future;
 	if (!future) {
-		future = PyString_InternFromString("__future__");
+		future = PyUnicode_InternFromString("__future__");
 		if (!future)
 			return 0;
 	}
diff --git a/Python/import.c b/Python/import.c
index 75f1e01..0e4e50c 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1920,7 +1920,7 @@
 		if (m == NULL)
 			goto err_return;
 		d = PyModule_GetDict(m);
-		s = PyString_InternFromString(name);
+		s = PyUnicode_InternFromString(name);
 		if (s == NULL)
 			goto err_return;
 		err = PyDict_SetItemString(d, "__path__", s);
@@ -1949,7 +1949,7 @@
 	PyObject *pname;
 	PyObject *result;
 
-	pname = PyString_FromString(name);
+	pname = PyUnicode_FromString(name);
 	if (pname == NULL)
 		return NULL;
 	result = PyImport_Import(pname);
@@ -2084,12 +2084,12 @@
 		return Py_None;
 
 	if (namestr == NULL) {
-		namestr = PyString_InternFromString("__name__");
+		namestr = PyUnicode_InternFromString("__name__");
 		if (namestr == NULL)
 			return NULL;
 	}
 	if (pathstr == NULL) {
-		pathstr = PyString_InternFromString("__path__");
+		pathstr = PyUnicode_InternFromString("__path__");
 		if (pathstr == NULL)
 			return NULL;
 	}
@@ -2097,9 +2097,18 @@
 	*buf = '\0';
 	*p_buflen = 0;
 	modname = PyDict_GetItem(globals, namestr);
-	if (modname == NULL || !PyString_Check(modname))
+	if (modname == NULL || (!PyString_Check(modname) && !PyUnicode_Check(modname)))
 		return Py_None;
 
+	if (PyUnicode_Check(modname)) {
+		/* XXX need to support Unicode better */
+		modname = _PyUnicode_AsDefaultEncodedString(modname, NULL);
+		if (!modname) {
+			PyErr_Clear();
+			return NULL;
+		}
+	}
+
 	modpath = PyDict_GetItem(globals, pathstr);
 	if (modpath != NULL) {
 		Py_ssize_t len = PyString_GET_SIZE(modname);
@@ -2254,13 +2263,23 @@
 			}
 			return 0;
 		}
-		if (!PyString_Check(item)) {
+		if (PyString_Check(item)) {
+			/* XXX there shouldn't be any str8 objects here */
+			PyObject *uni = PyUnicode_DecodeASCII(PyString_AsString(item),
+							      PyString_Size(item),
+							      "strict");
+			Py_DECREF(item);
+			if (!uni)
+				return 0;
+			item = uni;
+		}
+		if (!PyUnicode_Check(item)) {
 			PyErr_SetString(PyExc_TypeError,
-					"Item in ``from list'' not a string");
+					"Item in ``from list'' not a unicode string");
 			Py_DECREF(item);
 			return 0;
 		}
-		if (PyString_AS_STRING(item)[0] == '*') {
+		if (PyUnicode_AS_UNICODE(item)[0] == '*') {
 			PyObject *all;
 			Py_DECREF(item);
 			/* See if the package defines __all__ */
@@ -2279,9 +2298,23 @@
 		}
 		hasit = PyObject_HasAttr(mod, item);
 		if (!hasit) {
-			char *subname = PyString_AS_STRING(item);
+			PyObject *item8;
+			char *subname;
 			PyObject *submod;
 			char *p;
+			if (!Py_FileSystemDefaultEncoding) {
+				item8 = PyUnicode_EncodeASCII(PyUnicode_AsUnicode(item),
+							      PyUnicode_GetSize(item),
+							      "strict");
+			} else {
+				item8 = PyUnicode_AsEncodedObject(item, 
+				Py_FileSystemDefaultEncoding, "strict");
+			}
+			if (!item8) {
+				PyErr_SetString(PyExc_ValueError, "Cannot encode path item");
+				return 0;
+			}
+			subname = PyBytes_AsString(item8);
 			if (buflen + strlen(subname) >= MAXPATHLEN) {
 				PyErr_SetString(PyExc_ValueError,
 						"Module name too long");
@@ -2292,6 +2325,7 @@
 			*p++ = '.';
 			strcpy(p, subname);
 			submod = import_submodule(mod, subname, buf);
+			Py_DECREF(item8);
 			Py_XDECREF(submod);
 			if (submod == NULL) {
 				Py_DECREF(item);
@@ -2515,10 +2549,10 @@
 
 	/* Initialize constant string objects */
 	if (silly_list == NULL) {
-		import_str = PyString_InternFromString("__import__");
+		import_str = PyUnicode_InternFromString("__import__");
 		if (import_str == NULL)
 			return NULL;
-		builtins_str = PyString_InternFromString("__builtins__");
+		builtins_str = PyUnicode_InternFromString("__builtins__");
 		if (builtins_str == NULL)
 			return NULL;
 		silly_list = Py_BuildValue("[s]", "__doc__");
diff --git a/Python/modsupport.c b/Python/modsupport.c
index a272ce3..1ea08c3 100644
--- a/Python/modsupport.c
+++ b/Python/modsupport.c
@@ -65,7 +65,7 @@
 		return NULL;
 	d = PyModule_GetDict(m);
 	if (methods != NULL) {
-		n = PyString_FromString(name);
+		n = PyUnicode_FromString(name);
 		if (n == NULL)
 			return NULL;
 		for (ml = methods; ml->ml_name != NULL; ml++) {
@@ -689,5 +689,5 @@
 int 
 PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
 {
-	return PyModule_AddObject(m, name, PyString_FromString(value));
+	return PyModule_AddObject(m, name, PyUnicode_FromString(value));
 }
diff --git a/Python/pystate.c b/Python/pystate.c
index 086789d..1914ba8 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -167,6 +167,8 @@
 
 		tstate->frame = NULL;
 		tstate->recursion_depth = 0;
+		tstate->overflowed = 0;
+		tstate->recursion_critical = 0;
 		tstate->tracing = 0;
 		tstate->use_tracing = 0;
 		tstate->tick_counter = 0;
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index c2005f1..5daf7dd 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1133,6 +1133,8 @@
 	PyObject *f = PySys_GetObject("stderr");
 	Py_INCREF(value);
 	if (f == NULL)
+		_PyObject_Dump(value);
+	if (f == NULL)
 		fprintf(stderr, "lost sys.stderr\n");
 	else {
 		fflush(stdout);
diff --git a/Python/symtable.c b/Python/symtable.c
index f3a2c78..5df7318 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -92,7 +92,7 @@
 
 	PyOS_snprintf(buf, sizeof(buf),
 		      "<symtable entry %.100s(%ld), line %d>",
-		      PyString_AS_STRING(ste->ste_name),
+		      PyUnicode_AsString(ste->ste_name),
 		      PyInt_AS_LONG(ste->ste_id), ste->ste_lineno);
 	return PyUnicode_FromString(buf);
 }
@@ -190,7 +190,7 @@
     listcomp = NULL, setcomp = NULL;
 
 #define GET_IDENTIFIER(VAR) \
-	((VAR) ? (VAR) : ((VAR) = PyString_InternFromString(# VAR)))
+	((VAR) ? (VAR) : ((VAR) = PyUnicode_InternFromString(# VAR)))
 
 #define DUPLICATE_ARGUMENT \
 "duplicate argument '%s' in function definition"
@@ -390,13 +390,13 @@
 		if (flags & DEF_PARAM) {
 			PyErr_Format(PyExc_SyntaxError,
 				     "name '%s' is parameter and global",
-				     PyString_AS_STRING(name));
+				     PyUnicode_AsString(name));
 			return 0;
 		}
                 if (flags & DEF_NONLOCAL) {
 			PyErr_Format(PyExc_SyntaxError,
 				     "name '%s' is nonlocal and global",
-				     PyString_AS_STRING(name));
+				     PyUnicode_AsString(name));
 			return 0;
                 }
 		SET_SCOPE(scopes, name, GLOBAL_EXPLICIT);
@@ -410,7 +410,7 @@
 		if (flags & DEF_PARAM) {
 			PyErr_Format(PyExc_SyntaxError,
 				     "name '%s' is parameter and nonlocal",
-				     PyString_AS_STRING(name));
+				     PyUnicode_AsString(name));
 			return 0;
 		}
 		if (!bound) {
@@ -421,7 +421,7 @@
                 if (!PySet_Contains(bound, name)) {
                         PyErr_Format(PyExc_SyntaxError,
                                      "no binding for nonlocal '%s' found",
-				     PyString_AS_STRING(name));
+				     PyUnicode_AsString(name));
                                      
                         return 0;
                 }
@@ -524,7 +524,7 @@
 		PyOS_snprintf(buf, sizeof(buf), 
 			      "import * is not allowed in function '%.100s' "
 			      "because it is %s",
-			      PyString_AS_STRING(ste->ste_name), trailer);
+			      PyUnicode_AsString(ste->ste_name), trailer);
 		break;
 	}
 
@@ -984,7 +984,7 @@
 
 	PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]",
 		      ++st->st_cur->ste_tmpname);
-	tmp = PyString_InternFromString(tmpname);
+	tmp = PyUnicode_InternFromString(tmpname);
 	if (!tmp)
 		return 0;
 	if (!symtable_add_def(st, tmp, DEF_LOCAL))
@@ -1129,7 +1129,7 @@
 		asdl_seq *seq = s->v.Global.names;
 		for (i = 0; i < asdl_seq_LEN(seq); i++) {
 			identifier name = (identifier)asdl_seq_GET(seq, i);
-			char *c_name = PyString_AS_STRING(name);
+			char *c_name = PyUnicode_AsString(name);
 			long cur = symtable_lookup(st, name);
 			if (cur < 0)
 				return 0;
@@ -1156,7 +1156,7 @@
 		asdl_seq *seq = s->v.Nonlocal.names;
 		for (i = 0; i < asdl_seq_LEN(seq); i++) {
 			identifier name = (identifier)asdl_seq_GET(seq, i);
-			char *c_name = PyString_AS_STRING(name);
+			char *c_name = PyUnicode_AsString(name);
 			long cur = symtable_lookup(st, name);
 			if (cur < 0)
 				return 0;
@@ -1316,7 +1316,7 @@
 static int
 symtable_implicit_arg(struct symtable *st, int pos)
 {
-	PyObject *id = PyString_FromFormat(".%d", pos);
+	PyObject *id = PyUnicode_FromFormat(".%d", pos);
 	if (id == NULL)
 		return 0;
 	if (!symtable_add_def(st, id, DEF_PARAM)) {
@@ -1425,10 +1425,10 @@
 	*/
 	PyObject *store_name;
 	PyObject *name = (a->asname == NULL) ? a->name : a->asname;
-	const char *base = PyString_AS_STRING(name);
-	char *dot = strchr(base, '.');
+	const Py_UNICODE *base = PyUnicode_AS_UNICODE(name);
+	Py_UNICODE *dot = Py_UNICODE_strchr(base, '.');
 	if (dot) {
-		store_name = PyString_FromStringAndSize(base, dot - base);
+		store_name = PyUnicode_FromUnicode(base, dot - base);
 		if (!store_name)
 			return 0;
 	}
@@ -1436,7 +1436,7 @@
 		store_name = name;
 		Py_INCREF(store_name);
 	}
-	if (strcmp(PyString_AS_STRING(name), "*")) {
+	if (PyUnicode_CompareWithASCIIString(name, "*")) {
 		int r = symtable_add_def(st, store_name, DEF_IMPORT); 
 		Py_DECREF(store_name);
 		return r;
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 30e0180..1b7674b 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -280,7 +280,7 @@
 	int i;
 	for (i = 0; i < 7; ++i) {
 		if (whatstrings[i] == NULL) {
-			name = PyString_InternFromString(whatnames[i]);
+			name = PyUnicode_InternFromString(whatnames[i]);
 			if (name == NULL)
 				return -1;
 			whatstrings[i] = name;
@@ -801,7 +801,7 @@
 	if (list == NULL)
 		return NULL;
 	for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
-		PyObject *name = PyString_FromString(
+		PyObject *name = PyUnicode_FromString(
 			PyImport_Inittab[i].name);
 		if (name == NULL)
 			break;