[Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.198.2.6,2.198.2.7 ceval.c,2.241.2.4,2.241.2.5 compile.c,2.197,2.197.2.1 dynload_win.c,2.7,2.7.8.1 errors.c,2.62,2.62.6.1 getargs.c,2.54.6.1,2.54.6.2 graminit.c,2.28,2.28.8.1 import.c,2.176.2.1,2.176.2.2 marshal.c,1.62,1.62.4.1 pystate.c,2.16,2.16.6.1 pythonrun.c,2.133.4.3,2.133.4.4 symtable.c,2.4,2.4.6.1 sysmodule.c,2.85,2.85.4.1

Tim Peters tim_one@users.sourceforge.net
Sat, 07 Jul 2001 15:55:33 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv24450/mergedescr/dist/src/Python

Modified Files:
      Tag: descr-branch
	bltinmodule.c ceval.c compile.c dynload_win.c errors.c 
	getargs.c graminit.c import.c marshal.c pystate.c pythonrun.c 
	symtable.c sysmodule.c 
Log Message:
Merge of trunk tag date2001-07-06 into descr-branch.


Index: bltinmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.198.2.6
retrieving revision 2.198.2.7
diff -C2 -r2.198.2.6 -r2.198.2.7
*** bltinmodule.c	2001/07/04 00:13:58	2.198.2.6
--- bltinmodule.c	2001/07/07 22:55:30	2.198.2.7
***************
*** 14,17 ****
--- 14,26 ----
  #endif
  
+ /* The default encoding used by the platform file system APIs
+    Can remain NULL for all platforms that don't have such a concept
+ */
+ #if defined(MS_WIN32) && defined(HAVE_USABLE_WCHAR_T)
+ const char *Py_FileSystemDefaultEncoding = "mbcs";
+ #else
+ const char *Py_FileSystemDefaultEncoding = NULL; /* use default */
+ #endif
+ 
  /* Forward */
  static PyObject *filterstring(PyObject *, PyObject *);
***************
*** 143,193 ****
  builtin_filter(PyObject *self, PyObject *args)
  {
! 	PyObject *func, *seq, *result;
! 	PySequenceMethods *sqf;
! 	int len;
! 	register int i, j;
  
  	if (!PyArg_ParseTuple(args, "OO:filter", &func, &seq))
  		return NULL;
- 
- 	if (PyString_Check(seq)) {
- 		PyObject *r = filterstring(func, seq);
- 		return r;
- 	}
- 
- 	if (PyTuple_Check(seq)) {
- 		PyObject *r = filtertuple(func, seq);
- 		return r;
- 	}
  
! 	sqf = seq->ob_type->tp_as_sequence;
! 	if (sqf == NULL || sqf->sq_length == NULL || sqf->sq_item == NULL) {
! 		PyErr_SetString(PyExc_TypeError,
! 			   "filter() arg 2 must be a sequence");
! 		goto Fail_2;
  	}
  
! 	if ((len = (*sqf->sq_length)(seq)) < 0)
! 		goto Fail_2;
! 
  	if (PyList_Check(seq) && seq->ob_refcnt == 1) {
  		Py_INCREF(seq);
  		result = seq;
  	}
  	else {
! 		if ((result = PyList_New(len)) == NULL)
! 			goto Fail_2;
  	}
  
! 	for (i = j = 0; ; ++i) {
  		PyObject *item, *good;
  		int ok;
  
! 		if ((item = (*sqf->sq_item)(seq, i)) == NULL) {
! 			if (PyErr_ExceptionMatches(PyExc_IndexError)) {
! 				PyErr_Clear();
! 				break;
! 			}
! 			goto Fail_1;
  		}
  
--- 152,207 ----
  builtin_filter(PyObject *self, PyObject *args)
  {
! 	PyObject *func, *seq, *result, *it;
! 	int len;   /* guess for result list size */
! 	register int j;
  
  	if (!PyArg_ParseTuple(args, "OO:filter", &func, &seq))
  		return NULL;
  
! 	/* Strings and tuples return a result of the same type. */
! 	if (PyString_Check(seq))
! 		return filterstring(func, seq);
! 	if (PyTuple_Check(seq))
! 		return filtertuple(func, seq);
! 
! 	/* Get iterator. */
! 	it = PyObject_GetIter(seq);
! 	if (it == NULL)
! 		return NULL;
! 
! 	/* Guess a result list size. */
! 	len = -1;   /* unknown */
! 	if (PySequence_Check(seq) &&
! 	    seq->ob_type->tp_as_sequence->sq_length) {
! 		len = PySequence_Size(seq);
! 		if (len < 0)
! 			PyErr_Clear();
  	}
+ 	if (len < 0)
+ 		len = 8;  /* arbitrary */
  
! 	/* Get a result list. */
  	if (PyList_Check(seq) && seq->ob_refcnt == 1) {
+ 		/* Eww - can modify the list in-place. */
  		Py_INCREF(seq);
  		result = seq;
  	}
  	else {
! 		result = PyList_New(len);
! 		if (result == NULL)
! 			goto Fail_it;
  	}
  
! 	/* Build the result list. */
! 	j = 0;
! 	for (;;) {
  		PyObject *item, *good;
  		int ok;
  
! 		item = PyIter_Next(it);
! 		if (item == NULL) {
! 			if (PyErr_Occurred())
! 				goto Fail_result_it;
! 			break;
  		}
  
***************
*** 198,208 ****
  		else {
  			PyObject *arg = Py_BuildValue("(O)", item);
! 			if (arg == NULL)
! 				goto Fail_1;
  			good = PyEval_CallObject(func, arg);
  			Py_DECREF(arg);
  			if (good == NULL) {
  				Py_DECREF(item);
! 				goto Fail_1;
  			}
  		}
--- 212,224 ----
  		else {
  			PyObject *arg = Py_BuildValue("(O)", item);
! 			if (arg == NULL) {
! 				Py_DECREF(item);
! 				goto Fail_result_it;
! 			}
  			good = PyEval_CallObject(func, arg);
  			Py_DECREF(arg);
  			if (good == NULL) {
  				Py_DECREF(item);
! 				goto Fail_result_it;
  			}
  		}
***************
*** 210,238 ****
  		Py_DECREF(good);
  		if (ok) {
! 			if (j < len) {
! 				if (PyList_SetItem(result, j++, item) < 0)
! 					goto Fail_1;
! 			}
  			else {
  				int status = PyList_Append(result, item);
- 				j++;
  				Py_DECREF(item);
  				if (status < 0)
! 					goto Fail_1;
  			}
! 		} else {
! 			Py_DECREF(item);
  		}
  	}
  
  
  	if (j < len && PyList_SetSlice(result, j, len, NULL) < 0)
! 		goto Fail_1;
  
  	return result;
  
! Fail_1:
  	Py_DECREF(result);
! Fail_2:
  	return NULL;
  }
--- 226,255 ----
  		Py_DECREF(good);
  		if (ok) {
! 			if (j < len)
! 				PyList_SET_ITEM(result, j, item);
  			else {
  				int status = PyList_Append(result, item);
  				Py_DECREF(item);
  				if (status < 0)
! 					goto Fail_result_it;
  			}
! 			++j;
  		}
+ 		else
+ 			Py_DECREF(item);
  	}
  
  
+ 	/* Cut back result list if len is too big. */
  	if (j < len && PyList_SetSlice(result, j, len, NULL) < 0)
! 		goto Fail_result_it;
  
+ 	Py_DECREF(it);
  	return result;
  
! Fail_result_it:
  	Py_DECREF(result);
! Fail_it:
! 	Py_DECREF(it);
  	return NULL;
  }
***************
*** 272,286 ****
  {
  	long x;
! 	Py_UNICODE s[1];
  
  	if (!PyArg_ParseTuple(args, "l:unichr", &x))
  		return NULL;
! 	if (x < 0 || x >= 65536) {
  		PyErr_SetString(PyExc_ValueError,
! 				"unichr() arg not in range(65536)");
  		return NULL;
  	}
- 	s[0] = (Py_UNICODE)x;
- 	return PyUnicode_FromUnicode(s, 1);
  }
  
--- 289,320 ----
  {
  	long x;
! 	Py_UNICODE s[2];
  
  	if (!PyArg_ParseTuple(args, "l:unichr", &x))
  		return NULL;
! 
! 	if (x < 0 || x > 0x10ffff) {
  		PyErr_SetString(PyExc_ValueError,
! 				"unichr() arg not in range(0x110000)");
  		return NULL;
+ 	}
+ 
+ 	if (x <= 0xffff) {
+ 		/* UCS-2 character */
+ 		s[0] = (Py_UNICODE) x;
+ 		return PyUnicode_FromUnicode(s, 1);
+ 	}
+ 	else {
+ #ifndef Py_UNICODE_WIDE
+ 		/* UCS-4 character.  store as two surrogate characters */
+ 		x -= 0x10000L;
+ 		s[0] = 0xD800 + (Py_UNICODE) (x >> 10);
+ 		s[1] = 0xDC00 + (Py_UNICODE) (x & 0x03FF);
+ 		return PyUnicode_FromUnicode(s, 2);
+ #else
+ 		s[0] = (Py_UNICODE)x;
+ 		return PyUnicode_FromUnicode(s, 1);
+ #endif
  	}
  }
  
***************
*** 288,292 ****
  "unichr(i) -> Unicode character\n\
  \n\
! Return a Unicode string of one character with ordinal i; 0 <= i < 65536.";
  
  
--- 322,326 ----
  "unichr(i) -> Unicode character\n\
  \n\
! Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff.";
  
  
***************
*** 546,553 ****
  		PyCompilerFlags cf;
  		cf.cf_nested_scopes = 1;
! 		res = PyRun_FileExFlags(fp, filename, Py_file_input, globals, 
  				   locals, 1, &cf);
! 	} else 
! 		res = PyRun_FileEx(fp, filename, Py_file_input, globals, 
  				   locals, 1);
  	return res;
