Fixed bugs in resizetuple and extended the interface.
Added ifdefs in stringobject.c for shared strings of length 1.
Renamed free_list in tupleobject.c to free_tuples.
diff --git a/Include/tupleobject.h b/Include/tupleobject.h
index 8fe28a2..9897f6d 100644
--- a/Include/tupleobject.h
+++ b/Include/tupleobject.h
@@ -58,7 +58,7 @@
 extern object *gettupleitem PROTO((object *, int));
 extern int settupleitem PROTO((object *, int, object *));
 extern object *gettupleslice PROTO((object *, int, int));
-extern int resizetuple PROTO((object **, int));
+extern int resizetuple PROTO((object **, int, int));
 
 /* Macro, trading safety for speed */
 #define GETTUPLEITEM(op, i) ((op)->ob_item[i])
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 61863b6..0d03a3b 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -39,7 +39,9 @@
 #endif
 
 static stringobject *characters[UCHAR_MAX + 1];
+#ifndef DONT_SHARE_SHORT_STRINGS
 static stringobject *nullstring;
+#endif
 
 /*
    Newsizedstringobject() and newstringobject() try in certain cases
@@ -62,6 +64,7 @@
 	int size;
 {
 	register stringobject *op;
+#ifndef DONT_SHARE_SHORT_STRINGS
 	if (size == 0 && (op = nullstring) != NULL) {
 #ifdef COUNT_ALLOCS
 		null_strings++;
@@ -76,6 +79,7 @@
 		INCREF(op);
 		return (object *)op;
 	}
+#endif /* DONT_SHARE_SHORT_STRINGS */
 	op = (stringobject *)
 		malloc(sizeof(stringobject) + size * sizeof(char));
 	if (op == NULL)
@@ -89,6 +93,7 @@
 	if (str != NULL)
 		memcpy(op->ob_sval, str, size);
 	op->ob_sval[size] = '\0';
+#ifndef DONT_SHARE_SHORT_STRINGS
 	if (size == 0) {
 		nullstring = op;
 		INCREF(op);
@@ -96,6 +101,7 @@
 		characters[*str & UCHAR_MAX] = op;
 		INCREF(op);
 	}
+#endif
 	return (object *) op;
 }
 
@@ -105,6 +111,7 @@
 {
 	register unsigned int size = strlen(str);
 	register stringobject *op;
+#ifndef DONT_SHARE_SHORT_STRINGS
 	if (size == 0 && (op = nullstring) != NULL) {
 #ifdef COUNT_ALLOCS
 		null_strings++;
@@ -119,6 +126,7 @@
 		INCREF(op);
 		return (object *)op;
 	}
+#endif /* DONT_SHARE_SHORT_STRINGS */
 	op = (stringobject *)
 		malloc(sizeof(stringobject) + size * sizeof(char));
 	if (op == NULL)
@@ -130,6 +138,7 @@
 #endif
 	NEWREF(op);
 	strcpy(op->ob_sval, str);
+#ifndef DONT_SHARE_SHORT_STRINGS
 	if (size == 0) {
 		nullstring = op;
 		INCREF(op);
@@ -137,6 +146,7 @@
 		characters[*str & UCHAR_MAX] = op;
 		INCREF(op);
 	}
+#endif
 	return (object *) op;
 }
 
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 0047a09..68fed9e 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -34,7 +34,7 @@
 /* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
    tuple () of which at most one instance will be allocated.
 */
-static tupleobject *free_list[MAXSAVESIZE];
+static tupleobject *free_tuples[MAXSAVESIZE];
 #endif
 #ifdef COUNT_ALLOCS
 int fast_tuple_allocs;
@@ -52,16 +52,16 @@
 		return NULL;
 	}
 #if MAXSAVESIZE > 0
