- A new type object, 'string', is added.  This is a common base type
  for 'str' and 'unicode', and can be used instead of
  types.StringTypes, e.g. to test whether something is "a string":
  isinstance(x, string) is True for Unicode and 8-bit strings.  This
  is an abstract base class and cannot be instantiated directly.
diff --git a/Include/stringobject.h b/Include/stringobject.h
index 9049455..2a56ef6 100644
--- a/Include/stringobject.h
+++ b/Include/stringobject.h
@@ -39,6 +39,7 @@
     char ob_sval[1];
 } PyStringObject;
 
+extern DL_IMPORT(PyTypeObject) PyBaseString_Type;
 extern DL_IMPORT(PyTypeObject) PyString_Type;
 
 #define PyString_Check(op) PyObject_TypeCheck(op, &PyString_Type)
diff --git a/Misc/NEWS b/Misc/NEWS
index ff3fdc6..f544af4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -6,6 +6,12 @@
 
 Core and builtins
 
+- A new type object, 'string', is added.  This is a common base type
+  for 'str' and 'unicode', and can be used instead of
+  types.StringTypes, e.g. to test whether something is "a string":
+  isinstance(x, string) is True for Unicode and 8-bit strings.  This
+  is an abstract base class and cannot be instantiated directly.
+
 - Deprecated features of xrange objects have been removed as
   promised.  The start, stop, and step attributes and the tolist()
   method no longer exist.  xrange repetition and slicing have been
diff --git a/Objects/object.c b/Objects/object.c
index 1bd8db9..b1bf2c3 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1779,6 +1779,9 @@
 	if (PyType_Ready(&PyBool_Type) < 0)
 		Py_FatalError("Can't initialize 'bool'");
 
+	if (PyType_Ready(&PyString_Type) < 0)
+		Py_FatalError("Can't initialize 'str'");
+
 	if (PyType_Ready(&PyList_Type) < 0)
 		Py_FatalError("Can't initialize 'list'");
 
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 668668c..27b3af4 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -2855,6 +2855,60 @@
 	return pnew;
 }
 
+static PyObject *
+basestring_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+	PyErr_SetString(PyExc_TypeError,
+			"The string type cannot be instantiated");
+	return NULL;
+}
+
+static char basestring_doc[] =
+"Type string cannot be instantiated; it is the base for str and unicode.";
+
+PyTypeObject PyBaseString_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"string",
+	0,
+	0,
+ 	0,			 		/* tp_dealloc */
+	0,			 		/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,		 			/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,		 			/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	0,					/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+	basestring_doc,				/* tp_doc */
+	0,					/* tp_traverse */
+	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	0,					/* tp_members */
+	0,					/* tp_getset */
+	&PyBaseObject_Type,			/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,					/* tp_init */
+	0,					/* tp_alloc */
+	basestring_new,				/* tp_new */
+	0,		                	/* tp_free */
+};
+
 static char string_doc[] =
 "str(object) -> string\n\
 \n\
@@ -2893,7 +2947,7 @@
 	string_methods,				/* tp_methods */
 	0,					/* tp_members */
 	0,					/* tp_getset */
-	0,					/* tp_base */
+	&PyBaseString_Type,			/* tp_base */
 	0,					/* tp_dict */
 	0,					/* tp_descr_get */
 	0,					/* tp_descr_set */
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 5cc8455..0ac4941 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -5835,7 +5835,7 @@
     unicode_methods,			/* tp_methods */
     0,					/* tp_members */
     0,					/* tp_getset */
-    0,					/* tp_base */
+    &PyBaseString_Type,			/* tp_base */
     0,					/* tp_dict */
     0,					/* tp_descr_get */
     0,					/* tp_descr_set */
@@ -5859,6 +5859,8 @@
     strcpy(unicode_default_encoding, "ascii");
     for (i = 0; i < 256; i++)
 	unicode_latin1[i] = NULL;
+    if (PyType_Ready(&PyUnicode_Type) < 0)
+	Py_FatalError("Can't initialize 'unicode'");
 }
 
 /* Finalize the Unicode implementation */
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index d0411e2..311176e 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1905,6 +1905,7 @@
 	SETBUILTIN("object",		&PyBaseObject_Type);
 	SETBUILTIN("staticmethod",	&PyStaticMethod_Type);
 	SETBUILTIN("str",		&PyString_Type);
+	SETBUILTIN("string",		&PyBaseString_Type);
 	SETBUILTIN("super",		&PySuper_Type);
 	SETBUILTIN("tuple",		&PyTuple_Type);
 	SETBUILTIN("type",		&PyType_Type);