--- 580,587 ----
  		PyCompilerFlags cf;
  		cf.cf_nested_scopes = 1;
! 		res = PyRun_FileExFlags(fp, filename, Py_file_input, globals,
  				   locals, 1, &cf);
! 	} else
! 		res = PyRun_FileEx(fp, filename, Py_file_input, globals,
  				   locals, 1);
  	return res;
***************
*** 652,658 ****
  {
  	typedef struct {
! 		PyObject *seq;
! 		PySequenceMethods *sqf;
! 		int len;
  	} sequence;
  
--- 686,691 ----
  {
  	typedef struct {
! 		PyObject *it;	/* the iterator object */
! 		int saw_StopIteration;  /* bool:  did the iterator end? */
  	} sequence;
  
***************
*** 677,762 ****
  	}
  
  	if ((seqs = PyMem_NEW(sequence, n)) == NULL) {
  		PyErr_NoMemory();
! 		goto Fail_2;
  	}
  
! 	for (len = 0, i = 0, sqp = seqs; i < n; ++i, ++sqp) {
  		int curlen;
- 		PySequenceMethods *sqf;
- 
- 		if ((sqp->seq = PyTuple_GetItem(args, i + 1)) == NULL)
- 			goto Fail_2;
  
! 		sqp->sqf = sqf = sqp->seq->ob_type->tp_as_sequence;
! 		if (sqf == NULL ||
! 		    sqf->sq_length == NULL ||
! 		    sqf->sq_item == NULL)
! 		{
  			static char errmsg[] =
! 			    "argument %d to map() must be a sequence object";
  			char errbuf[sizeof(errmsg) + 25];
- 
  			sprintf(errbuf, errmsg, i+2);
  			PyErr_SetString(PyExc_TypeError, errbuf);
  			goto Fail_2;
  		}
- 
- 		if ((curlen = sqp->len = (*sqp->sqf->sq_length)(sqp->seq)) < 0)
- 			goto Fail_2;
  
! 		if (curlen > len)
! 			len = curlen;
  	}
  
  	if ((result = (PyObject *) PyList_New(len)) == NULL)
  		goto Fail_2;
  
  	for (i = 0; ; ++i) {
  		PyObject *alist, *item=NULL, *value;
! 		int any = 0;
  
  		if (func == Py_None && n == 1)
  			alist = NULL;
! 		else {
! 			if ((alist = PyTuple_New(n)) == NULL)
! 				goto Fail_1;
! 		}
  
  		for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
! 			if (sqp->len < 0) {
  				Py_INCREF(Py_None);
  				item = Py_None;
  			}
  			else {
! 				item = (*sqp->sqf->sq_item)(sqp->seq, i);
! 				if (item == NULL) {
! 					if (PyErr_ExceptionMatches(
! 						PyExc_IndexError))
! 					{
! 						PyErr_Clear();
! 						Py_INCREF(Py_None);
! 						item = Py_None;
! 						sqp->len = -1;
! 					}
! 					else {
! 						goto Fail_0;
  					}
  				}
- 				else
- 					any = 1;
- 
  			}
! 			if (!alist)
  				break;
- 			if (PyTuple_SetItem(alist, j, item) < 0) {
- 				Py_DECREF(item);
- 				goto Fail_0;
- 			}
- 			continue;
- 
- 		Fail_0:
- 			Py_XDECREF(alist);
- 			goto Fail_1;
  		}
  
--- 710,796 ----
  	}
  
+ 	/* Get space for sequence descriptors.  Must NULL out the iterator
+ 	 * pointers so that jumping to Fail_2 later doesn't see trash.
+ 	 */
  	if ((seqs = PyMem_NEW(sequence, n)) == NULL) {
  		PyErr_NoMemory();
! 		return NULL;
  	}
+ 	for (i = 0; i < n; ++i) {
+ 		seqs[i].it = (PyObject*)NULL;
+ 		seqs[i].saw_StopIteration = 0;
+ 	}
  
! 	/* Do a first pass to obtain iterators for the arguments, and set len
! 	 * to the largest of their lengths.
! 	 */
! 	len = 0;
! 	for (i = 0, sqp = seqs; i < n; ++i, ++sqp) {
! 		PyObject *curseq;
  		int curlen;
  
! 		/* Get iterator. */
! 		curseq = PyTuple_GetItem(args, i+1);
! 		sqp->it = PyObject_GetIter(curseq);
! 		if (sqp->it == NULL) {
  			static char errmsg[] =
! 			    "argument %d to map() must support iteration";
  			char errbuf[sizeof(errmsg) + 25];
  			sprintf(errbuf, errmsg, i+2);
  			PyErr_SetString(PyExc_TypeError, errbuf);
  			goto Fail_2;
  		}
  
! 		/* Update len. */
! 		curlen = -1;  /* unknown */
! 		if (PySequence_Check(curseq) &&
! 		    curseq->ob_type->tp_as_sequence->sq_length) {
! 			curlen = PySequence_Size(curseq);
! 			if (curlen < 0)
! 				PyErr_Clear();
! 		}
! 		if (curlen < 0)
! 			curlen = 8;  /* arbitrary */
! 			if (curlen > len)
! 				len = curlen;
  	}
  
+ 	/* Get space for the result list. */
  	if ((result = (PyObject *) PyList_New(len)) == NULL)
  		goto Fail_2;
  
+ 	/* Iterate over the sequences until all have stopped. */
  	for (i = 0; ; ++i) {
  		PyObject *alist, *item=NULL, *value;
! 		int numactive = 0;
  
  		if (func == Py_None && n == 1)
  			alist = NULL;
! 		else if ((alist = PyTuple_New(n)) == NULL)
! 			goto Fail_1;
  
  		for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
! 			if (sqp->saw_StopIteration) {
  				Py_INCREF(Py_None);
  				item = Py_None;
  			}
  			else {
! 				item = PyIter_Next(sqp->it);
! 				if (item)
! 					++numactive;
! 				else {
! 					if (PyErr_Occurred()) {
! 						Py_XDECREF(alist);
! 						goto Fail_1;
  					}
+ 					Py_INCREF(Py_None);
+ 					item = Py_None;
+ 					sqp->saw_StopIteration = 1;
  				}
  			}
! 			if (alist)
! 				PyTuple_SET_ITEM(alist, j, item);
! 			else
  				break;
  		}
  