-	if (size == 0 && free_list[0]) {
-		op = free_list[0];
+	if (size == 0 && free_tuples[0]) {
+		op = free_tuples[0];
 		INCREF(op);
 #ifdef COUNT_ALLOCS
 		tuple_zero_allocs++;
 #endif
 		return (object *) op;
 	}
-	if (0 < size && size < MAXSAVESIZE && (op = free_list[size]) != NULL) {
-		free_list[size] = (tupleobject *) op->ob_item[0];
+	if (0 < size && size < MAXSAVESIZE && (op = free_tuples[size]) != NULL) {
+		free_tuples[size] = (tupleobject *) op->ob_item[0];
 #ifdef COUNT_ALLOCS
 		fast_tuple_allocs++;
 #endif
@@ -80,7 +80,7 @@
 	NEWREF(op);
 #if MAXSAVESIZE > 0
 	if (size == 0) {
-		free_list[0] = op;
+		free_tuples[0] = op;
 		INCREF(op);	/* extra INCREF so that this is never freed */
 	}
 #endif
@@ -149,8 +149,8 @@
 		XDECREF(op->ob_item[i]);
 #if MAXSAVESIZE > 0
 	if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
-		op->ob_item[0] = (object *) free_list[op->ob_size];
-		free_list[op->ob_size] = op;
+		op->ob_item[0] = (object *) free_tuples[op->ob_size];
+		free_tuples[op->ob_size] = op;
 	} else
 #endif
 		free((ANY *)op);
@@ -397,36 +397,67 @@
    is only one module referencing the object.  You can also think of it
    as creating a new tuple object and destroying the old one, only
    more efficiently.  In any case, don't use this if the tuple may
-   already be known to some other part of the code... */
+   already be known to some other part of the code...
+   If last_is_sticky is set, the tuple will grow or shrink at the
+   front, otherwise it will grow or shrink at the end. */
 
 int
-resizetuple(pv, newsize)
+resizetuple(pv, newsize, last_is_sticky)
 	object **pv;
 	int newsize;
+	int last_is_sticky;
 {
-	register object *v;
+	register tupleobject *v;
 	register tupleobject *sv;
-	v = *pv;
+	int i;
+	int sizediff;
+
+	v = (tupleobject *) *pv;
+	sizediff = newsize - v->ob_size;
 	if (!is_tupleobject(v) || v->ob_refcnt != 1) {
 		*pv = 0;
 		DECREF(v);
 		err_badcall();
 		return -1;
 	}
+	if (sizediff == 0)
+		return 0;
 	/* XXX UNREF/NEWREF interface should be more symmetrical */
 #ifdef REF_DEBUG
 	--ref_total;
 #endif
 	UNREF(v);
-	*pv = (object *)
+	if (last_is_sticky && sizediff < 0) {
+		/* shrinking: move entries to the front and zero moved entries */
+		for (i = 0; i < newsize; i++) {
+			XDECREF(v->ob_item[i]);
+			v->ob_item[i] = v->ob_item[i - sizediff];
+			v->ob_item[i - sizediff] = NULL;
+		}
+	}
+	for (i = newsize; i < v->ob_size; i++) {
+		XDECREF(v->ob_item[i]);
+		v->ob_item[i] = NULL;
+	}
+	sv = (tupleobject *)
 		realloc((char *)v,
 			sizeof(tupleobject) + newsize * sizeof(object *));
-	if (*pv == NULL) {
+	*pv = (object *) sv;
+	if (sv == NULL) {
 		DEL(v);
 		err_nomem();
 		return -1;
 	}
-	NEWREF(*pv);
-	((tupleobject *) *pv)->ob_size = newsize;
+	NEWREF(sv);
+	for (i = sv->ob_size; i < newsize; i++)
+		sv->ob_item[i] = NULL;
+	if (last_is_sticky && sizediff > 0) {
+		/* growing: move entries to the end and zero moved entries */
+		for (i = newsize - 1; i >= sizediff; i--) {
+			sv->ob_item[i] = sv->ob_item[i - sizediff];
+			sv->ob_item[i - sizediff] = NULL;
+		}
+	}
+	sv->ob_size = newsize;
 	return 0;
 }
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index f4d7f47..6069ae0 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1319,7 +1319,7 @@
 		}
 	}
 
-	if (resizetuple(&result, j) < 0)
+	if (resizetuple(&result, j, 0) < 0)
 		return NULL;
 
 	if (shared)