mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Merge of descr-branch back into trunk.
This commit is contained in:
		
							parent
							
								
									52d55a3926
								
							
						
					
					
						commit
						6d6c1a35e0
					
				
					 57 changed files with 6923 additions and 1309 deletions
				
			
		|  | @ -131,26 +131,6 @@ start of the object (or at the specified offset). The slice will\n\ | |||
| extend to the end of the target object (or with the specified size)."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_unicode(PyObject *self, PyObject *args) | ||||
| { | ||||
|         PyObject *v; | ||||
| 	char *encoding = NULL; | ||||
| 	char *errors = NULL; | ||||
| 
 | ||||
| 	if ( !PyArg_ParseTuple(args, "O|ss:unicode", &v, &encoding, &errors) ) | ||||
| 	    return NULL; | ||||
| 	return PyUnicode_FromEncodedObject(v, encoding, errors); | ||||
| } | ||||
| 
 | ||||
| static char unicode_doc[] = | ||||
| "unicode(string [, encoding[, errors]]) -> object\n\
 | ||||
| \n\ | ||||
| Create a new Unicode object from the given encoded string.\n\ | ||||
| encoding defaults to the current default string encoding and \n\ | ||||
| errors, defining the error handling, to 'strict'."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_callable(PyObject *self, PyObject *args) | ||||
| { | ||||
|  | @ -435,257 +415,6 @@ The mode must be 'exec' to compile a module, 'single' to compile a\n\ | |||
| single (interactive) statement, or 'eval' to compile an expression."; | ||||
| 
 | ||||
| 
 | ||||
| #ifndef WITHOUT_COMPLEX | ||||
| 
 | ||||
| static PyObject * | ||||
| complex_from_string(PyObject *v) | ||||
| { | ||||
| 	extern double strtod(const char *, char **); | ||||
| 	const char *s, *start; | ||||
| 	char *end; | ||||
| 	double x=0.0, y=0.0, z; | ||||
| 	int got_re=0, got_im=0, done=0; | ||||
| 	int digit_or_dot; | ||||
| 	int sw_error=0; | ||||
| 	int sign; | ||||
| 	char buffer[256]; /* For errors */ | ||||
| 	char s_buffer[256]; | ||||
| 	int len; | ||||
| 
 | ||||
| 	if (PyString_Check(v)) { | ||||
| 		s = PyString_AS_STRING(v); | ||||
| 		len = PyString_GET_SIZE(v); | ||||
| 	} | ||||
| 	else if (PyUnicode_Check(v)) { | ||||
| 		if (PyUnicode_GET_SIZE(v) >= sizeof(s_buffer)) { | ||||
| 			PyErr_SetString(PyExc_ValueError, | ||||
| 				 "complex() literal too large to convert"); | ||||
| 			return NULL; | ||||
| 		} | ||||
| 		if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), | ||||
| 					    PyUnicode_GET_SIZE(v), | ||||
| 					    s_buffer, | ||||
| 					    NULL)) | ||||
| 			return NULL; | ||||
| 		s = s_buffer; | ||||
| 		len = (int)strlen(s); | ||||
| 	} | ||||
| 	else if (PyObject_AsCharBuffer(v, &s, &len)) { | ||||
| 		PyErr_SetString(PyExc_TypeError, | ||||
| 				"complex() arg is not a string"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	/* position on first nonblank */ | ||||
| 	start = s; | ||||
| 	while (*s && isspace(Py_CHARMASK(*s))) | ||||
| 		s++; | ||||
| 	if (s[0] == '\0') { | ||||
| 		PyErr_SetString(PyExc_ValueError, | ||||
| 				"complex() arg is an empty string"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	z = -1.0; | ||||
| 	sign = 1; | ||||
| 	do { | ||||
| 
 | ||||
| 		switch (*s) { | ||||
| 
 | ||||
| 		case '\0': | ||||
| 			if (s-start != len) { | ||||
| 				PyErr_SetString( | ||||
| 					PyExc_ValueError, | ||||
| 					"complex() arg contains a null byte"); | ||||
| 				return NULL; | ||||
| 			} | ||||
| 			if(!done) sw_error=1; | ||||
| 			break; | ||||
| 
 | ||||
| 		case '-': | ||||
| 			sign = -1; | ||||
| 				/* Fallthrough */ | ||||
| 		case '+': | ||||
| 			if (done)  sw_error=1; | ||||
| 			s++; | ||||
| 			if  (  *s=='\0'||*s=='+'||*s=='-'  || | ||||
| 			       isspace(Py_CHARMASK(*s))  )  sw_error=1; | ||||
| 			break; | ||||
| 
 | ||||
| 		case 'J': | ||||
| 		case 'j': | ||||
| 			if (got_im || done) { | ||||
| 				sw_error = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 			if  (z<0.0) { | ||||
| 				y=sign; | ||||
| 			} | ||||
| 			else{ | ||||
| 				y=sign*z; | ||||
| 			} | ||||
| 			got_im=1; | ||||
| 			s++; | ||||
| 			if  (*s!='+' && *s!='-' ) | ||||
| 				done=1; | ||||
| 			break; | ||||
| 
 | ||||
| 		default: | ||||
| 			if (isspace(Py_CHARMASK(*s))) { | ||||
| 				while (*s && isspace(Py_CHARMASK(*s))) | ||||
| 					s++; | ||||
| 				if (s[0] != '\0') | ||||
| 					sw_error=1; | ||||
| 				else | ||||
| 					done = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 			digit_or_dot = | ||||
| 				(*s=='.' || isdigit(Py_CHARMASK(*s))); | ||||
| 			if  (done||!digit_or_dot) { | ||||
| 				sw_error=1; | ||||
| 				break; | ||||
| 			} | ||||
| 			errno = 0; | ||||
| 			PyFPE_START_PROTECT("strtod", return 0) | ||||
| 				z = strtod(s, &end) ; | ||||
| 			PyFPE_END_PROTECT(z) | ||||
| 				if (errno != 0) { | ||||
| 					sprintf(buffer, | ||||
| 					  "float() out of range: %.150s", s); | ||||
| 					PyErr_SetString( | ||||
| 						PyExc_ValueError, | ||||
| 						buffer); | ||||
| 					return NULL; | ||||
| 				} | ||||
| 			s=end; | ||||
| 			if  (*s=='J' || *s=='j') { | ||||
| 
 | ||||
| 				break; | ||||
| 			} | ||||
| 			if  (got_re) { | ||||
| 				sw_error=1; | ||||
| 				break; | ||||
| 			} | ||||
| 
 | ||||
| 				/* accept a real part */ | ||||
| 			x=sign*z; | ||||
| 			got_re=1; | ||||
| 			if  (got_im)  done=1; | ||||
| 			z = -1.0; | ||||
| 			sign = 1; | ||||
| 			break; | ||||
| 
 | ||||
| 		}  /* end of switch  */ | ||||
| 
 | ||||
| 	} while (*s!='\0' && !sw_error); | ||||
| 
 | ||||
| 	if (sw_error) { | ||||
| 		PyErr_SetString(PyExc_ValueError, | ||||
| 				"complex() arg is a malformed string"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	return PyComplex_FromDoubles(x,y); | ||||
| } | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_complex(PyObject *self, PyObject *args) | ||||
| { | ||||
| 	PyObject *r, *i, *tmp; | ||||
| 	PyNumberMethods *nbr, *nbi = NULL; | ||||
| 	Py_complex cr, ci; | ||||
| 	int own_r = 0; | ||||
| 
 | ||||
| 	i = NULL; | ||||
| 	if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i)) | ||||
| 		return NULL; | ||||
| 	if (PyString_Check(r) || PyUnicode_Check(r)) | ||||
| 		return complex_from_string(r); | ||||
| 	if ((nbr = r->ob_type->tp_as_number) == NULL || | ||||
| 	    nbr->nb_float == NULL || | ||||
| 	    (i != NULL && | ||||
| 	     ((nbi = i->ob_type->tp_as_number) == NULL || | ||||
| 	      nbi->nb_float == NULL))) { | ||||
| 		PyErr_SetString(PyExc_TypeError, | ||||
| 			   "complex() arg can't be converted to complex"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	/* XXX Hack to support classes with __complex__ method */ | ||||
| 	if (PyInstance_Check(r)) { | ||||
| 		static PyObject *complexstr; | ||||
| 		PyObject *f; | ||||
| 		if (complexstr == NULL) { | ||||
| 			complexstr = PyString_InternFromString("__complex__"); | ||||
| 			if (complexstr == NULL) | ||||
| 				return NULL; | ||||
| 		} | ||||
| 		f = PyObject_GetAttr(r, complexstr); | ||||
| 		if (f == NULL) | ||||
| 			PyErr_Clear(); | ||||
| 		else { | ||||
| 			PyObject *args = Py_BuildValue("()"); | ||||
| 			if (args == NULL) | ||||
| 				return NULL; | ||||
| 			r = PyEval_CallObject(f, args); | ||||
| 			Py_DECREF(args); | ||||
| 			Py_DECREF(f); | ||||
| 			if (r == NULL) | ||||
| 				return NULL; | ||||
| 			own_r = 1; | ||||
| 		} | ||||
| 	} | ||||
| 	if (PyComplex_Check(r)) { | ||||
| 		cr = ((PyComplexObject*)r)->cval; | ||||
| 		if (own_r) { | ||||
| 			Py_DECREF(r); | ||||
| 		} | ||||
| 	} | ||||
| 	else { | ||||
| 		tmp = PyNumber_Float(r); | ||||
| 		if (own_r) { | ||||
| 			Py_DECREF(r); | ||||
| 		} | ||||
| 		if (tmp == NULL) | ||||
| 			return NULL; | ||||
| 		if (!PyFloat_Check(tmp)) { | ||||
| 			PyErr_SetString(PyExc_TypeError, | ||||
| 					"float(r) didn't return a float"); | ||||
| 			Py_DECREF(tmp); | ||||
| 			return NULL; | ||||
| 		} | ||||
| 		cr.real = PyFloat_AsDouble(tmp); | ||||
| 		Py_DECREF(tmp); | ||||
| 		cr.imag = 0.0; | ||||
| 	} | ||||
| 	if (i == NULL) { | ||||
| 		ci.real = 0.0; | ||||
| 		ci.imag = 0.0; | ||||
| 	} | ||||
| 	else if (PyComplex_Check(i)) | ||||
| 		ci = ((PyComplexObject*)i)->cval; | ||||
| 	else { | ||||
| 		tmp = (*nbi->nb_float)(i); | ||||
| 		if (tmp == NULL) | ||||
| 			return NULL; | ||||
| 		ci.real = PyFloat_AsDouble(tmp); | ||||
| 		Py_DECREF(tmp); | ||||
| 		ci.imag = 0.; | ||||
| 	} | ||||
| 	cr.real -= ci.imag; | ||||
| 	cr.imag += ci.real; | ||||
| 	return PyComplex_FromCComplex(cr); | ||||
| } | ||||
| 
 | ||||
| static char complex_doc[] = | ||||
| "complex(real[, imag]) -> complex number\n\
 | ||||
| \n\ | ||||
| Create a complex number from a real part and an optional imaginary part.\n\ | ||||
| This is equivalent to (real + imag*1j) where imag defaults to 0."; | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_dir(PyObject *self, PyObject *args) | ||||
| { | ||||
|  | @ -1060,8 +789,8 @@ builtin_map(PyObject *self, PyObject *args) | |||
| 		} | ||||
| 		if (curlen < 0) | ||||
| 			curlen = 8;  /* arbitrary */ | ||||
| 		if (curlen > len) | ||||
| 			len = curlen; | ||||
| 			if (curlen > len) | ||||
| 				len = curlen; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Get space for the result list. */ | ||||
|  | @ -1300,91 +1029,6 @@ Return the string itself or the previously interned string object with the\n\ | |||
| same value."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_int(PyObject *self, PyObject *args) | ||||
| { | ||||
| 	PyObject *v; | ||||
| 	int base = -909;		     /* unlikely! */ | ||||
| 
 | ||||
| 	if (!PyArg_ParseTuple(args, "O|i:int", &v, &base)) | ||||
| 		return NULL; | ||||
| 	if (base == -909) | ||||
| 		return PyNumber_Int(v); | ||||
| 	else if (PyString_Check(v)) | ||||
| 		return PyInt_FromString(PyString_AS_STRING(v), NULL, base); | ||||
| 	else if (PyUnicode_Check(v)) | ||||
| 		return PyInt_FromUnicode(PyUnicode_AS_UNICODE(v), | ||||
| 					 PyUnicode_GET_SIZE(v), | ||||
| 					 base); | ||||
| 	else { | ||||
| 		PyErr_SetString(PyExc_TypeError, | ||||
| 				"int() can't convert non-string with explicit base"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static char int_doc[] = | ||||
| "int(x[, base]) -> integer\n\
 | ||||
| \n\ | ||||
| Convert a string or number to an integer, if possible.  A floating point\n\ | ||||
| argument will be truncated towards zero (this does not include a string\n\ | ||||
| representation of a floating point number!)  When converting a string, use\n\ | ||||
| the optional base.  It is an error to supply a base when converting a\n\ | ||||
| non-string."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_long(PyObject *self, PyObject *args) | ||||
| { | ||||
| 	PyObject *v; | ||||
| 	int base = -909;		     /* unlikely! */ | ||||
| 
 | ||||
| 	if (!PyArg_ParseTuple(args, "O|i:long", &v, &base)) | ||||
| 		return NULL; | ||||
| 	if (base == -909) | ||||
| 		return PyNumber_Long(v); | ||||
| 	else if (PyString_Check(v)) | ||||
| 		return PyLong_FromString(PyString_AS_STRING(v), NULL, base); | ||||
| 	else if (PyUnicode_Check(v)) | ||||
| 		return PyLong_FromUnicode(PyUnicode_AS_UNICODE(v), | ||||
| 					  PyUnicode_GET_SIZE(v), | ||||
| 					  base); | ||||
| 	else { | ||||
| 		PyErr_SetString(PyExc_TypeError, | ||||
| 				"long() can't convert non-string with explicit base"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static char long_doc[] = | ||||
| "long(x) -> long integer\n\
 | ||||
| long(x, base) -> long integer\n\ | ||||
| \n\ | ||||
| Convert a string or number to a long integer, if possible.  A floating\n\ | ||||
| point argument will be truncated towards zero (this does not include a\n\ | ||||
| string representation of a floating point number!)  When converting a\n\ | ||||
| string, use the given base.  It is an error to supply a base when\n\ | ||||
| converting a non-string."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_float(PyObject *self, PyObject *args) | ||||
| { | ||||
| 	PyObject *v; | ||||
| 
 | ||||
| 	if (!PyArg_ParseTuple(args, "O:float", &v)) | ||||
| 		return NULL; | ||||
| 	if (PyString_Check(v)) | ||||
| 		return PyFloat_FromString(v, NULL); | ||||
| 	return PyNumber_Float(v); | ||||
| } | ||||
| 
 | ||||
| static char float_doc[] = | ||||
| "float(x) -> floating point number\n\
 | ||||
| \n\ | ||||
| Convert a string or number to a floating point number, if possible."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_iter(PyObject *self, PyObject *args) | ||||
| { | ||||
|  | @ -1431,22 +1075,6 @@ static char len_doc[] = | |||
| Return the number of items of a sequence or mapping."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_list(PyObject *self, PyObject *args) | ||||
| { | ||||
| 	PyObject *v; | ||||
| 
 | ||||
| 	if (!PyArg_ParseTuple(args, "O:list", &v)) | ||||
| 		return NULL; | ||||
| 	return PySequence_List(v); | ||||
| } | ||||
| 
 | ||||
| static char list_doc[] = | ||||
| "list(sequence) -> list\n\
 | ||||
| \n\ | ||||
| Return a new list whose items are the same as those of the argument sequence."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_slice(PyObject *self, PyObject *args) | ||||
| { | ||||
|  | @ -2032,58 +1660,6 @@ Round a number to a given precision in decimal digits (default 0 digits).\n\ | |||
| This always returns a floating point number.  Precision may be negative."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_str(PyObject *self, PyObject *args) | ||||
| { | ||||
| 	PyObject *v; | ||||
| 
 | ||||
| 	if (!PyArg_ParseTuple(args, "O:str", &v)) | ||||
| 		return NULL; | ||||
| 	return PyObject_Str(v); | ||||
| } | ||||
| 
 | ||||
| static char str_doc[] = | ||||
| "str(object) -> string\n\
 | ||||
| \n\ | ||||
| Return a nice string representation of the object.\n\ | ||||
| If the argument is a string, the return value is the same object."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_tuple(PyObject *self, PyObject *args) | ||||
| { | ||||
| 	PyObject *v; | ||||
| 
 | ||||
| 	if (!PyArg_ParseTuple(args, "O:tuple", &v)) | ||||
| 		return NULL; | ||||
| 	return PySequence_Tuple(v); | ||||
| } | ||||
| 
 | ||||
| static char tuple_doc[] = | ||||
| "tuple(sequence) -> list\n\
 | ||||
| \n\ | ||||
| Return a tuple whose items are the same as those of the argument sequence.\n\ | ||||
| If the argument is a tuple, the return value is the same object."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_type(PyObject *self, PyObject *args) | ||||
| { | ||||
| 	PyObject *v; | ||||
| 
 | ||||
| 	if (!PyArg_ParseTuple(args, "O:type", &v)) | ||||
| 		return NULL; | ||||
| 	v = (PyObject *)v->ob_type; | ||||
| 	Py_INCREF(v); | ||||
| 	return v; | ||||
| } | ||||
| 
 | ||||
| static char type_doc[] = | ||||
| "type(object) -> type object\n\
 | ||||
| \n\ | ||||
| Return the type of the object."; | ||||
| 
 | ||||
| 
 | ||||
| static PyObject * | ||||
| builtin_vars(PyObject *self, PyObject *args) | ||||
| { | ||||
|  | @ -2255,16 +1831,12 @@ static PyMethodDef builtin_methods[] = { | |||
| 	{"cmp",		builtin_cmp, 1, cmp_doc}, | ||||
| 	{"coerce",	builtin_coerce, 1, coerce_doc}, | ||||
| 	{"compile",	builtin_compile, 1, compile_doc}, | ||||
| #ifndef WITHOUT_COMPLEX | ||||
| 	{"complex",	builtin_complex, 1, complex_doc}, | ||||
| #endif | ||||
| 	{"delattr",	builtin_delattr, 1, delattr_doc}, | ||||
| 	{"dir",		builtin_dir, 1, dir_doc}, | ||||
| 	{"divmod",	builtin_divmod, 1, divmod_doc}, | ||||
| 	{"eval",	builtin_eval, 1, eval_doc}, | ||||
| 	{"execfile",	builtin_execfile, 1, execfile_doc}, | ||||
| 	{"filter",	builtin_filter, 1, filter_doc}, | ||||
| 	{"float",	builtin_float, 1, float_doc}, | ||||
| 	{"getattr",	builtin_getattr, 1, getattr_doc}, | ||||
| 	{"globals",	builtin_globals, 1, globals_doc}, | ||||
| 	{"hasattr",	builtin_hasattr, 1, hasattr_doc}, | ||||
|  | @ -2273,14 +1845,11 @@ static PyMethodDef builtin_methods[] = { | |||
| 	{"id",		builtin_id, 1, id_doc}, | ||||
| 	{"input",	builtin_input, 1, input_doc}, | ||||
| 	{"intern",	builtin_intern, 1, intern_doc}, | ||||
| 	{"int",		builtin_int, 1, int_doc}, | ||||
| 	{"isinstance",  builtin_isinstance, 1, isinstance_doc}, | ||||
| 	{"issubclass",  builtin_issubclass, 1, issubclass_doc}, | ||||
| 	{"iter",	builtin_iter, 1, iter_doc}, | ||||
| 	{"len",		builtin_len, 1, len_doc}, | ||||
| 	{"list",	builtin_list, 1, list_doc}, | ||||
| 	{"locals",	builtin_locals, 1, locals_doc}, | ||||
| 	{"long",	builtin_long, 1, long_doc}, | ||||
| 	{"map",		builtin_map, 1, map_doc}, | ||||
| 	{"max",		builtin_max, 1, max_doc}, | ||||
| 	{"min",		builtin_min, 1, min_doc}, | ||||
|  | @ -2296,10 +1865,6 @@ static PyMethodDef builtin_methods[] = { | |||
| 	{"round",	builtin_round, 1, round_doc}, | ||||
| 	{"setattr",	builtin_setattr, 1, setattr_doc}, | ||||
| 	{"slice",       builtin_slice, 1, slice_doc}, | ||||
| 	{"str",		builtin_str, 1, str_doc}, | ||||
| 	{"tuple",	builtin_tuple, 1, tuple_doc}, | ||||
| 	{"type",	builtin_type, 1, type_doc}, | ||||
| 	{"unicode",	builtin_unicode, 1, unicode_doc}, | ||||
| 	{"unichr",	builtin_unichr, 1, unichr_doc}, | ||||
| 	{"vars",	builtin_vars, 1, vars_doc}, | ||||
| 	{"xrange",	builtin_xrange, 1, xrange_doc}, | ||||
|  | @ -2329,6 +1894,42 @@ _PyBuiltin_Init(void) | |||
| 	if (PyDict_SetItemString(dict, "NotImplemented", | ||||
| 				 Py_NotImplemented) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "classmethod", | ||||
| 				 (PyObject *) &PyClassMethod_Type) < 0) | ||||
| 		return NULL; | ||||
| #ifndef WITHOUT_COMPLEX | ||||
| 	if (PyDict_SetItemString(dict, "complex", | ||||
| 				 (PyObject *) &PyComplex_Type) < 0) | ||||
| 		return NULL; | ||||
| #endif | ||||
| 	if (PyDict_SetItemString(dict, "dictionary", | ||||
| 				 (PyObject *) &PyDict_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "float", | ||||
| 				 (PyObject *) &PyFloat_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "int", (PyObject *) &PyInt_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "list", (PyObject *) &PyList_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "long", (PyObject *) &PyLong_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "object", | ||||
| 				 (PyObject *) &PyBaseObject_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "staticmethod", | ||||
| 				 (PyObject *) &PyStaticMethod_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "str", (PyObject *) &PyString_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "tuple", | ||||
| 				 (PyObject *) &PyTuple_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "type", (PyObject *) &PyType_Type) < 0) | ||||
| 		return NULL; | ||||
| 	if (PyDict_SetItemString(dict, "unicode", | ||||
| 				 (PyObject *) &PyUnicode_Type) < 0) | ||||
| 		return NULL; | ||||
| 	debug = PyInt_FromLong(Py_OptimizeFlag == 0); | ||||
| 	if (PyDict_SetItemString(dict, "__debug__", debug) < 0) { | ||||
| 		Py_XDECREF(debug); | ||||
|  |  | |||
							
								
								
									
										163
									
								
								Python/ceval.c
									
										
									
									
									
								
							
							
						
						
									
										163
									
								
								Python/ceval.c
									
										
									
									
									
								
							|  | @ -13,6 +13,7 @@ | |||
| #include "frameobject.h" | ||||
| #include "eval.h" | ||||
| #include "opcode.h" | ||||
| #include "structmember.h" | ||||
| 
 | ||||
| #ifdef macintosh | ||||
| #include "macglue.h" | ||||
|  | @ -32,17 +33,7 @@ | |||
| typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *); | ||||
| 
 | ||||
| /* Forward declarations */ | ||||
| 
 | ||||
| static PyObject *eval_code2(PyCodeObject *, | ||||
| 			    PyObject *, PyObject *, | ||||
| 			    PyObject **, int, | ||||
| 			    PyObject **, int, | ||||
| 			    PyObject **, int, | ||||
| 			    PyObject *); | ||||
| 
 | ||||
| static PyObject *eval_frame(PyFrameObject *); | ||||
| static char *get_func_name(PyObject *); | ||||
| static char *get_func_desc(PyObject *); | ||||
| static PyObject *call_object(PyObject *, PyObject *, PyObject *); | ||||
| static PyObject *call_cfunction(PyObject *, PyObject *, PyObject *); | ||||
| static PyObject *call_instance(PyObject *, PyObject *, PyObject *); | ||||
|  | @ -98,7 +89,6 @@ static long dxp[256]; | |||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| staticforward PyTypeObject gentype; | ||||
| 
 | ||||
| typedef struct { | ||||
|  | @ -211,24 +201,11 @@ static struct PyMethodDef gen_methods[] = { | |||
| 	{NULL,          NULL}   /* Sentinel */ | ||||
| }; | ||||
| 
 | ||||
| static PyObject * | ||||
| gen_getattr(genobject *gen, char *name) | ||||
| { | ||||
| 	PyObject *result; | ||||
| 
 | ||||
| 	if (strcmp(name, "gi_frame") == 0) { | ||||
| 		result = (PyObject *)gen->gi_frame; | ||||
| 		assert(result != NULL); | ||||
| 		Py_INCREF(result); | ||||
| 	} | ||||
| 	else if (strcmp(name, "gi_running") == 0) | ||||
| 		result = (PyObject *)PyInt_FromLong((long)gen->gi_running); | ||||
| 	else if (strcmp(name, "__members__") == 0) | ||||
| 		result = Py_BuildValue("[ss]", "gi_frame", "gi_running"); | ||||
| 	else | ||||
|  		result = Py_FindMethod(gen_methods, (PyObject *)gen, name); | ||||
|  	return result; | ||||
| } | ||||
| static struct memberlist gen_memberlist[] = { | ||||
| 	{"gi_frame",	T_OBJECT, offsetof(genobject, gi_frame),	RO}, | ||||
| 	{"gi_running",	T_INT,    offsetof(genobject, gi_running),	RO}, | ||||
| 	{NULL}	/* Sentinel */ | ||||
| }; | ||||
| 
 | ||||
| statichere PyTypeObject gentype = { | ||||
| 	PyObject_HEAD_INIT(&PyType_Type) | ||||
|  | @ -239,7 +216,7 @@ statichere PyTypeObject gentype = { | |||
| 	/* methods */ | ||||
| 	(destructor)gen_dealloc, 		/* tp_dealloc */ | ||||
| 	0,					/* tp_print */ | ||||
| 	(getattrfunc)gen_getattr,		/* tp_getattr */ | ||||
| 	0, 					/* tp_getattr */ | ||||
| 	0,					/* tp_setattr */ | ||||
| 	0,					/* tp_compare */ | ||||
| 	0,					/* tp_repr */ | ||||
|  | @ -249,7 +226,7 @@ statichere PyTypeObject gentype = { | |||
| 	0,					/* tp_hash */ | ||||
| 	0,					/* tp_call */ | ||||
| 	0,					/* tp_str */ | ||||
| 	0,					/* tp_getattro */ | ||||
| 	PyObject_GenericGetAttr,		/* tp_getattro */ | ||||
| 	0,					/* tp_setattro */ | ||||
| 	0,					/* tp_as_buffer */ | ||||
| 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC,	/* tp_flags */ | ||||
|  | @ -260,6 +237,11 @@ statichere PyTypeObject gentype = { | |||
| 	0,					/* tp_weaklistoffset */ | ||||
| 	(getiterfunc)gen_getiter,		/* tp_iter */ | ||||
| 	(iternextfunc)gen_iternext,		/* tp_iternext */ | ||||
| 	gen_methods,				/* tp_methods */ | ||||
| 	gen_memberlist,				/* tp_members */ | ||||
| 	0,					/* tp_getset */ | ||||
| 	0,					/* tp_base */ | ||||
| 	0,					/* tp_dict */ | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -505,7 +487,7 @@ static int unpack_iterable(PyObject *, int, PyObject **); | |||
| PyObject * | ||||
| PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals) | ||||
| { | ||||
| 	return eval_code2(co, | ||||
| 	return PyEval_EvalCodeEx(co, | ||||
| 			  globals, locals, | ||||
| 			  (PyObject **)NULL, 0, | ||||
| 			  (PyObject **)NULL, 0, | ||||
|  | @ -516,7 +498,7 @@ PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals) | |||
| 
 | ||||
| /* Interpreter main loop */ | ||||
| 
 | ||||
| PyObject * | ||||
| static PyObject * | ||||
| eval_frame(PyFrameObject *f) | ||||
| { | ||||
| #ifdef DXPAIRS | ||||
|  | @ -965,7 +947,7 @@ eval_frame(PyFrameObject *f) | |||
| 		case BINARY_SUBSCR: | ||||
| 			w = POP(); | ||||
| 			v = POP(); | ||||
| 			if (PyList_Check(v) && PyInt_Check(w)) { | ||||
| 			if (v->ob_type == &PyList_Type && PyInt_Check(w)) { | ||||
| 				/* INLINE: list[int] */ | ||||
| 				long i = PyInt_AsLong(w); | ||||
| 				if (i < 0) | ||||
|  | @ -2273,8 +2255,8 @@ eval_frame(PyFrameObject *f) | |||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| static PyObject * | ||||
| eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, | ||||
| PyObject * | ||||
| PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals, | ||||
| 	   PyObject **args, int argcount, PyObject **kws, int kwcount, | ||||
| 	   PyObject **defs, int defcount, PyObject *closure) | ||||
| { | ||||
|  | @ -2973,13 +2955,13 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw) | |||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	result = call_object(func, arg, kw); | ||||
| 	result = PyObject_Call(func, arg, kw); | ||||
| 	Py_DECREF(arg); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| /* How often is each kind of object called?  The answer depends on the
 | ||||
|    program.  An instrumented call_object() was used to run the Python | ||||
|    program.  An instrumented PyObject_Call() was used to run the Python | ||||
|    regression test suite.  The results were: | ||||
|    4200000 PyCFunctions | ||||
|     390000 fast_function() calls | ||||
|  | @ -2992,11 +2974,11 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw) | |||
|     most common, but not by such a large margin. | ||||
| */ | ||||
| 
 | ||||
| static char * | ||||
| get_func_name(PyObject *func) | ||||
| char * | ||||
| PyEval_GetFuncName(PyObject *func) | ||||
| { | ||||
| 	if (PyMethod_Check(func)) | ||||
| 		return get_func_name(PyMethod_GET_FUNCTION(func)); | ||||
| 		return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func)); | ||||
| 	else if (PyFunction_Check(func)) | ||||
| 		return PyString_AsString(((PyFunctionObject*)func)->func_name); | ||||
| 	else if (PyCFunction_Check(func)) | ||||
|  | @ -3011,8 +2993,8 @@ get_func_name(PyObject *func) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static char * | ||||
| get_func_desc(PyObject *func) | ||||
| char * | ||||
| PyEval_GetFuncDesc(PyObject *func) | ||||
| { | ||||
| 	if (PyMethod_Check(func)) | ||||
| 		return "()"; | ||||
|  | @ -3136,7 +3118,8 @@ call_method(PyObject *func, PyObject *arg, PyObject *kw) | |||
| 			PyErr_Format(PyExc_TypeError, | ||||
| 				     "unbound method %s%s must be " | ||||
| 				     "called with instance as first argument", | ||||
| 				     get_func_name(func), get_func_desc(func)); | ||||
| 				     PyEval_GetFuncName(func), | ||||
| 				     PyEval_GetFuncDesc(func)); | ||||
| 			return NULL; | ||||
| 		} | ||||
| 		Py_INCREF(arg); | ||||
|  | @ -3199,7 +3182,7 @@ call_eval_code2(PyObject *func, PyObject *arg, PyObject *kw) | |||
| 		nk = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	result = eval_code2( | ||||
| 	result = PyEval_EvalCodeEx( | ||||
| 		(PyCodeObject *)PyFunction_GET_CODE(func), | ||||
| 		PyFunction_GET_GLOBALS(func), (PyObject *)NULL, | ||||
| 		&PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg), | ||||
|  | @ -3255,7 +3238,7 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk) | |||
| 		d = &PyTuple_GET_ITEM(argdefs, 0); | ||||
| 		nd = ((PyTupleObject *)argdefs)->ob_size; | ||||
| 	} | ||||
| 	return eval_code2((PyCodeObject *)co, globals, | ||||
| 	return PyEval_EvalCodeEx((PyCodeObject *)co, globals, | ||||
| 			  (PyObject *)NULL, (*pp_stack)-n, na, | ||||
| 			  (*pp_stack)-2*nk, nk, d, nd, | ||||
| 			  closure); | ||||
|  | @ -3282,8 +3265,8 @@ update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack, | |||
|                         PyErr_Format(PyExc_TypeError, | ||||
|                                      "%.200s%s got multiple values " | ||||
|                                      "for keyword argument '%.200s'", | ||||
| 				     get_func_name(func), | ||||
| 				     get_func_desc(func), | ||||
| 				     PyEval_GetFuncName(func), | ||||
| 				     PyEval_GetFuncDesc(func), | ||||
| 				     PyString_AsString(key)); | ||||
| 			Py_DECREF(key); | ||||
| 			Py_DECREF(value); | ||||
|  | @ -3356,7 +3339,7 @@ do_call(PyObject *func, PyObject ***pp_stack, int na, int nk) | |||
| 	callargs = load_args(pp_stack, na); | ||||
| 	if (callargs == NULL) | ||||
| 		goto call_fail; | ||||
| 	result = call_object(func, callargs, kwdict); | ||||
| 	result = PyObject_Call(func, callargs, kwdict); | ||||
|  call_fail: | ||||
| 	Py_XDECREF(callargs); | ||||
| 	Py_XDECREF(kwdict); | ||||
|  | @ -3378,8 +3361,8 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) | |||
| 			PyErr_Format(PyExc_TypeError, | ||||
| 				     "%s%s argument after ** " | ||||
| 				     "must be a dictionary", | ||||
| 				     get_func_name(func), | ||||
| 				     get_func_desc(func)); | ||||
| 				     PyEval_GetFuncName(func), | ||||
| 				     PyEval_GetFuncDesc(func)); | ||||
| 			goto ext_call_fail; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -3393,8 +3376,8 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) | |||
| 					PyErr_Format(PyExc_TypeError, | ||||
| 						     "%s%s argument after * " | ||||
| 						     "must be a sequence", | ||||
| 						     get_func_name(func), | ||||
| 						     get_func_desc(func)); | ||||
| 						     PyEval_GetFuncName(func), | ||||
| 						     PyEval_GetFuncDesc(func)); | ||||
| 				} | ||||
| 				goto ext_call_fail; | ||||
| 			} | ||||
|  | @ -3411,7 +3394,7 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) | |||
| 	callargs = update_star_args(na, nstar, stararg, pp_stack); | ||||
| 	if (callargs == NULL) | ||||
| 		goto ext_call_fail; | ||||
| 	result = call_object(func, callargs, kwdict); | ||||
| 	result = PyObject_Call(func, callargs, kwdict); | ||||
|       ext_call_fail: | ||||
| 	Py_XDECREF(callargs); | ||||
| 	Py_XDECREF(kwdict); | ||||
|  | @ -3632,63 +3615,25 @@ import_all_from(PyObject *locals, PyObject *v) | |||
| static PyObject * | ||||
| build_class(PyObject *methods, PyObject *bases, PyObject *name) | ||||
| { | ||||
| 	int i, n; | ||||
| 	if (!PyTuple_Check(bases)) { | ||||
| 		PyErr_SetString(PyExc_SystemError, | ||||
| 				"build_class with non-tuple bases"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	if (!PyDict_Check(methods)) { | ||||
| 		PyErr_SetString(PyExc_SystemError, | ||||
| 				"build_class with non-dictionary"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	if (!PyString_Check(name)) { | ||||
| 		PyErr_SetString(PyExc_SystemError, | ||||
| 				"build_class with non-string name"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	n = PyTuple_Size(bases); | ||||
| 	for (i = 0; i < n; i++) { | ||||
| 		PyObject *base = PyTuple_GET_ITEM(bases, i); | ||||
| 		if (!PyClass_Check(base)) { | ||||
| 			/* Call the base's *type*, if it is callable.
 | ||||
| 			   This code is a hook for Donald Beaudry's | ||||
| 			   and Jim Fulton's type extensions.  In | ||||
| 			   unextended Python it will never be triggered | ||||
| 			   since its types are not callable. | ||||
| 			   Ditto: call the bases's *class*, if it has | ||||
| 			   one.  This makes the same thing possible | ||||
| 			   without writing C code.  A true meta-object | ||||
| 			   protocol! */ | ||||
| 			PyObject *basetype = (PyObject *)base->ob_type; | ||||
| 			PyObject *callable = NULL; | ||||
| 			if (PyCallable_Check(basetype)) | ||||
| 				callable = basetype; | ||||
| 			else | ||||
| 				callable = PyObject_GetAttrString( | ||||
| 					base, "__class__"); | ||||
| 			if (callable) { | ||||
| 				PyObject *args; | ||||
| 				PyObject *newclass = NULL; | ||||
| 				args = Py_BuildValue( | ||||
| 					"(OOO)", name, bases, methods); | ||||
| 				if (args != NULL) { | ||||
| 					newclass = PyEval_CallObject( | ||||
| 						callable, args); | ||||
| 					Py_DECREF(args); | ||||
| 				} | ||||
| 				if (callable != basetype) { | ||||
| 					Py_DECREF(callable); | ||||
| 				} | ||||
| 				return newclass; | ||||
| 			} | ||||
| 			PyErr_SetString(PyExc_TypeError, | ||||
| 				"base is not a class object"); | ||||
| 			return NULL; | ||||
| 	PyObject *metaclass = NULL; | ||||
| 
 | ||||
| 	if (PyDict_Check(methods)) | ||||
| 		metaclass = PyDict_GetItemString(methods, "__metaclass__"); | ||||
| 
 | ||||
| 	if (metaclass == NULL) { | ||||
| 		if (PyTuple_Check(bases) && PyTuple_GET_SIZE(bases) > 0) | ||||
| 			metaclass = (PyObject *) | ||||
| 				PyTuple_GET_ITEM(bases, 0)->ob_type; | ||||
| 		else { | ||||
| 			PyObject *g = PyEval_GetGlobals(); | ||||
| 			if (g != NULL && PyDict_Check(g)) | ||||
| 				metaclass = PyDict_GetItemString( | ||||
| 					g, "__metaclass__"); | ||||
| 			if (metaclass == NULL) | ||||
| 				metaclass = (PyObject *) &PyClass_Type; | ||||
| 		} | ||||
| 	} | ||||
| 	return PyClass_New(bases, methods, name); | ||||
| 	return PyObject_CallFunction(metaclass, "OOO", name, bases, methods); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
|  |  | |||
|  | @ -1056,23 +1056,36 @@ static struct { | |||
|  | ||||
| 
 | ||||
| DL_EXPORT(void) | ||||
| init_exceptions(void) | ||||
| _PyExc_Init(void) | ||||
| { | ||||
|     char *modulename = "exceptions"; | ||||
|     int modnamesz = strlen(modulename); | ||||
|     int i; | ||||
|     PyObject *me, *mydict, *bltinmod, *bdict, *doc, *args; | ||||
| 
 | ||||
|     PyObject *me = Py_InitModule(modulename, functions); | ||||
|     PyObject *mydict = PyModule_GetDict(me); | ||||
|     PyObject *bltinmod = PyImport_ImportModule("__builtin__"); | ||||
|     PyObject *bdict = PyModule_GetDict(bltinmod); | ||||
|     PyObject *doc = PyString_FromString(module__doc__); | ||||
|     PyObject *args; | ||||
|     me = Py_InitModule(modulename, functions); | ||||
|     if (me == NULL) | ||||
| 	goto err; | ||||
|     mydict = PyModule_GetDict(me); | ||||
|     if (mydict == NULL) | ||||
| 	goto err; | ||||
|     bltinmod = PyImport_ImportModule("__builtin__"); | ||||
|     if (bltinmod == NULL) | ||||
| 	goto err; | ||||
|     bdict = PyModule_GetDict(bltinmod); | ||||
|     if (bdict == NULL) | ||||
| 	goto err; | ||||
|     doc = PyString_FromString(module__doc__); | ||||
|     if (doc == NULL) | ||||
| 	goto err; | ||||
| 
 | ||||
|     PyDict_SetItemString(mydict, "__doc__", doc); | ||||
|     i = PyDict_SetItemString(mydict, "__doc__", doc); | ||||
|     Py_DECREF(doc); | ||||
|     if (PyErr_Occurred()) | ||||
|     if (i < 0) { | ||||
|  err: | ||||
| 	Py_FatalError("exceptions bootstrapping error."); | ||||
| 	return; | ||||
|     } | ||||
| 
 | ||||
|     /* This is the base class of all exceptions, so make it first. */ | ||||
|     if (make_Exception(modulename) || | ||||
|  | @ -1139,7 +1152,7 @@ init_exceptions(void) | |||
| 
 | ||||
| 
 | ||||
| DL_EXPORT(void) | ||||
| fini_exceptions(void) | ||||
| _PyExc_Fini(void) | ||||
| { | ||||
|     int i; | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *); | |||
| /* XXX Perhaps the magic number should be frozen and a version field
 | ||||
|    added to the .pyc file header? */ | ||||
| /* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */ | ||||
| #define MAGIC (60420 | ((long)'\r'<<16) | ((long)'\n'<<24)) | ||||
| #define MAGIC (60717 | ((long)'\r'<<16) | ((long)'\n'<<24)) | ||||
| 
 | ||||
| /* Magic word as global; note that _PyImport_Init() can change the
 | ||||
|    value of this global to accommodate for alterations of how the | ||||
|  | @ -1968,8 +1968,11 @@ PyImport_Import(PyObject *module_name) | |||
| 	} | ||||
| 
 | ||||
| 	/* Get the __import__ function from the builtins */ | ||||
| 	if (PyDict_Check(builtins)) | ||||
| 	if (PyDict_Check(builtins)) { | ||||
| 		import = PyObject_GetItem(builtins, import_str); | ||||
| 		if (import == NULL) | ||||
| 			PyErr_SetObject(PyExc_KeyError, import_str); | ||||
| 	} | ||||
| 	else | ||||
| 		import = PyObject_GetAttr(builtins, import_str); | ||||
| 	if (import == NULL) | ||||
|  |  | |||
|  | @ -115,6 +115,9 @@ Py_Initialize(void) | |||
| 		Py_FatalError("Py_Initialize: can't make first thread"); | ||||
| 	(void) PyThreadState_Swap(tstate); | ||||
| 
 | ||||
| 	if (PyType_InitDict(&PyType_Type) < 0) | ||||
| 		Py_FatalError("Py_Initialize: can't initialize 'type'"); | ||||
| 
 | ||||
| 	interp->modules = PyDict_New(); | ||||
| 	if (interp->modules == NULL) | ||||
| 		Py_FatalError("Py_Initialize: can't make modules dictionary"); | ||||
|  | @ -144,7 +147,7 @@ Py_Initialize(void) | |||
| 	_PyImport_Init(); | ||||
| 
 | ||||
| 	/* initialize builtin exceptions */ | ||||
| 	init_exceptions(); | ||||
| 	_PyExc_Init(); | ||||
| 
 | ||||
| 	/* phase 2 of builtins */ | ||||
| 	_PyImport_FixupExtension("__builtin__", "__builtin__"); | ||||
|  | @ -238,7 +241,7 @@ Py_Finalize(void) | |||
| 	   below has been checked to make sure no exceptions are ever | ||||
| 	   raised. | ||||
| 	*/ | ||||
| 	fini_exceptions(); | ||||
| 	_PyExc_Fini(); | ||||
| 
 | ||||
| 	/* Delete current thread */ | ||||
| 	PyInterpreterState_Clear(interp); | ||||
|  | @ -1345,7 +1348,7 @@ _Py_AskYesNo(char *prompt) | |||
| { | ||||
| 	char buf[256]; | ||||
| 	 | ||||
| 	printf("%s [ny] ", prompt); | ||||
| 	fprintf(stderr, "%s [ny] ", prompt); | ||||
| 	if (fgets(buf, sizeof buf, stdin) == NULL) | ||||
| 		return 0; | ||||
| 	return buf[0] == 'y' || buf[0] == 'Y'; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Tim Peters
						Tim Peters