***************
*** 764,768 ****
  			alist = item;
  
! 		if (!any) {
  			Py_DECREF(alist);
  			break;
--- 798,802 ----
  			alist = item;
  
! 		if (numactive == 0) {
  			Py_DECREF(alist);
  			break;
***************
*** 782,790 ****
  			if (status < 0)
  				goto Fail_1;
- 		}
- 		else {
- 			if (PyList_SetItem(result, i, value) < 0)
- 				goto Fail_1;
  		}
  	}
  
--- 816,822 ----
  			if (status < 0)
  				goto Fail_1;
  		}
+ 		else if (PyList_SetItem(result, i, value) < 0)
+ 		 	goto Fail_1;
  	}
  
***************
*** 792,803 ****
  		goto Fail_1;
  
! 	PyMem_DEL(seqs);
! 	return result;
  
  Fail_1:
  	Py_DECREF(result);
  Fail_2:
! 	if (seqs) PyMem_DEL(seqs);
! 	return NULL;
  }
  
--- 824,839 ----
  		goto Fail_1;
  
! 	goto Succeed;
  
  Fail_1:
  	Py_DECREF(result);
  Fail_2:
! 	result = NULL;
! Succeed:
! 	assert(seqs);
! 	for (i = 0; i < n; ++i)
! 		Py_XDECREF(seqs[i].it);
! 	PyMem_DEL(seqs);
! 	return result;
  }
  
***************
*** 1048,1054 ****
  min_max(PyObject *args, int op)
  {
! 	int i;
! 	PyObject *v, *w, *x;
! 	PySequenceMethods *sq;
  
  	if (PyTuple_Size(args) > 1)
--- 1084,1088 ----
  min_max(PyObject *args, int op)
  {
! 	PyObject *v, *w, *x, *it;
  
  	if (PyTuple_Size(args) > 1)
***************
*** 1056,1076 ****
  	else if (!PyArg_ParseTuple(args, "O:min/max", &v))
  		return NULL;
! 	sq = v->ob_type->tp_as_sequence;
! 	if (sq == NULL || sq->sq_item == NULL) {
! 		PyErr_SetString(PyExc_TypeError,
! 				"min() or max() arg must be a sequence");
  		return NULL;
! 	}
! 	w = NULL;
! 	for (i = 0; ; i++) {
! 		x = (*sq->sq_item)(v, i); /* Implies INCREF */
  		if (x == NULL) {
! 			if (PyErr_ExceptionMatches(PyExc_IndexError)) {
! 				PyErr_Clear();
! 				break;
  			}
! 			Py_XDECREF(w);
! 			return NULL;
  		}
  		if (w == NULL)
  			w = x;
--- 1090,1110 ----
  	else if (!PyArg_ParseTuple(args, "O:min/max", &v))
  		return NULL;
! 	
! 	it = PyObject_GetIter(v);
! 	if (it == NULL)
  		return NULL;
! 
! 	w = NULL;  /* the result */
! 	for (;;) {
! 		x = PyIter_Next(it);
  		if (x == NULL) {
! 			if (PyErr_Occurred()) {
! 				Py_XDECREF(w);
! 				Py_DECREF(it);
! 				return NULL;
  			}
! 			break;
  		}
+ 
  		if (w == NULL)
  			w = x;
***************
*** 1083,1087 ****
  			else if (cmp < 0) {
  				Py_DECREF(x);
! 				Py_XDECREF(w);
  				return NULL;
  			}
--- 1117,1122 ----
  			else if (cmp < 0) {
  				Py_DECREF(x);
! 				Py_DECREF(w);
! 				Py_DECREF(it);
  				return NULL;
  			}
***************
*** 1093,1096 ****
--- 1128,1132 ----
  		PyErr_SetString(PyExc_ValueError,
  				"min() or max() arg is an empty sequence");
+ 	Py_DECREF(it);
  	return w;
  }
***************
*** 1150,1161 ****
  builtin_open(PyObject *self, PyObject *args)
  {
! 	char *name;
  	char *mode = "r";
  	int bufsize = -1;
  	PyObject *f;
  
! 	if (!PyArg_ParseTuple(args, "s|si:open", &name, &mode, &bufsize))
  		return NULL;
  	f = PyFile_FromString(name, mode);
  	if (f != NULL)
  		PyFile_SetBufSize(f, bufsize);
--- 1186,1199 ----
  builtin_open(PyObject *self, PyObject *args)
  {
! 	char *name = NULL;
  	char *mode = "r";
  	int bufsize = -1;
  	PyObject *f;
  
! 	if (!PyArg_ParseTuple(args, "et|si:open", Py_FileSystemDefaultEncoding, 
! 	                      &name, &mode, &bufsize))
  		return NULL;
  	f = PyFile_FromString(name, mode);
+ 	PyMem_Free(name); /* free the encoded string */
  	if (f != NULL)
  		PyFile_SetBufSize(f, bufsize);
***************
*** 1354,1358 ****
  		return NULL;
  	}
! 	return PyRange_New(ilow, n, istep, 1);
  }
  
--- 1392,1396 ----
  		return NULL;
  	}
! 	return PyRange_New(ilow, n, istep);
  }
  
***************
*** 1445,1451 ****
  builtin_reduce(PyObject *self, PyObject *args)
  {
! 	PyObject *seq, *func, *result = NULL;
! 	PySequenceMethods *sqf;
! 	register int i;
  
  	if (!PyArg_ParseTuple(args, "OO|O:reduce", &func, &seq, &result))
--- 1483,1487 ----
  builtin_reduce(PyObject *self, PyObject *args)
  {
! 	PyObject *seq, *func, *result = NULL, *it;
  
  	if (!PyArg_ParseTuple(args, "OO|O:reduce", &func, &seq, &result))
***************
*** 1454,1461 ****
  		Py_INCREF(result);
  
! 	sqf = seq->ob_type->tp_as_sequence;
! 	if (sqf == NULL || sqf->sq_item == NULL) {
  		PyErr_SetString(PyExc_TypeError,
! 		    "reduce() arg 2 must be a sequence");
  		return NULL;
  	}
--- 1490,1498 ----
  		Py_INCREF(result);
  
! 	it = PyObject_GetIter(seq);
! 	if (it == NULL) {
  		PyErr_SetString(PyExc_TypeError,
! 		    "reduce() arg 2 must support iteration");
! 		Py_XDECREF(result);
  		return NULL;
  	}
***************
*** 1464,1468 ****
  		goto Fail;
  
! 	for (i = 0; ; ++i) {
  		PyObject *op2;
  
--- 1501,1505 ----
  		goto Fail;
  
! 	for (;;) {
  		PyObject *op2;
  
***************
*** 1473,1482 ****
  		}
  
! 		if ((op2 = (*sqf->sq_item)(seq, i)) == NULL) {
! 			if (PyErr_ExceptionMatches(PyExc_IndexError)) {
! 				PyErr_Clear();
! 				break;
! 			}
! 			goto Fail;
  		}
  
--- 1510,1518 ----
  		}
  
! 		op2 = PyIter_Next(it);
! 		if (op2 == NULL) {
! 			if (PyErr_Occurred())
! 				goto Fail;
!  			break;
  		}
  
***************
*** 1497,1500 ****
--- 1533,1537 ----
  			   "reduce() of empty sequence with no initial value");
  
+ 	Py_DECREF(it);
  	return result;
  
***************
*** 1502,1505 ****
--- 1539,1543 ----
  	Py_XDECREF(args);
  	Py_XDECREF(result);
+ 	Py_DECREF(it);
  	return NULL;
  }
***************
*** 1670,1674 ****
  	PyObject *ret;
  	int itemsize = PySequence_Length(args);
! 	int i, j;
  
  	if (itemsize < 1) {
--- 1708,1713 ----
  	PyObject *ret;
  	int itemsize = PySequence_Length(args);
! 	int i;
! 	PyObject *itlist;  /* tuple of iterators */
  
  	if (itemsize < 1) {
***************
*** 1680,1712 ****
  	assert(PyTuple_Check(args));
  
  	if ((ret = PyList_New(0)) == NULL)
  		return NULL;
  
! 	for (i = 0;; i++) {
! 		PyObject *next = PyTuple_New(itemsize);
! 		if (!next) {
! 			Py_DECREF(ret);
! 			return NULL;
  		}
! 		for (j = 0; j < itemsize; j++) {
! 			PyObject *seq = PyTuple_GET_ITEM(args, j);
! 			PyObject *item = PySequence_GetItem(seq, i);
  
  			if (!item) {
! 				if (PyErr_ExceptionMatches(PyExc_IndexError)) {
! 					PyErr_Clear();
! 					Py_DECREF(next);
! 					return ret;
  				}
  				Py_DECREF(next);
! 				Py_DECREF(ret);
! 				return NULL;
  			}
! 			PyTuple_SET_ITEM(next, j, item);
  		}
! 		PyList_Append(ret, next);
  		Py_DECREF(next);
  	}
! 	/* no return */
  }
  
--- 1719,1776 ----
  	assert(PyTuple_Check(args));
  
+ 	/* allocate result list */
  	if ((ret = PyList_New(0)) == NULL)
  		return NULL;
  
! 	/* obtain iterators */
! 	itlist = PyTuple_New(itemsize);
! 	if (itlist == NULL)
! 		goto Fail_ret;
! 	for (i = 0; i < itemsize; ++i) {
! 		PyObject *item = PyTuple_GET_ITEM(args, i);
! 		PyObject *it = PyObject_GetIter(item);
! 		if (it == NULL) {
! 			if (PyErr_ExceptionMatches(PyExc_TypeError))
! 				PyErr_Format(PyExc_TypeError,
! 				    "zip argument #%d must support iteration",
! 				    i+1);
! 			goto Fail_ret_itlist;
  		}
! 		PyTuple_SET_ITEM(itlist, i, it);
! 	}
! 
! 	/* build result into ret list */
! 	for (;;) {
! 		int status;
! 		PyObject *next = PyTuple_New(itemsize);
! 		if (!next)
! 			goto Fail_ret_itlist;
  
+ 		for (i = 0; i < itemsize; i++) {
+ 			PyObject *it = PyTuple_GET_ITEM(itlist, i);
+ 			PyObject *item = PyIter_Next(it);
  			if (!item) {
! 				if (PyErr_Occurred()) {
! 					Py_DECREF(ret);
! 					ret = NULL;
  				}
  				Py_DECREF(next);
! 				Py_DECREF(itlist);
! 				return ret;
  			}
! 			PyTuple_SET_ITEM(next, i, item);
  		}
! 
! 		status = PyList_Append(ret, next);
  		Py_DECREF(next);
+ 		if (status < 0)
+ 			goto Fail_ret_itlist;
  	}
! 
! Fail_ret_itlist:
! 	Py_DECREF(itlist);
! Fail_ret:
! 	Py_DECREF(ret);
! 	return NULL;
  }
  
***************
*** 1884,1888 ****
  	}
  
