Patch #445762: Support --disable-unicode
- Do not compile unicodeobject, unicodectype, and unicodedata if Unicode is disabled
- check for Py_USING_UNICODE in all places that use Unicode functions
- disables unicode literals, and the builtin functions
- add the types.StringTypes list
- remove Unicode literals from most tests.
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 12af47f..d0f934f 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -276,6 +276,7 @@
 Return a string of one character with ordinal i; 0 <= i < 256.";
 
 
+#ifdef Py_USING_UNICODE
 static PyObject *
 builtin_unichr(PyObject *self, PyObject *args)
 {
@@ -324,6 +325,7 @@
 "unichr(i) -> Unicode character\n\
 \n\
 Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.";
+#endif
 
 
 static PyObject *
@@ -630,11 +632,13 @@
 
 	if (!PyArg_ParseTuple(args, "OO|O:getattr", &v, &name, &dflt))
 		return NULL;
+#ifdef Py_USING_UNICODE
 	if (PyUnicode_Check(name)) {
 		name = _PyUnicode_AsDefaultEncodedString(name, NULL);
 		if (name == NULL)
 			return NULL;
 	}
+#endif
 
 	if (!PyString_Check(name)) {
 		PyErr_SetString(PyExc_TypeError,
@@ -682,11 +686,13 @@
 
 	if (!PyArg_ParseTuple(args, "OO:hasattr", &v, &name))
 		return NULL;
+#ifdef Py_USING_UNICODE
 	if (PyUnicode_Check(name)) {
 		name = _PyUnicode_AsDefaultEncodedString(name, NULL);
 		if (name == NULL)
 			return NULL;
 	}
+#endif
 
 	if (!PyString_Check(name)) {
 		PyErr_SetString(PyExc_TypeError,
@@ -1252,12 +1258,14 @@
 			ord = (long)((unsigned char)*PyString_AS_STRING(obj));
 			return PyInt_FromLong(ord);
 		}
+#ifdef Py_USING_UNICODE
 	} else if (PyUnicode_Check(obj)) {
 		size = PyUnicode_GET_SIZE(obj);
 		if (size == 1) {
 			ord = (long)*PyUnicode_AS_UNICODE(obj);
 			return PyInt_FromLong(ord);
 		}
+#endif
 	} else {
 		PyErr_Format(PyExc_TypeError,
 			     "ord() expected string of length 1, but " \
@@ -1843,7 +1851,9 @@
  	{"round",	builtin_round,      METH_VARARGS, round_doc},
  	{"setattr",	builtin_setattr,    METH_VARARGS, setattr_doc},
  	{"slice",       builtin_slice,      METH_VARARGS, slice_doc},
+#ifdef Py_USING_UNICODE
  	{"unichr",	builtin_unichr,     METH_VARARGS, unichr_doc},
+#endif
  	{"vars",	builtin_vars,       METH_VARARGS, vars_doc},
  	{"xrange",	builtin_xrange,     METH_VARARGS, xrange_doc},
   	{"zip",         builtin_zip,        METH_VARARGS, zip_doc},
@@ -1905,9 +1915,11 @@
 		return NULL;
 	if (PyDict_SetItemString(dict, "type", (PyObject *) &PyType_Type) < 0)
 		return NULL;
+#ifdef Py_USING_UNICODE
 	if (PyDict_SetItemString(dict, "unicode",
 				 (PyObject *) &PyUnicode_Type) < 0)
 		return NULL;
+#endif
 	debug = PyInt_FromLong(Py_OptimizeFlag == 0);
 	if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
 		Py_XDECREF(debug);
diff --git a/Python/compile.c b/Python/compile.c
index 21349ba..c6c3394 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -520,8 +520,8 @@
 static PyCodeObject *icompile(node *, struct compiling *);
 static PyCodeObject *jcompile(node *, char *, struct compiling *,
 			      PyCompilerFlags *);
-static PyObject *parsestrplus(node *);
-static PyObject *parsestr(char *);
+static PyObject *parsestrplus(struct compiling*, node *);
+static PyObject *parsestr(struct compiling *, char *);
 static node *get_rawdocstring(node *);
 
 static int get_ref_type(struct compiling *, char *);
@@ -1111,7 +1111,7 @@
 }
 
 static PyObject *
-parsestr(char *s)
+parsestr(struct compiling *com, char *s)
 {
 	PyObject *v;
 	size_t len;
@@ -1122,11 +1122,19 @@
 	int first = *s;
 	int quote = first;
 	int rawmode = 0;
+#ifdef Py_USING_UNICODE
 	int unicode = 0;
+#endif
 	if (isalpha(quote) || quote == '_') {
 		if (quote == 'u' || quote == 'U') {
+#ifdef Py_USING_UNICODE
 			quote = *++s;
 			unicode = 1;
+#else
+			com_error(com, PyExc_SyntaxError,
+				  "Unicode literals not supported in this Python");
+			return NULL;
+#endif
 		}
 		if (quote == 'r' || quote == 'R') {
 			quote = *++s;
@@ -1155,6 +1163,7 @@
 			return NULL;
 		}
 	}
+#ifdef Py_USING_UNICODE
 	if (unicode || Py_UnicodeFlag) {
 		if (rawmode)
 			return PyUnicode_DecodeRawUnicodeEscape(
@@ -1163,6 +1172,7 @@
 			return PyUnicode_DecodeUnicodeEscape(
 				s, len, NULL);
 	}
+#endif
 	if (rawmode || strchr(s, '\\') == NULL)
 		return PyString_FromStringAndSize(s, len);
 	v = PyString_FromStringAndSize((char *)NULL, len);
@@ -1238,16 +1248,16 @@
 }
 
 static PyObject *
-parsestrplus(node *n)
+parsestrplus(struct compiling* c, node *n)
 {
 	PyObject *v;
 	int i;
 	REQ(CHILD(n, 0), STRING);
-	if ((v = parsestr(STR(CHILD(n, 0)))) != NULL) {
+	if ((v = parsestr(c, STR(CHILD(n, 0)))) != NULL) {
 		/* String literal concatenation */
 		for (i = 1; i < NCH(n); i++) {
 		    PyObject *s;
-		    s = parsestr(STR(CHILD(n, i)));
+		    s = parsestr(c, STR(CHILD(n, i)));
 		    if (s == NULL)
 			goto onError;
 		    if (PyString_Check(v) && PyString_Check(s)) {
@@ -1255,6 +1265,7 @@
 			if (v == NULL)
 			    goto onError;
 		    }
+#ifdef Py_USING_UNICODE
 		    else {
 			PyObject *temp;
 			temp = PyUnicode_Concat(v, s);
@@ -1264,6 +1275,7 @@
 			Py_DECREF(v);
 			v = temp;
 		    }
+#endif
 		}
 	}
 	return v;
@@ -1445,7 +1457,7 @@
 		com_push(c, 1);
 		break;
 	case STRING:
-		v = parsestrplus(n);
+		v = parsestrplus(c, n);
 		if (v == NULL) {
 			c->c_errors++;
 			i = 255;
@@ -2936,7 +2948,7 @@
 		return i == 0;
 
 	case STRING:
-		v = parsestr(STR(n));
+		v = parsestr(c, STR(n));
 		if (v == NULL) {
 			PyErr_Clear();
 			break;
@@ -3330,7 +3342,7 @@
 }
 
 static PyObject *
-get_docstring(node *n)
+get_docstring(struct compiling *c, node *n)
 {
 	/* Don't generate doc-strings if run with -OO */
 	if (Py_OptimizeFlag > 1)
@@ -3338,7 +3350,7 @@
 	n = get_rawdocstring(n);
 	if (n == NULL)
 		return NULL;
-	return parsestrplus(n);
+	return parsestrplus(c, n);
 }
 
 static void
@@ -3794,7 +3806,7 @@
 	int i;
 	PyObject *doc;
 	REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
-	doc = get_docstring(n);
+	doc = get_docstring(c, n);
 	if (doc != NULL) {
 		int i = com_addconst(c, doc);
 		Py_DECREF(doc);
@@ -3819,7 +3831,7 @@
 	node *ch;
 	REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
 	c->c_name = STR(CHILD(n, 1));
-	doc = get_docstring(CHILD(n, 4));
+	doc = get_docstring(c, CHILD(n, 4));
 	if (doc != NULL) {
 		(void) com_addconst(c, doc);
 		Py_DECREF(doc);
@@ -3869,7 +3881,7 @@
 	c->c_name = STR(CHILD(n, 1));
 	c->c_private = c->c_name;
 	ch = CHILD(n, NCH(n)-1); /* The suite */
-	doc = get_docstring(ch);
+	doc = get_docstring(c, ch);
 	if (doc != NULL) {
 		int i = com_addconst(c, doc);
 		Py_DECREF(doc);
diff --git a/Python/getargs.c b/Python/getargs.c
index c9a5273..9f76ac0 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -566,6 +566,7 @@
 				*p = PyString_AS_STRING(arg);
 				*q = PyString_GET_SIZE(arg);
 			}
+#ifdef Py_USING_UNICODE
 			else if (PyUnicode_Check(arg)) {
 				arg = UNICODE_DEFAULT_ENCODING(arg);
 				if (arg == NULL)
@@ -574,6 +575,7 @@
 				*p = PyString_AS_STRING(arg);
 				*q = PyString_GET_SIZE(arg);
 			}
+#endif
 			else { /* any buffer-like object */
 				char *buf;
 				int count = convertbuffer(arg, p, &buf);
@@ -587,6 +589,7 @@
 			
 			if (PyString_Check(arg))
 				*p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
 			else if (PyUnicode_Check(arg)) {
 				arg = UNICODE_DEFAULT_ENCODING(arg);
 				if (arg == NULL)
@@ -594,6 +597,7 @@
 							  arg, msgbuf);
 				*p = PyString_AS_STRING(arg);
 			}
+#endif
 			else
 				return converterr("string", arg, msgbuf);
 			if ((int)strlen(*p) != PyString_Size(arg))
@@ -616,6 +620,7 @@
 				*p = PyString_AS_STRING(arg);
 				*q = PyString_GET_SIZE(arg);
 			}
+#ifdef Py_USING_UNICODE
 			else if (PyUnicode_Check(arg)) {
 				arg = UNICODE_DEFAULT_ENCODING(arg);
 				if (arg == NULL)
@@ -624,6 +629,7 @@
 				*p = PyString_AS_STRING(arg);
 				*q = PyString_GET_SIZE(arg);
 			}
+#endif
 			else { /* any buffer-like object */
 				char *buf;
 				int count = convertbuffer(arg, p, &buf);
@@ -640,6 +646,7 @@
 				*p = 0;
 			else if (PyString_Check(arg))
 				*p = PyString_AsString(arg);
+#ifdef Py_USING_UNICODE
 			else if (PyUnicode_Check(arg)) {
 				arg = UNICODE_DEFAULT_ENCODING(arg);
 				if (arg == NULL)
@@ -647,6 +654,7 @@
 							  arg, msgbuf);
 				*p = PyString_AS_STRING(arg);
 			}
+#endif
 			else
 				return converterr("string or None", 
 						  arg, msgbuf);
@@ -670,13 +678,15 @@
 	case 'e': {/* encoded string */
 		char **buffer;
 		const char *encoding;
-		PyObject *u, *s;
+		PyObject *s;
 		int size, recode_strings;
 
 		/* Get 'e' parameter: the encoding name */
 		encoding = (const char *)va_arg(*p_va, const char *);
+#ifdef Py_USING_UNICODE
 		if (encoding == NULL)
 			encoding = PyUnicode_GetDefaultEncoding();
+#endif
 			
 		/* Get output buffer parameter:
 		   's' (recode all objects via Unicode) or
@@ -702,6 +712,9 @@
 			Py_INCREF(s);
 		}
 		else {
+#ifdef Py_USING_UNICODE
+		    	PyObject *u;
+
 			/* Convert object to Unicode */
 			u = PyUnicode_FromObject(arg);
 			if (u == NULL)
@@ -723,6 +736,9 @@
 					"(encoder failed to return a string)",
 					arg, msgbuf);
 			}
+#else
+			return converterr("string<e>", arg, msgbuf);
+#endif
 		}
 		size = PyString_GET_SIZE(s);
 
@@ -808,6 +824,7 @@
 		break;
 	}
 
+#ifdef Py_USING_UNICODE
 	case 'u': {/* raw unicode buffer (Py_UNICODE *) */
 		if (*format == '#') { /* any buffer-like object */
 			void **p = (void **)va_arg(*p_va, char **);
@@ -829,6 +846,7 @@
 		}
 		break;
 	}
+#endif
 
 	case 'S': { /* string object */
 		PyObject **p = va_arg(*p_va, PyObject **);
@@ -839,6 +857,7 @@
 		break;
 	}
 	
+#ifdef Py_USING_UNICODE
 	case 'U': { /* Unicode object */
 		PyObject **p = va_arg(*p_va, PyObject **);
 		if (PyUnicode_Check(arg))
@@ -847,6 +866,7 @@
 			return converterr("unicode", arg, msgbuf);
 		break;
 	}
+#endif
 	
 	case 'O': { /* object */
 		PyTypeObject *type;
diff --git a/Python/marshal.c b/Python/marshal.c
index 008659d..5ef11ef 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -187,6 +187,7 @@
 		w_long((long)n, p);
 		w_string(PyString_AS_STRING(v), n, p);
 	}
+#ifdef Py_USING_UNICODE
 	else if (PyUnicode_Check(v)) {
 	        PyObject *utf8;
 		utf8 = PyUnicode_AsUTF8String(v);
@@ -201,6 +202,7 @@
 		w_string(PyString_AS_STRING(utf8), n, p);
 		Py_DECREF(utf8);
 	}
+#endif
 	else if (PyTuple_Check(v)) {
 		w_byte(TYPE_TUPLE, p);
 		n = PyTuple_Size(v);
@@ -472,6 +474,7 @@
 		}
 		return v;
 
+#ifdef Py_USING_UNICODE
 	case TYPE_UNICODE:
 	    {
 		char *buffer;
@@ -494,6 +497,7 @@
 		PyMem_DEL(buffer);
 		return v;
 	    }
+#endif
 
 	case TYPE_TUPLE:
 		n = r_long(p);
diff --git a/Python/modsupport.c b/Python/modsupport.c
index 8fad54a..0450a8a 100644
--- a/Python/modsupport.c
+++ b/Python/modsupport.c
@@ -199,6 +199,7 @@
 	return v;
 }
 
+#ifdef Py_USING_UNICODE
 static int
 _ustrlen(Py_UNICODE *u)
 {
@@ -207,6 +208,7 @@
 	while (*v != 0) { i++; v++; } 
 	return i;
 }
+#endif
 
 static PyObject *
 do_mktuple(char **p_format, va_list *p_va, int endchar, int n)
@@ -269,6 +271,7 @@
 		case 'L':
 			return PyLong_FromLongLong((LONG_LONG)va_arg(*p_va, LONG_LONG));
 #endif
+#ifdef Py_USING_UNICODE
 		case 'u':
 		{
 			PyObject *v;
@@ -291,6 +294,7 @@
 			}
 			return v;
 		}
+#endif
 		case 'f':
 		case 'd':
 			return PyFloat_FromDouble(
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 232ba55..621ce9d 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -125,8 +125,10 @@
 	/* Init codec registry */
 	_PyCodecRegistry_Init();
 
+#ifdef Py_USING_UNICODE
 	/* Init Unicode implementation; relies on the codec registry */
 	_PyUnicode_Init();
+#endif
 
 	bimod = _PyBuiltin_Init();
 	if (bimod == NULL)
@@ -206,8 +208,10 @@
 	/* Disable signal handling */
 	PyOS_FiniInterrupts();
 
+#ifdef Py_USING_UNICODE
 	/* Cleanup Unicode implementation */
 	_PyUnicode_Fini();
+#endif
 
 	/* Cleanup Codec registry */
 	_PyCodecRegistry_Fini();
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 2eae03d..82d2999 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -176,6 +176,8 @@
 Return the current default string encoding used by the Unicode \n\
 implementation.";
 
+#ifdef Py_USING_UNICODE
+
 static PyObject *
 sys_setdefaultencoding(PyObject *self, PyObject *args)
 {
@@ -193,6 +195,8 @@
 \n\
 Set the current default string encoding used by the Unicode implementation.";
 
+#endif
+
 /*
  * Cached interned string objects used for calling the profile and
  * trace functions.  Initialized by trace_init().
@@ -530,8 +534,10 @@
 	{"exc_info",	(PyCFunction)sys_exc_info, METH_NOARGS, exc_info_doc},
 	{"excepthook",	sys_excepthook, METH_VARARGS, excepthook_doc},
 	{"exit",	sys_exit, METH_OLDARGS, exit_doc},
+#ifdef Py_USING_UNICODE
 	{"getdefaultencoding", (PyCFunction)sys_getdefaultencoding, METH_NOARGS,
 	 getdefaultencoding_doc}, 
+#endif
 #ifdef HAVE_DLOPEN
 	{"getdlopenflags", (PyCFunction)sys_getdlopenflags, METH_NOARGS, 
 	 getdlopenflags_doc},
@@ -553,8 +559,10 @@
 #ifdef USE_MALLOPT
 	{"mdebug",	sys_mdebug, METH_VARARGS},
 #endif
+#ifdef Py_USING_UNICODE
 	{"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS,
 	 setdefaultencoding_doc}, 
+#endif
 	{"setcheckinterval",	sys_setcheckinterval, METH_VARARGS,
 	 setcheckinterval_doc}, 
 #ifdef HAVE_DLOPEN
@@ -782,9 +790,11 @@
 	PyDict_SetItemString(sysdict, "maxint",
 			     v = PyInt_FromLong(PyInt_GetMax()));
 	Py_XDECREF(v);
+#ifdef Py_USING_UNICODE
 	PyDict_SetItemString(sysdict, "maxunicode",
 			     v = PyInt_FromLong(PyUnicode_GetMax()));
 	Py_XDECREF(v);
+#endif
 	PyDict_SetItemString(sysdict, "builtin_module_names",
 		   v = list_builtin_module_names());
 	Py_XDECREF(v);