! 	if (_PyTuple_Resize(&result, j, 0) < 0)
  		return NULL;
  
--- 1948,1952 ----
  	}
  
! 	if (_PyTuple_Resize(&result, j) < 0)
  		return NULL;
  

Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.241.2.4
retrieving revision 2.241.2.5
diff -C2 -r2.241.2.4 -r2.241.2.5
*** ceval.c	2001/06/28 20:32:44	2.241.2.4
--- ceval.c	2001/07/07 22:55:30	2.241.2.5
***************
*** 3,7 ****
  
  /* XXX TO DO:
!    XXX how to pass arguments to call_trace?
     XXX speed up searching for keywords by using a dictionary
     XXX document it!
--- 3,7 ----
  
  /* XXX TO DO:
!    XXX how to pass arguments to profile and trace functions?
     XXX speed up searching for keywords by using a dictionary
[...1630 lines suppressed...]
+ 		/* XXX This is broken if the caller deletes dict items! */
+ 	}
+ 	else {
+ 		k = NULL;
+ 		nk = 0;
+ 	}
+ 
+ 	result = PyEval_EvalCodeEx(
+ 		(PyCodeObject *)PyFunction_GET_CODE(func),
+ 		PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
+ 		&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg),
+ 		k, nk, d, nd,
+ 		PyFunction_GET_CLOSURE(func));
+ 
+ 	if (k != NULL)
+ 		PyMem_DEL(k);
+ 
+ 	return result;
  }
  

Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.197
retrieving revision 2.197.2.1
diff -C2 -r2.197 -r2.197.2.1
*** compile.c	2001/04/20 19:13:02	2.197
--- compile.c	2001/07/07 22:55:30	2.197.2.1
***************
*** 337,340 ****
--- 337,384 ----
  */
  
+ /* All about c_lnotab.
+ 
+ c_lnotab is an array of unsigned bytes disguised as a Python string.  In -O
+ mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped
+ to source code line #s (when needed for tracebacks) via c_lnotab instead.
+ The array is conceptually a list of
+     (bytecode offset increment, line number increment)
+ pairs.  The details are important and delicate, best illustrated by example:
+ 
+     byte code offset    source code line number
+         0		    1
+         6		    2
+        50		    7
+       350                 307
+       361                 308
+ 
+ The first trick is that these numbers aren't stored, only the increments
+ from one row to the next (this doesn't really work, but it's a start):
+ 
+     0, 1,  6, 1,  44, 5,  300, 300,  11, 1
+ 
+ The second trick is that an unsigned byte can't hold negative values, or
+ values larger than 255, so (a) there's a deep assumption that byte code
+ offsets and their corresponding line #s both increase monotonically, and (b)
+ if at least one column jumps by more than 255 from one row to the next, more
+ than one pair is written to the table. In case #b, there's no way to know
+ from looking at the table later how many were written.  That's the delicate
+ part.  A user of c_lnotab desiring to find the source line number
+ corresponding to a bytecode address A should do something like this
+ 
+     lineno = addr = 0
+     for addr_incr, line_incr in c_lnotab:
+         addr += addr_incr
+         if addr > A:
+             return lineno
+         lineno += line_incr
+ 
+ In order for this to work, when the addr field increments by more than 255,
+ the line # increment in each pair generated must be 0 until the remaining addr
+ increment is < 256.  So, in the example above, com_set_lineno should not (as
+ was actually done until 2.2) expand 300, 300 to 255, 255,  45, 45, but to
+ 255, 0,  45, 255,  0, 45.
+ */
+ 
  struct compiling {
  	PyObject *c_code;	/* string */
***************
*** 693,707 ****
  		int incr_addr = c->c_nexti - c->c_last_addr;
  		int incr_line = lineno - c->c_last_line;
! 		while (incr_addr > 0 || incr_line > 0) {
! 			int trunc_addr = incr_addr;
! 			int trunc_line = incr_line;
! 			if (trunc_addr > 255)
! 				trunc_addr = 255;
! 			if (trunc_line > 255)
! 				trunc_line = 255;
! 			com_add_lnotab(c, trunc_addr, trunc_line);
! 			incr_addr -= trunc_addr;
! 			incr_line -= trunc_line;
  		}
  		c->c_last_addr = c->c_nexti;
  		c->c_last_line = lineno;
--- 737,751 ----
  		int incr_addr = c->c_nexti - c->c_last_addr;
  		int incr_line = lineno - c->c_last_line;
! 		while (incr_addr > 255) {
! 			com_add_lnotab(c, 255, 0);
! 			incr_addr -= 255;
! 		}
! 		while (incr_line > 255) {
! 			com_add_lnotab(c, incr_addr, 255);
! 			incr_line -=255;
! 			incr_addr = 0;
  		}
+ 		if (incr_addr > 0 || incr_line > 0)
+ 			com_add_lnotab(c, incr_addr, incr_line);
  		c->c_last_addr = c->c_nexti;
  		c->c_last_line = lineno;
***************
*** 2591,2594 ****
--- 2635,2644 ----
  		com_error(c, PyExc_SyntaxError, "'return' outside function");
  	}
+ 	if (c->c_flags & CO_GENERATOR) {
+ 		if (NCH(n) > 1) {
+ 			com_error(c, PyExc_SyntaxError,
+ 				  "'return' with argument inside generator");
+ 		}
+ 	}
  	if (NCH(n) < 2) {
  		com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
***************
*** 2602,2605 ****
--- 2652,2677 ----
  
  static void
+ com_yield_stmt(struct compiling *c, node *n)
+ {
+ 	int i;
+ 	REQ(n, yield_stmt); /* 'yield' testlist */
+ 	if (!c->c_infunction) {
+ 		com_error(c, PyExc_SyntaxError, "'yield' outside function");
+ 	}
+ 	
+ 	for (i = 0; i < c->c_nblocks; ++i) {
+ 		if (c->c_block[i] == SETUP_FINALLY) {
+ 			com_error(c, PyExc_SyntaxError,
+ 				  "'yield' not allowed in a 'try' block "
+ 				  "with a 'finally' clause");
+ 			return;
+ 		}
+ 	}
+ 	com_node(c, CHILD(n, 1));
+ 	com_addbyte(c, YIELD_VALUE);
+ 	com_pop(c, 1);
+ }
+ 
+ static void
  com_raise_stmt(struct compiling *c, node *n)
  {
***************
*** 2805,2808 ****
--- 2877,2919 ----
  }
  
+ 
+ /* Look under n for a return stmt with an expression.
+  * This hack is used to find illegal returns under "if 0:" blocks in
+  * functions already known to be generators (as determined by the symtable
+  * pass).
+  * Return the offending return node if found, else NULL.
+  */
+ static node *
+ look_for_offending_return(node *n)
+ {
+ 	int i;
+ 
+ 	for (i = 0; i < NCH(n); ++i) {
+ 		node *kid = CHILD(n, i);
+ 
+ 		switch (TYPE(kid)) {
+ 			case classdef:
+ 			case funcdef:
+ 			case lambdef:
+ 				/* Stuff in nested functions & classes doesn't
+ 				   affect the code block we started in. */
+ 				return NULL;
+ 
+ 			case return_stmt:
+ 				if (NCH(kid) > 1)
+ 					return kid;
+ 				break;
+ 
+ 			default: {
+ 				node *bad = look_for_offending_return(kid);
+ 				if (bad != NULL)
+ 					return bad;
+ 			}
+ 		}
+ 	}
+ 
+ 	return NULL;
+ }			
+ 
  static void
  com_if_stmt(struct compiling *c, node *n)
***************
*** 2815,2820 ****
  		int a = 0;
  		node *ch = CHILD(n, i+1);
! 		if (is_constant_false(c, ch))
  			continue;
  		if (i > 0)
  			com_addoparg(c, SET_LINENO, ch->n_lineno);
--- 2926,2947 ----
  		int a = 0;
  		node *ch = CHILD(n, i+1);
! 		if (is_constant_false(c, ch)) {
! 			/* We're going to skip this block.  However, if this
! 			   is a generator, we have to check the dead code
! 			   anyway to make sure there aren't any return stmts
! 			   with expressions, in the same scope. */
! 			if (c->c_flags & CO_GENERATOR) {
! 				node *p = look_for_offending_return(n);
! 				if (p != NULL) {
! 					int savelineno = c->c_lineno;
! 					c->c_lineno = p->n_lineno;
! 					com_error(c, PyExc_SyntaxError,
! 			  	   		"'return' with argument "
! 			  	   		"inside generator");
! 			  	   	c->c_lineno = savelineno;
! 				}
! 			}
  			continue;
+ 		}
  		if (i > 0)
  			com_addoparg(c, SET_LINENO, ch->n_lineno);
***************
*** 3412,3415 ****
--- 3539,3545 ----
  		com_return_stmt(c, n);
  		break;
+ 	case yield_stmt:
+ 		com_yield_stmt(c, n);
+ 		break;
  	case raise_stmt:
  		com_raise_stmt(c, n);
***************
*** 3540,3544 ****
  		node *ch = CHILD(n, i);
  		node *fp;
- 		char *name;
  		if (TYPE(ch) == STAR || TYPE(ch) == DOUBLESTAR)
  			break;
--- 3670,3673 ----
***************
*** 3546,3550 ****
  		fp = CHILD(ch, 0);
  		if (TYPE(fp) != NAME) {
- 			name = nbuf;
  			sprintf(nbuf, ".%d", i);
  			complex = 1;
--- 3675,3678 ----
***************
*** 4058,4062 ****
  
  static int
! symtable_resolve_free(struct compiling *c, PyObject *name, 
  		      struct symbol_info *si)
  {
--- 4186,4190 ----
  
  static int
! symtable_resolve_free(struct compiling *c, PyObject *name, int flags,
  		      struct symbol_info *si)
  {
***************
*** 4068,4076 ****
  	   method and a free variable with the same name.
  	*/
- 
  	if (c->c_symtable->st_cur->ste_type == TYPE_FUNCTION) {
  		v = PyInt_FromLong(si->si_ncells++);
  		dict = c->c_cellvars;
  	} else {
  		v = PyInt_FromLong(si->si_nfrees++);
  		dict = c->c_freevars;
--- 4196,4212 ----
  	   method and a free variable with the same name.
  	*/
  	if (c->c_symtable->st_cur->ste_type == TYPE_FUNCTION) {
+ 		/* If it isn't declared locally, it can't be a cell. */
+ 		if (!(flags & (DEF_LOCAL | DEF_PARAM)))
+ 			return 0;
  		v = PyInt_FromLong(si->si_ncells++);
  		dict = c->c_cellvars;
  	} else {
+ 		/* If it is free anyway, then there is no need to do
+ 		   anything here.
+ 		*/
+ 		if (is_free(flags ^ DEF_FREE_CLASS) 
+ 		    || (flags == DEF_FREE_CLASS))
+ 			return 0;
  		v = PyInt_FromLong(si->si_nfrees++);
  		dict = c->c_freevars;
***************
*** 4253,4256 ****
--- 4389,4393 ----
  	if (!(flags & DEF_BOUND))
  		return 0;
+ 
  	/* The semantics of this code will change with nested scopes.
  	   It is defined in the current scope and referenced in a
***************
*** 4292,4295 ****
--- 4429,4434 ----
  	if (c->c_future && c->c_future->ff_nested_scopes)
  		c->c_flags |= CO_NESTED;
+ 	if (ste->ste_generator)
+ 		c->c_flags |= CO_GENERATOR;
  	if (ste->ste_type != TYPE_MODULE)
  		c->c_flags |= CO_NEWLOCALS;
***************
*** 4357,4365 ****
  		   variables or declared global.
  		*/
! 		if (flags & (DEF_FREE | DEF_FREE_CLASS)) {
! 		    if ((ste->ste_type == TYPE_CLASS 
! 			 && flags != DEF_FREE_CLASS)
! 			|| (flags & (DEF_LOCAL | DEF_PARAM)))
! 			symtable_resolve_free(c, name, &si);
  		}
  
--- 4496,4503 ----
  		   variables or declared global.
  		*/
! 		if (st->st_nested_scopes) {
! 		    if (flags & (DEF_FREE | DEF_FREE_CLASS)) {
! 			symtable_resolve_free(c, name, flags, &si);
! 		    }
  		}
  
***************
*** 4421,4424 ****
--- 4559,4567 ----
  	}
  
+ 	assert(PyDict_Size(c->c_freevars) == si.si_nfrees);
+ 
+ 	if (st->st_nested_scopes == 0)
+ 		assert(si.si_nfrees == 0);
+ 
  	if (si.si_ncells > 1) { /* one cell is always in order */
  		if (symtable_cellvar_offsets(&c->c_cellvars, c->c_argcount,
***************
*** 4525,4529 ****
  			   indirectly) in A and there are no scopes
  			   with bindings for N between B and A, then N
! 			   is global in B.
  			*/
  			if (v && (ste->ste_type != TYPE_CLASS)) {
--- 4668,4674 ----
  			   indirectly) in A and there are no scopes
  			   with bindings for N between B and A, then N
! 			   is global in B.  Unless A is a class scope,
! 			   because class scopes are not considered for
! 			   nested scopes.
  			*/
  			if (v && (ste->ste_type != TYPE_CLASS)) {
***************
*** 4751,4754 ****
--- 4896,4931 ----
  #define symtable_add_use(ST, NAME) symtable_add_def((ST), (NAME), USE)
  
+ /* Look for a yield stmt under n.  Return 1 if found, else 0.
+    This hack is used to look inside "if 0:" blocks (which are normally
+    ignored) in case those are the only places a yield occurs (so that this
+    function is a generator). */
+ static int
+ look_for_yield(node *n)
+ {
+ 	int i;
+ 
+ 	for (i = 0; i < NCH(n); ++i) {
+ 		node *kid = CHILD(n, i);
+ 
+ 		switch (TYPE(kid)) {
+ 
+ 		case classdef:
+ 		case funcdef:
+ 		case lambdef:
+ 			/* Stuff in nested functions and classes can't make
+ 			   the parent a generator. */
+ 			return 0;
+ 
+ 		case yield_stmt:
+ 			return 1;
+ 
+ 		default:
+ 			if (look_for_yield(kid))
+ 				return 1;
+ 		}
+ 	}
+ 	return 0;
+ }			
+ 
  static void
  symtable_node(struct symtable *st, node *n)
***************
*** 4794,4799 ****
  	case if_stmt:
  		for (i = 0; i + 3 < NCH(n); i += 4) {
! 			if (is_constant_false(NULL, (CHILD(n, i + 1))))
  				continue;
  			symtable_node(st, CHILD(n, i + 1));
  			symtable_node(st, CHILD(n, i + 3));
--- 4971,4980 ----
  	case if_stmt:
  		for (i = 0; i + 3 < NCH(n); i += 4) {
! 			if (is_constant_false(NULL, (CHILD(n, i + 1)))) {
! 				if (st->st_cur->ste_generator == 0)
! 					st->st_cur->ste_generator =
! 						look_for_yield(CHILD(n, i+3));
  				continue;
+ 			}
  			symtable_node(st, CHILD(n, i + 1));
  			symtable_node(st, CHILD(n, i + 3));
***************
*** 4844,4847 ****
--- 5025,5032 ----
  		symtable_assign(st, CHILD(n, 1), 0);
  		break;
+ 	case yield_stmt:
+ 		st->st_cur->ste_generator = 1;
+ 		n = CHILD(n, 1);
+ 		goto loop;
  	case expr_stmt:
  		if (NCH(n) == 1)

Index: dynload_win.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/dynload_win.c,v
retrieving revision 2.7
retrieving revision 2.7.8.1
diff -C2 -r2.7 -r2.7.8.1
*** dynload_win.c	2000/10/05 10:54:45	2.7
--- dynload_win.c	2001/07/07 22:55:30	2.7.8.1
***************
*** 164,185 ****
  #ifdef MS_WIN32
  	{
! 		HINSTANCE hDLL;
  		char pathbuf[260];
! 		if (strchr(pathname, '\\') == NULL &&
! 		    strchr(pathname, '/') == NULL)
! 		{
! 			/* Prefix bare filename with ".\" */
! 			char *p = pathbuf;
! 			*p = '\0';
! 			_getcwd(pathbuf, sizeof pathbuf);
! 			if (*p != '\0' && p[1] == ':')
! 				p += 2;
! 			sprintf(p, ".\\%-.255s", pathname);
! 			pathname = pathbuf;
! 		}
! 		/* Look for dependent DLLs in directory of pathname first */
! 		/* XXX This call doesn't exist in Windows CE */
! 		hDLL = LoadLibraryEx(pathname, NULL,
! 				     LOAD_WITH_ALTERED_SEARCH_PATH);
  		if (hDLL==NULL){
  			char errBuf[256];
--- 164,182 ----
  #ifdef MS_WIN32
  	{
! 		HINSTANCE hDLL = NULL;
  		char pathbuf[260];
! 		LPTSTR dummy;
! 		/* We use LoadLibraryEx so Windows looks for dependent DLLs 
! 		    in directory of pathname first.  However, Windows95
! 		    can sometimes not work correctly unless the absolute
! 		    path is used.  If GetFullPathName() fails, the LoadLibrary
! 		    will certainly fail too, so use its error code */
! 		if (GetFullPathName(pathname,
! 				    sizeof(pathbuf),
! 				    pathbuf,
! 				    &dummy))
! 			/* XXX This call doesn't exist in Windows CE */
! 			hDLL = LoadLibraryEx(pathname, NULL,
! 					     LOAD_WITH_ALTERED_SEARCH_PATH);
  		if (hDLL==NULL){
  			char errBuf[256];

Index: errors.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/errors.c,v
retrieving revision 2.62
retrieving revision 2.62.6.1
diff -C2 -r2.62 -r2.62.6.1
*** errors.c	2001/03/06 12:12:02	2.62
--- errors.c	2001/07/07 22:55:30	2.62.6.1
***************
*** 76,80 ****
  PyErr_Occurred(void)
  {
! 	PyThreadState *tstate = PyThreadState_Get();
  
  	return tstate->curexc_type;
--- 76,80 ----
  PyErr_Occurred(void)
  {
! 	PyThreadState *tstate = PyThreadState_GET();
  
  	return tstate->curexc_type;

Index: getargs.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/getargs.c,v
retrieving revision 2.54.6.1
retrieving revision 2.54.6.2
diff -C2 -r2.54.6.1 -r2.54.6.2
*** getargs.c	2001/06/07 11:28:06	2.54.6.1
--- getargs.c	2001/07/07 22:55:30	2.54.6.2
***************
*** 26,30 ****
  			  int *, char *, int);
  static char *convertsimple(PyObject *, char **, va_list *, char *);
! static char *convertsimple1(PyObject *, char **, va_list *);
  
  static int vgetargskeywords(PyObject *, PyObject *,
--- 26,30 ----
  			  int *, char *, int);
  static char *convertsimple(PyObject *, char **, va_list *, char *);
! static int convertbuffer(PyObject *, void **p, char **);
  
[...1349 lines suppressed...]
  	/* do a cursory check of the keywords just to see how many we got */
--- 1039,1043 ----
  	}	
  	
! 	tplen = PyTuple_GET_SIZE(args);
  	
  	/* do a cursory check of the keywords just to see how many we got */
***************
*** 1096,1100 ****
  		if (*format == '|')
  			format++;
! 		msg = convertitem(PyTuple_GetItem(args, i), &format, p_va,
  				 levels, msgbuf);
  		if (msg) {
--- 1115,1119 ----
  		if (*format == '|')
  			format++;
! 		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
  				 levels, msgbuf);
  		if (msg) {

Index: graminit.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/graminit.c,v
retrieving revision 2.28
retrieving revision 2.28.8.1
diff -C2 -r2.28 -r2.28.8.1
*** graminit.c	2000/08/24 20:11:32	2.28
--- graminit.c	2001/07/07 22:55:30	2.28.8.1
***************
*** 342,350 ****
  	{1, arcs_15_1},
  };
! static arc arcs_16_0[4] = {
  	{54, 1},
  	{55, 1},
  	{56, 1},
  	{57, 1},
  };
  static arc arcs_16_1[1] = {
--- 342,351 ----
[...2505 lines suppressed...]
  	{25, 0},
  	{2, 0},
  	{3, 0},
! 	{319, 0},
  	{1, "lambda"},
! 	{316, 0},
  	{309, 0},
  	{310, 0},
+ 	{311, 0},
  	{1, "class"},
  	{317, 0},
! 	{318, 0},
! 	{320, 0},
  };
  grammar _PyParser_Grammar = {
! 	65,
  	dfas,
! 	{144, labels},
  	256
  };

Index: import.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/import.c,v
retrieving revision 2.176.2.1
retrieving revision 2.176.2.2
diff -C2 -r2.176.2.1 -r2.176.2.2
*** import.c	2001/06/28 16:21:07	2.176.2.1
--- import.c	2001/07/07 22:55:31	2.176.2.2
***************
*** 959,970 ****
  		   and there's an __init__ module in that directory */
  #ifdef HAVE_STAT
! 		if (stat(buf, &statbuf) == 0 &&
! 		    S_ISDIR(statbuf.st_mode) &&
! 		    find_init_module(buf)) {
! 			if (case_ok(buf, len, namelen, name))
! 				return &fd_package;
! 			else
! 				return NULL;
! 		}
  #else
  		/* XXX How are you going to test for directories? */
--- 959,967 ----
  		   and there's an __init__ module in that directory */
  #ifdef HAVE_STAT
! 		if (stat(buf, &statbuf) == 0 &&       /* it exists */
! 		    S_ISDIR(statbuf.st_mode) &&       /* it's a directory */
! 		    find_init_module(buf) &&          /* it has __init__.py */
! 		    case_ok(buf, len, namelen, name)) /* and case matches */
! 			return &fd_package;
  #else
  		/* XXX How are you going to test for directories? */
***************
*** 1198,1221 ****
  find_init_module(char *buf)
  {
! 	size_t save_len = strlen(buf);
  	size_t i = save_len;
  	struct stat statbuf;
  
  	if (save_len + 13 >= MAXPATHLEN)
  		return 0;
  	buf[i++] = SEP;
! 	strcpy(buf+i, "__init__.py");
  	if (stat(buf, &statbuf) == 0) {
! 		buf[save_len] = '\0';
! 		return 1;
  	}
! 	i += strlen(buf+i);
! 	if (Py_OptimizeFlag)
! 		strcpy(buf+i, "o");
! 	else
! 		strcpy(buf+i, "c");
  	if (stat(buf, &statbuf) == 0) {
! 		buf[save_len] = '\0';
! 		return 1;
  	}
  	buf[save_len] = '\0';
--- 1195,1235 ----
  find_init_module(char *buf)
  {
! 	const size_t save_len = strlen(buf);
  	size_t i = save_len;
+ 	char *pname;  /* pointer to start of __init__ */
  	struct stat statbuf;
  
+ /*	For calling case_ok(buf, len, namelen, name):
+  *	/a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
+  *	^                      ^                   ^    ^
+  *	|--------------------- buf ---------------------|
+  *	|------------------- len ------------------|
+  *	                       |------ name -------|
+  *	                       |----- namelen -----|
+  */
  	if (save_len + 13 >= MAXPATHLEN)
  		return 0;
  	buf[i++] = SEP;
! 	pname = buf + i;
! 	strcpy(pname, "__init__.py");
  	if (stat(buf, &statbuf) == 0) {
! 		if (case_ok(buf,
! 			    save_len + 9,	/* len("/__init__") */
! 		            8,   		/* len("__init__") */
! 		            pname)) {
! 			buf[save_len] = '\0';
! 			return 1;
! 		}
  	}
! 	i += strlen(pname);
! 	strcpy(buf+i, Py_OptimizeFlag ? "o" : "c");
  	if (stat(buf, &statbuf) == 0) {
! 		if (case_ok(buf,
! 			    save_len + 9,	/* len("/__init__") */
! 		            8,   		/* len("__init__") */
! 		            pname)) {
! 			buf[save_len] = '\0';
! 			return 1;
! 		}
  	}
  	buf[save_len] = '\0';

Index: marshal.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v
retrieving revision 1.62
retrieving revision 1.62.4.1
diff -C2 -r1.62 -r1.62.4.1
*** marshal.c	2001/04/10 05:02:52	1.62
--- marshal.c	2001/07/07 22:55:31	1.62.4.1
***************
*** 18,21 ****
--- 18,22 ----
  #define TYPE_NULL	'0'
  #define TYPE_NONE	'N'
+ #define TYPE_STOPITER	'S'
  #define TYPE_ELLIPSIS   '.'
  #define TYPE_INT	'i'
***************
*** 121,124 ****
--- 122,128 ----
  		w_byte(TYPE_NONE, p);
  	}
+ 	else if (v == PyExc_StopIteration) {
+ 		w_byte(TYPE_STOPITER, p);
+ 	}
  	else if (v == Py_Ellipsis) {
  	        w_byte(TYPE_ELLIPSIS, p);
***************
*** 150,156 ****
  	}
  	else if (PyFloat_Check(v)) {
- 		extern void PyFloat_AsString(char *, PyFloatObject *);
  		char buf[256]; /* Plenty to format any double */
! 		PyFloat_AsString(buf, (PyFloatObject *)v);
  		n = strlen(buf);
  		w_byte(TYPE_FLOAT, p);
--- 154,159 ----
  	}
  	else if (PyFloat_Check(v)) {
  		char buf[256]; /* Plenty to format any double */
! 		PyFloat_AsReprString(buf, (PyFloatObject *)v);
  		n = strlen(buf);
  		w_byte(TYPE_FLOAT, p);
***************
*** 160,164 ****
  #ifndef WITHOUT_COMPLEX
  	else if (PyComplex_Check(v)) {
- 		extern void PyFloat_AsString(char *, PyFloatObject *);
  		char buf[256]; /* Plenty to format any double */
  		PyFloatObject *temp;
--- 163,166 ----
***************
*** 166,170 ****
  		temp = (PyFloatObject*)PyFloat_FromDouble(
  			PyComplex_RealAsDouble(v));
! 		PyFloat_AsString(buf, temp);
  		Py_DECREF(temp);
  		n = strlen(buf);
--- 168,172 ----
  		temp = (PyFloatObject*)PyFloat_FromDouble(
  			PyComplex_RealAsDouble(v));
! 		PyFloat_AsReprString(buf, temp);
  		Py_DECREF(temp);
  		n = strlen(buf);
***************
*** 173,177 ****
  		temp = (PyFloatObject*)PyFloat_FromDouble(
  			PyComplex_ImagAsDouble(v));
! 		PyFloat_AsString(buf, temp);
  		Py_DECREF(temp);
  		n = strlen(buf);
--- 175,179 ----
  		temp = (PyFloatObject*)PyFloat_FromDouble(
  			PyComplex_ImagAsDouble(v));
! 		PyFloat_AsReprString(buf, temp);
  		Py_DECREF(temp);
  		n = strlen(buf);
***************
*** 378,381 ****
--- 380,387 ----
  		Py_INCREF(Py_None);
  		return Py_None;
+ 
+ 	case TYPE_STOPITER:
+ 		Py_INCREF(PyExc_StopIteration);
+ 		return PyExc_StopIteration;
  
  	case TYPE_ELLIPSIS:

Index: pystate.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pystate.c,v
retrieving revision 2.16
retrieving revision 2.16.6.1
diff -C2 -r2.16 -r2.16.6.1
*** pystate.c	2001/01/23 01:46:06	2.16
--- pystate.c	2001/07/07 22:55:31	2.16.6.1
***************
*** 110,113 ****
--- 110,114 ----
  		tstate->ticker = 0;
  		tstate->tracing = 0;
+ 		tstate->use_tracing = 0;
  
  		tstate->dict = NULL;
***************
*** 121,126 ****
  		tstate->exc_traceback = NULL;
  
! 		tstate->sys_profilefunc = NULL;
! 		tstate->sys_tracefunc = NULL;
  
  		HEAD_LOCK();
--- 122,129 ----
  		tstate->exc_traceback = NULL;
  
! 		tstate->c_profilefunc = NULL;
! 		tstate->c_tracefunc = NULL;
! 		tstate->c_profileobj = NULL;
! 		tstate->c_traceobj = NULL;
  
  		HEAD_LOCK();
***************
*** 153,158 ****
  	ZAP(tstate->exc_traceback);
  
! 	ZAP(tstate->sys_profilefunc);
! 	ZAP(tstate->sys_tracefunc);
  }
  
--- 156,163 ----
  	ZAP(tstate->exc_traceback);
  
! 	tstate->c_profilefunc = NULL;
! 	tstate->c_tracefunc = NULL;
! 	ZAP(tstate->c_profileobj);
! 	ZAP(tstate->c_traceobj);
  }
  

Index: pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.133.4.3
retrieving revision 2.133.4.4
diff -C2 -r2.133.4.3 -r2.133.4.4
*** pythonrun.c	2001/07/05 16:25:52	2.133.4.3
--- pythonrun.c	2001/07/07 22:55:31	2.133.4.4
***************
*** 1080,1085 ****
  		if (co->co_flags & CO_NESTED)
  			flags->cf_nested_scopes = 1;
  		fprintf(stderr, "run_pyc_file: nested_scopes: %d\n",
! 			flags->cf_nested_scopes);			
  	}
  	Py_DECREF(co);
--- 1080,1087 ----
  		if (co->co_flags & CO_NESTED)
  			flags->cf_nested_scopes = 1;
+ #if 0
  		fprintf(stderr, "run_pyc_file: nested_scopes: %d\n",
! 			flags->cf_nested_scopes);
! #endif
  	}
  	Py_DECREF(co);

Index: symtable.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v
retrieving revision 2.4
retrieving revision 2.4.6.1
diff -C2 -r2.4 -r2.4.6.1
*** symtable.c	2001/02/27 19:07:02	2.4
--- symtable.c	2001/07/07 22:55:31	2.4.6.1
***************
*** 70,73 ****
--- 70,74 ----
  		ste->ste_nested = 0;
  	ste->ste_child_free = 0;
+ 	ste->ste_generator = 0;
  
  	if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)

Index: sysmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v
retrieving revision 2.85
retrieving revision 2.85.4.1
diff -C2 -r2.85 -r2.85.4.1
*** sysmodule.c	2001/04/10 22:07:43	2.85
--- sysmodule.c	2001/07/07 22:55:31	2.85.4.1
***************
*** 197,210 ****
  Set the current default string encoding used by the Unicode implementation.";
  
  static PyObject *
  sys_settrace(PyObject *self, PyObject *args)
  {
! 	PyThreadState *tstate = PyThreadState_Get();
  	if (args == Py_None)
! 		args = NULL;
  	else
! 		Py_XINCREF(args);
! 	Py_XDECREF(tstate->sys_tracefunc);
! 	tstate->sys_tracefunc = args;
  	Py_INCREF(Py_None);
  	return Py_None;
--- 197,314 ----
  Set the current default string encoding used by the Unicode implementation.";
  
+ /*
+  * Cached interned string objects used for calling the profile and
+  * trace functions.  Initialized by trace_init().
+  */
+ static PyObject *whatstrings[4] = {NULL, NULL, NULL, NULL};
+ 
+ static int
+ trace_init(void)
+ {
+ 	static char *whatnames[4] = {"call", "exception", "line", "return"};
+ 	PyObject *name;
+ 	int i;
+ 	for (i = 0; i < 4; ++i) {
+ 		if (whatstrings[i] == NULL) {
+ 			name = PyString_InternFromString(whatnames[i]);
+ 			if (name == NULL)
+ 				return -1;
+ 			whatstrings[i] = name;
+                 }
+ 	}
+ 	return 0;
+ }
+ 
+ 
  static PyObject *
+ call_trampoline(PyThreadState *tstate, PyObject* callback,
+ 		PyFrameObject *frame, int what, PyObject *arg)
+ {
+ 	PyObject *args = PyTuple_New(3);
+ 	PyObject *whatstr;
+ 	PyObject *result;
+ 
+ 	if (args == NULL)
+ 		return NULL;
+ 	Py_INCREF(frame);
+ 	whatstr = whatstrings[what];
+ 	Py_INCREF(whatstr);
+ 	if (arg == NULL)
+ 		arg = Py_None;
+ 	Py_INCREF(arg);
+ 	PyTuple_SET_ITEM(args, 0, (PyObject *)frame);
+ 	PyTuple_SET_ITEM(args, 1, whatstr);
+ 	PyTuple_SET_ITEM(args, 2, arg);
+ 
+ 	/* call the Python-level function */
+ 	PyFrame_FastToLocals(frame);
+ 	result = PyEval_CallObject(callback, args);
+ 	PyFrame_LocalsToFast(frame, 1);
+ 	if (result == NULL)
+ 		PyTraceBack_Here(frame);
+ 
+ 	/* cleanup */
+ 	Py_DECREF(args);
+ 	return result;
+ }
+ 
+ static int
+ profile_trampoline(PyObject *self, PyFrameObject *frame,
+ 		   int what, PyObject *arg)
+ {
+ 	PyThreadState *tstate = frame->f_tstate;
+ 	PyObject *result;
+ 
+ 	result = call_trampoline(tstate, self, frame, what, arg);
+ 	if (result == NULL) {
+ 		PyEval_SetProfile(NULL, NULL);
+ 		return -1;
+ 	}
+ 	Py_DECREF(result);
+ 	return 0;
+ }
+ 
+ static int
+ trace_trampoline(PyObject *self, PyFrameObject *frame,
+ 		 int what, PyObject *arg)
+ {
+ 	PyThreadState *tstate = frame->f_tstate;
+ 	PyObject *callback;
+ 	PyObject *result;
+ 
+ 	if (what == PyTrace_CALL)
+ 		callback = self;
+ 	else
+ 		callback = frame->f_trace;
+ 	if (callback == NULL)
+ 		return 0;
+ 	result = call_trampoline(tstate, callback, frame, what, arg);
+ 	if (result == NULL) {
+ 		PyEval_SetTrace(NULL, NULL);
+ 		Py_XDECREF(frame->f_trace);
+ 		frame->f_trace = NULL;
+ 		return -1;
+ 	}
+ 	if (result != Py_None) {
+ 		PyObject *temp = frame->f_trace;
+ 		frame->f_trace = NULL;
+ 		Py_XDECREF(temp);
+ 		frame->f_trace = result;
+ 	}
+ 	else {
+ 		Py_DECREF(result);
+ 	}
+ 	return 0;
+ }
+ 
+ static PyObject *
  sys_settrace(PyObject *self, PyObject *args)
  {
! 	if (trace_init() == -1)
! 		return NULL;
  	if (args == Py_None)
! 		PyEval_SetTrace(NULL, NULL);
  	else
! 		PyEval_SetTrace(trace_trampoline, args);
  	Py_INCREF(Py_None);
  	return Py_None;
***************
*** 220,230 ****
  sys_setprofile(PyObject *self, PyObject *args)
  {
! 	PyThreadState *tstate = PyThreadState_Get();
  	if (args == Py_None)
! 		args = NULL;
  	else
! 		Py_XINCREF(args);
! 	Py_XDECREF(tstate->sys_profilefunc);
! 	tstate->sys_profilefunc = args;
  	Py_INCREF(Py_None);
  	return Py_None;
--- 324,333 ----
  sys_setprofile(PyObject *self, PyObject *args)
  {
! 	if (trace_init() == -1)
! 		return NULL;
  	if (args == Py_None)
! 		PyEval_SetProfile(NULL, NULL);
  	else
! 		PyEval_SetProfile(profile_trampoline, args);
  	Py_INCREF(Py_None);
  	return Py_None;
***************
*** 528,531 ****
--- 631,635 ----
  \n\
  maxint -- the largest supported integer (the smallest is -maxint-1)\n\
+ maxunicode -- the largest supported character\n\
  builtin_module_names -- tuple of module names built into this intepreter\n\
  version -- the version of this interpreter as a string\n\
***************
*** 637,640 ****
--- 741,747 ----
  	PyDict_SetItemString(sysdict, "maxint",
  			     v = PyInt_FromLong(PyInt_GetMax()));
+ 	Py_XDECREF(v);
+ 	PyDict_SetItemString(sysdict, "maxunicode",
+ 			     v = PyInt_FromLong(PyUnicode_GetMax()));
  	Py_XDECREF(v);
  	PyDict_SetItemString(sysdict, "builtin_module_names",