diff options
Diffstat (limited to 'Objects')
| -rw-r--r-- | Objects/abstract.c | 16 | ||||
| -rw-r--r-- | Objects/bufferobject.c | 2 | ||||
| -rw-r--r-- | Objects/exceptions.c | 70 | ||||
| -rw-r--r-- | Objects/intobject.c | 26 | ||||
| -rw-r--r-- | Objects/longobject.c | 69 | ||||
| -rw-r--r-- | Objects/stringobject.c | 78 | ||||
| -rw-r--r-- | Objects/typeobject.c | 84 | ||||
| -rw-r--r-- | Objects/unicodeobject.c | 34 | 
8 files changed, 229 insertions, 150 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 6e638525d7..d43bb6a40b 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -969,6 +969,22 @@ PyNumber_Float(PyObject *o)  	return PyFloat_FromString(o);  } + +PyObject * +PyNumber_ToBase(PyObject *n, int base) +{ +	PyObject *res; +	PyObject *index = PyNumber_Index(n); + +	if (!index) +		return NULL; +	assert(PyLong_Check(index)); +	res = _PyLong_Format(index, base); +	Py_DECREF(index); +	return res; +} + +  /* Operations on sequences */  int diff --git a/Objects/bufferobject.c b/Objects/bufferobject.c index dd2566820d..4b38aa2e70 100644 --- a/Objects/bufferobject.c +++ b/Objects/bufferobject.c @@ -19,7 +19,7 @@ enum buffer_t {      READ_BUFFER,      WRITE_BUFFER,      CHAR_BUFFER, -    ANY_BUFFER, +    ANY_BUFFER  };  static int diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 2fb58e2537..c9335ad838 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -314,17 +314,9 @@ SimpleExtendsException(PyExc_BaseException, Exception,  /* - *    StandardError extends Exception + *    TypeError extends Exception   */ -SimpleExtendsException(PyExc_Exception, StandardError, -    "Base class for all standard Python exceptions that do not represent\n" -    "interpreter exiting."); - - -/* - *    TypeError extends StandardError - */ -SimpleExtendsException(PyExc_StandardError, TypeError, +SimpleExtendsException(PyExc_Exception, TypeError,                         "Inappropriate argument type."); @@ -405,14 +397,14 @@ SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt,  /* - *    ImportError extends StandardError + *    ImportError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, ImportError, +SimpleExtendsException(PyExc_Exception, ImportError,            "Import can't find module, or can't find name in module.");  /* - *    EnvironmentError extends StandardError + *    EnvironmentError extends Exception   */  /* Where a function has a single filename, such as open() or some @@ -561,7 +553,7 @@ static PyMethodDef EnvironmentError_methods[] = {      {NULL}  }; -ComplexExtendsException(PyExc_StandardError, EnvironmentError, +ComplexExtendsException(PyExc_Exception, EnvironmentError,                          EnvironmentError, EnvironmentError_dealloc,                          EnvironmentError_methods, EnvironmentError_members,                          EnvironmentError_str, @@ -695,16 +687,16 @@ MiddlingExtendsException(PyExc_OSError, VMSError, EnvironmentError,  /* - *    EOFError extends StandardError + *    EOFError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, EOFError, +SimpleExtendsException(PyExc_Exception, EOFError,                         "Read beyond end of file.");  /* - *    RuntimeError extends StandardError + *    RuntimeError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, RuntimeError, +SimpleExtendsException(PyExc_Exception, RuntimeError,                         "Unspecified run-time error."); @@ -715,9 +707,9 @@ SimpleExtendsException(PyExc_RuntimeError, NotImplementedError,                         "Method or function hasn't been implemented yet.");  /* - *    NameError extends StandardError + *    NameError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, NameError, +SimpleExtendsException(PyExc_Exception, NameError,                         "Name not found globally.");  /* @@ -727,14 +719,14 @@ SimpleExtendsException(PyExc_NameError, UnboundLocalError,                         "Local name referenced but not bound to a value.");  /* - *    AttributeError extends StandardError + *    AttributeError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, AttributeError, +SimpleExtendsException(PyExc_Exception, AttributeError,                         "Attribute not found.");  /* - *    SyntaxError extends StandardError + *    SyntaxError extends Exception   */  static int @@ -884,7 +876,7 @@ static PyMemberDef SyntaxError_members[] = {      {NULL}  /* Sentinel */  }; -ComplexExtendsException(PyExc_StandardError, SyntaxError, SyntaxError, +ComplexExtendsException(PyExc_Exception, SyntaxError, SyntaxError,                          SyntaxError_dealloc, 0, SyntaxError_members,                          SyntaxError_str, "Invalid syntax."); @@ -904,9 +896,9 @@ MiddlingExtendsException(PyExc_IndentationError, TabError, SyntaxError,  /* - *    LookupError extends StandardError + *    LookupError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, LookupError, +SimpleExtendsException(PyExc_Exception, LookupError,                         "Base class for lookup errors."); @@ -943,9 +935,9 @@ ComplexExtendsException(PyExc_LookupError, KeyError, BaseException,  /* - *    ValueError extends StandardError + *    ValueError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, ValueError, +SimpleExtendsException(PyExc_Exception, ValueError,                         "Inappropriate argument value (of correct type).");  /* @@ -1558,16 +1550,16 @@ PyUnicodeTranslateError_Create(  /* - *    AssertionError extends StandardError + *    AssertionError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, AssertionError, +SimpleExtendsException(PyExc_Exception, AssertionError,                         "Assertion failed.");  /* - *    ArithmeticError extends StandardError + *    ArithmeticError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, ArithmeticError, +SimpleExtendsException(PyExc_Exception, ArithmeticError,                         "Base class for arithmetic errors."); @@ -1593,9 +1585,9 @@ SimpleExtendsException(PyExc_ArithmeticError, ZeroDivisionError,  /* - *    SystemError extends StandardError + *    SystemError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, SystemError, +SimpleExtendsException(PyExc_Exception, SystemError,      "Internal error in the Python interpreter.\n"      "\n"      "Please report this to the Python maintainer, along with the traceback,\n" @@ -1603,16 +1595,16 @@ SimpleExtendsException(PyExc_StandardError, SystemError,  /* - *    ReferenceError extends StandardError + *    ReferenceError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, ReferenceError, +SimpleExtendsException(PyExc_Exception, ReferenceError,                         "Weak ref proxy used after referent went away.");  /* - *    MemoryError extends StandardError + *    MemoryError extends Exception   */ -SimpleExtendsException(PyExc_StandardError, MemoryError, "Out of memory."); +SimpleExtendsException(PyExc_Exception, MemoryError, "Out of memory.");  /* Warning category docstrings */ @@ -1725,7 +1717,6 @@ _PyExc_Init(void)      PRE_INIT(BaseException)      PRE_INIT(Exception) -    PRE_INIT(StandardError)      PRE_INIT(TypeError)      PRE_INIT(StopIteration)      PRE_INIT(GeneratorExit) @@ -1785,7 +1776,6 @@ _PyExc_Init(void)      POST_INIT(BaseException)      POST_INIT(Exception) -    POST_INIT(StandardError)      POST_INIT(TypeError)      POST_INIT(StopIteration)      POST_INIT(GeneratorExit) diff --git a/Objects/intobject.c b/Objects/intobject.c index ad60a49b2d..14f98b941f 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -918,28 +918,6 @@ int_float(PyIntObject *v)  }  static PyObject * -int_oct(PyIntObject *v) -{ -	long x = v -> ob_ival; -	if (x < 0) -		return PyUnicode_FromFormat("-0%lo", -x); -	else if (x == 0) -		return PyUnicode_FromString("0"); -	else -		return PyUnicode_FromFormat("0%lo", x); -} - -static PyObject * -int_hex(PyIntObject *v) -{ -	long x = v -> ob_ival; -	if (x < 0) -		return PyUnicode_FromFormat("-0x%lx", -x); -	else -		return PyUnicode_FromFormat("0x%lx", x); -} - -static PyObject *  int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);  static PyObject * @@ -1064,8 +1042,8 @@ static PyNumberMethods int_as_number = {  	(unaryfunc)int_int,	/*nb_int*/  	(unaryfunc)int_long,	/*nb_long*/  	(unaryfunc)int_float,	/*nb_float*/ -	(unaryfunc)int_oct,	/*nb_oct*/ -	(unaryfunc)int_hex, 	/*nb_hex*/ +	0,			/*nb_oct*/ /* not in use */ +	0, 			/*nb_hex*/ /* not in use */  	0,			/*nb_inplace_add*/  	0,			/*nb_inplace_subtract*/  	0,			/*nb_inplace_multiply*/ diff --git a/Objects/longobject.c b/Objects/longobject.c index 1f497c4141..1f568d8eac 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -80,7 +80,6 @@ static PyLongObject *long_normalize(PyLongObject *);  static PyLongObject *mul1(PyLongObject *, wdigit);  static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit);  static PyLongObject *divrem1(PyLongObject *, digit, digit *); -static PyObject *long_format(PyObject *aa, int base);  #define SIGCHECK(PyTryBlock) \  	if (--_Py_Ticker < 0) { \ @@ -1384,7 +1383,7 @@ muladd1(PyLongObject *a, wdigit n, wdigit extra)  /* Divide long pin, w/ size digits, by non-zero digit n, storing quotient     in pout, and returning the remainder.  pin and pout point at the LSD.     It's OK for pin == pout on entry, which saves oodles of mallocs/frees in -   long_format, but that should be done with great care since longs are +   _PyLong_Format, but that should be done with great care since longs are     immutable. */  static digit @@ -1424,10 +1423,10 @@ divrem1(PyLongObject *a, digit n, digit *prem)  /* Convert a long int object to a string, using a given conversion base.     Return a string object. -   If base is 8 or 16, add the proper prefix '0' or '0x'. */ +   If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'. */ -static PyObject * -long_format(PyObject *aa, int base) +PyObject * +_PyLong_Format(PyObject *aa, int base)  {  	register PyLongObject *a = (PyLongObject *)aa;  	PyObject *str; @@ -1551,14 +1550,18 @@ long_format(PyObject *aa, int base)  		Py_DECREF(scratch);  	} -	if (base == 8) { -		if (size_a != 0) -			*--p = '0'; -	} -	else if (base == 16) { +	if (base == 16) {  		*--p = 'x';  		*--p = '0';  	} +	else if (base == 8) { +		*--p = 'o'; +		*--p = '0'; +	} +	else if (base == 2) { +		*--p = 'b'; +		*--p = '0'; +	}  	else if (base != 10) {  		*--p = '#';  		*--p = '0' + base%10; @@ -1677,9 +1680,9 @@ long_from_binary_base(char **str, int base)  PyObject *  PyLong_FromString(char *str, char **pend, int base)  { -	int sign = 1; +	int sign = 1, error_if_nonzero = 0;  	char *start, *orig_str = str; -	PyLongObject *z; +	PyLongObject *z = NULL;  	PyObject *strobj, *strrepr;  	Py_ssize_t slen; @@ -1703,10 +1706,21 @@ PyLong_FromString(char *str, char **pend, int base)  			base = 10;  		else if (str[1] == 'x' || str[1] == 'X')  			base = 16; -		else +		else if (str[1] == 'o' || str[1] == 'O')  			base = 8; +		else if (str[1] == 'b' || str[1] == 'B') +			base = 2; +		else { +			/* "old" (C-style) octal literal, now invalid. +			   it might still be zero though */ +			error_if_nonzero = 1; +			base = 10; +		}  	} -	if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) +	if (str[0] == '0' && +	    ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || +	     (base == 8  && (str[1] == 'o' || str[1] == 'O')) || +	     (base == 2  && (str[1] == 'b' || str[1] == 'B'))))  		str += 2;  	start = str; @@ -1910,6 +1924,15 @@ digit beyond the first.  	}  	if (z == NULL)  		return NULL; +	if (error_if_nonzero) { +		/* reset the base to 0, else the exception message +		   doesn't make too much sense */ +		base = 0; +		if (z->ob_size != 0) +			goto onError; +		/* there might still be other problems, therefore base +		   remains zero here for the same reason */ +	}  	if (str == start)  		goto onError;  	if (sign < 0) @@ -2130,7 +2153,7 @@ long_dealloc(PyObject *v)  static PyObject *  long_repr(PyObject *v)  { -	return long_format(v, 10); +	return _PyLong_Format(v, 10);  }  static int @@ -3489,18 +3512,6 @@ long_float(PyObject *v)  }  static PyObject * -long_oct(PyObject *v) -{ -	return long_format(v, 8); -} - -static PyObject * -long_hex(PyObject *v) -{ -	return long_format(v, 16); -} - -static PyObject *  long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);  static PyObject * @@ -3631,8 +3642,8 @@ static PyNumberMethods long_as_number = {  			long_int,	/*nb_int*/  			long_long,	/*nb_long*/  			long_float,	/*nb_float*/ -			long_oct,	/*nb_oct*/ -			long_hex,	/*nb_hex*/ +			0,		/*nb_oct*/ /* not used */ +			0,		/*nb_hex*/ /* not used */  	0,				/* nb_inplace_add */  	0,				/* nb_inplace_subtract */  	0,				/* nb_inplace_multiply */ diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 92bc95bf37..62955b9c7a 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -3265,7 +3265,7 @@ string_expandtabs(PyStringObject *self, PyObject *args)  {      const char *e, *p;      char *q; -    Py_ssize_t i, j; +    Py_ssize_t i, j, old_j;      PyObject *u;      int tabsize = 8; @@ -3273,21 +3273,38 @@ string_expandtabs(PyStringObject *self, PyObject *args)  	return NULL;      /* First pass: determine size of output string */ -    i = j = 0; +    i = j = old_j = 0;      e = PyString_AS_STRING(self) + PyString_GET_SIZE(self);      for (p = PyString_AS_STRING(self); p < e; p++)          if (*p == '\t') { -	    if (tabsize > 0) +	    if (tabsize > 0) {  		j += tabsize - (j % tabsize); +		if (old_j > j) { +		    PyErr_SetString(PyExc_OverflowError, +				    "new string is too long"); +		    return NULL; +		} +		old_j = j; +            }  	}          else {              j++;              if (*p == '\n' || *p == '\r') {                  i += j; -                j = 0; +                old_j = j = 0; +                if (i < 0) { +                    PyErr_SetString(PyExc_OverflowError, +                                    "new string is too long"); +                    return NULL; +                }              }          } +    if ((i + j) < 0) { +        PyErr_SetString(PyExc_OverflowError, "new string is too long"); +        return NULL; +    } +      /* Second pass: create output string and fill it */      u = PyString_FromStringAndSize(NULL, i + j);      if (!u) @@ -4199,12 +4216,13 @@ _PyString_FormatLong(PyObject *val, int flags, int prec, int type,  		result = val->ob_type->tp_str(val);  		break;  	case 'o': -		result = val->ob_type->tp_as_number->nb_oct(val); +		numnondigits = 2; +		result = PyNumber_ToBase(val, 8);  		break;  	case 'x':  	case 'X':  		numnondigits = 2; -		result = val->ob_type->tp_as_number->nb_hex(val); +		result = PyNumber_ToBase(val, 16);  		break;  	default:  		assert(!"'type' not in [duoxX]"); @@ -4239,32 +4257,16 @@ _PyString_FormatLong(PyObject *val, int flags, int prec, int type,  	assert(numdigits > 0);  	/* Get rid of base marker unless F_ALT */ -	if ((flags & F_ALT) == 0) { -		/* Need to skip 0x, 0X or 0. */ -		int skipped = 0; -		switch (type) { -		case 'o': -			assert(buf[sign] == '0'); -			/* If 0 is only digit, leave it alone. */ -			if (numdigits > 1) { -				skipped = 1; -				--numdigits; -			} -			break; -		case 'x': -		case 'X': -			assert(buf[sign] == '0'); -			assert(buf[sign + 1] == 'x'); -			skipped = 2; -			numnondigits -= 2; -			break; -		} -		if (skipped) { -			buf += skipped; -			len -= skipped; -			if (sign) -				buf[0] = '-'; -		} +	if (((flags & F_ALT) == 0 && +	    (type == 'o' || type == 'x' || type == 'X'))) { +		assert(buf[sign] == '0'); +		assert(buf[sign+1] == 'x' || buf[sign+1] == 'X' || +                       buf[sign+1] == 'o'); +		numnondigits -= 2; +		buf += 2; +		len -= 2; +		if (sign) +			buf[0] = '-';  		assert(len == numnondigits + numdigits);  		assert(numdigits > 0);  	} @@ -4333,9 +4335,10 @@ formatint(char *buf, size_t buflen, int flags,  		prec = 1;  	if ((flags & F_ALT) && -	    (type == 'x' || type == 'X')) { -		/* When converting under %#x or %#X, there are a number +	    (type == 'x' || type == 'X' || type == 'o')) { +		/* When converting under %#o, %#x or %#X, there are a number  		 * of issues that cause pain: +		 * - for %#o, we want a different base marker than C  		 * - when 0 is being converted, the C standard leaves off  		 *   the '0x' or '0X', which is inconsistent with other  		 *   %#x/%#X conversions and inconsistent with Python's @@ -4363,7 +4366,7 @@ formatint(char *buf, size_t buflen, int flags,  			      prec, type);  	} -	/* buf = '+'/'-'/'' + '0'/'0x'/'' + '[0-9]'*max(prec, len(x in octal)) +	/* buf = '+'/'-'/'' + '0o'/'0x'/'' + '[0-9]'*max(prec, len(x in octal))  	 * worst case buf = '-0x' + [0-9]*prec, where prec >= 11  	 */  	if (buflen <= 14 || buflen <= (size_t)3 + (size_t)prec) { @@ -4751,7 +4754,8 @@ PyString_Format(PyObject *format, PyObject *args)  				if (width > len)  					width--;  			} -			if ((flags & F_ALT) && (c == 'x' || c == 'X')) { +			if ((flags & F_ALT) && +			    (c == 'x' || c == 'X' || c == 'o')) {  				assert(pbuf[0] == '0');  				assert(pbuf[1] == c);  				if (fill != ' ') { @@ -4774,7 +4778,7 @@ PyString_Format(PyObject *format, PyObject *args)  				if (sign)  					*res++ = sign;  				if ((flags & F_ALT) && -				    (c == 'x' || c == 'X')) { +				    (c == 'x' || c == 'X' || c == 'o')) {  					assert(pbuf[0] == '0');  					assert(pbuf[1] == c);  					*res++ = *pbuf++; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 4cdb7e30d4..9d65451fca 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1,6 +1,7 @@  /* Type object implementation */  #include "Python.h" +#include "frameobject.h"  #include "structmember.h"  #include <ctype.h> @@ -3190,8 +3191,6 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)  		COPYNUM(nb_int);  		COPYNUM(nb_long);  		COPYNUM(nb_float); -		COPYNUM(nb_oct); -		COPYNUM(nb_hex);  		COPYNUM(nb_inplace_add);  		COPYNUM(nb_inplace_subtract);  		COPYNUM(nb_inplace_multiply); @@ -4510,8 +4509,6 @@ SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__")  SLOT0(slot_nb_int, "__int__")  SLOT0(slot_nb_long, "__long__")  SLOT0(slot_nb_float, "__float__") -SLOT0(slot_nb_oct, "__oct__") -SLOT0(slot_nb_hex, "__hex__")  SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O")  SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O")  SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O") @@ -5168,10 +5165,6 @@ static slotdef slotdefs[] = {  	       "long(x)"),  	UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,  	       "float(x)"), -	UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc, -	       "oct(x)"), -	UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc, -	       "hex(x)"),  	NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc,   	       "x[y:z] <==> x[y.__index__():z.__index__()]"),  	IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, @@ -5834,14 +5827,77 @@ static int  super_init(PyObject *self, PyObject *args, PyObject *kwds)  {  	superobject *su = (superobject *)self; -	PyTypeObject *type; +	PyTypeObject *type = NULL;  	PyObject *obj = NULL;  	PyTypeObject *obj_type = NULL;  	if (!_PyArg_NoKeywords("super", kwds))  		return -1; -	if (!PyArg_ParseTuple(args, "O!|O:super", &PyType_Type, &type, &obj)) +	if (!PyArg_ParseTuple(args, "|O!O:super", &PyType_Type, &type, &obj))  		return -1; + +        if (type == NULL) { +		/* Call super(), without args -- fill in from __class__ +		   and first local variable on the stack. */ +		PyFrameObject *f = PyThreadState_GET()->frame; +		PyCodeObject *co = f->f_code; +		int i, n; +		if (co == NULL) { +			PyErr_SetString(PyExc_SystemError, +					"super(): no code object"); +			return -1; +		} +		if (co->co_argcount == 0) { +			PyErr_SetString(PyExc_SystemError, +					"super(): no arguments"); +			return -1; +		} +		obj = f->f_localsplus[0]; +		if (obj == NULL) { +			PyErr_SetString(PyExc_SystemError, +					"super(): arg[0] deleted"); +			return -1; +		} +		if (co->co_freevars == NULL) +			n = 0; +		else { +			assert(PyTuple_Check(co->co_freevars)); +			n = PyTuple_GET_SIZE(co->co_freevars); +		} +		for (i = 0; i < n; i++) { +			PyObject *name = PyTuple_GET_ITEM(co->co_freevars, i); +			assert(PyUnicode_Check(name)); +                        if (!PyUnicode_CompareWithASCIIString(name, +                                                              "__class__")) { +				PyObject *cell = +					f->f_localsplus[co->co_nlocals + i]; +				if (cell == NULL || !PyCell_Check(cell)) { +					PyErr_SetString(PyExc_SystemError, +					  "super(): bad __class__ cell"); +					return -1; +				} +				type = (PyTypeObject *) PyCell_GET(cell); +				if (type == NULL) { +					PyErr_SetString(PyExc_SystemError, +					  "super(): empty __class__ cell"); +					return -1; +				} +				if (!PyType_Check(type)) { +				    PyErr_Format(PyExc_SystemError, +				      "super(): __class__ is not a type (%s)", +				      type->ob_type->tp_name); +				    return -1; +				} +				break; +			} +		} +		if (type == NULL) { +			PyErr_SetString(PyExc_SystemError, +					"super(): __class__ cell not found"); +			return -1; +		} +        } +  	if (obj == Py_None)  		obj = NULL;  	if (obj != NULL) { @@ -5858,13 +5914,19 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds)  }  PyDoc_STRVAR(super_doc, +"super() -> same as super(__class__, <first argument>)\n"  "super(type) -> unbound super object\n"  "super(type, obj) -> bound super object; requires isinstance(obj, type)\n"  "super(type, type2) -> bound super object; requires issubclass(type2, type)\n"  "Typical use to call a cooperative superclass method:\n"  "class C(B):\n"  "    def meth(self, arg):\n" -"	 super(C, self).meth(arg)"); +"	 super().meth(arg)\n" +"This works for class methods too:\n" +"class C(B):\n" +"    @classmethod\n" +"    def cmeth(cls, arg):\n" +"	 super().cmeth(arg)\n");  static int  super_traverse(PyObject *self, visitproc visit, void *arg) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 18843c060b..7310ebd026 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -6217,7 +6217,7 @@ unicode_expandtabs(PyUnicodeObject *self, PyObject *args)      Py_UNICODE *e;      Py_UNICODE *p;      Py_UNICODE *q; -    Py_ssize_t i, j; +    Py_ssize_t i, j, old_j;      PyUnicodeObject *u;      int tabsize = 8; @@ -6225,21 +6225,38 @@ unicode_expandtabs(PyUnicodeObject *self, PyObject *args)  	return NULL;      /* First pass: determine size of output string */ -    i = j = 0; +    i = j = old_j = 0;      e = self->str + self->length;      for (p = self->str; p < e; p++)          if (*p == '\t') { -	    if (tabsize > 0) +	    if (tabsize > 0) {  		j += tabsize - (j % tabsize); +		if (old_j > j) { +		    PyErr_SetString(PyExc_OverflowError, +				    "new string is too long"); +		    return NULL; +		} +		old_j = j; +	    }  	}          else {              j++;              if (*p == '\n' || *p == '\r') {                  i += j; -                j = 0; +                old_j = j = 0; +                if (i < 0) { +                    PyErr_SetString(PyExc_OverflowError, +                                    "new string is too long"); +                    return NULL; +                }              }          } +    if ((i + j) < 0) { +        PyErr_SetString(PyExc_OverflowError, "new string is too long"); +        return NULL; +    } +      /* Second pass: create output string and fill it */      u = _PyUnicode_New(i + j);      if (!u) @@ -7997,9 +8014,10 @@ formatint(Py_UNICODE *buf,      }      if ((flags & F_ALT) && -        (type == 'x' || type == 'X')) { -        /* When converting under %#x or %#X, there are a number +        (type == 'x' || type == 'X' || type == 'o')) { +        /* When converting under %#o, %#x or %#X, there are a number           * of issues that cause pain: +	 * - for %#o, we want a different base marker than C           * - when 0 is being converted, the C standard leaves off           *   the '0x' or '0X', which is inconsistent with other           *   %#x/%#X conversions and inconsistent with Python's @@ -8457,7 +8475,7 @@ PyObject *PyUnicode_Format(PyObject *format,  		if (width > len)  		    width--;  	    } -	    if ((flags & F_ALT) && (c == 'x' || c == 'X')) { +	    if ((flags & F_ALT) && (c == 'x' || c == 'X' || c == 'o')) {  		assert(pbuf[0] == '0');  		assert(pbuf[1] == c);  		if (fill != ' ') { @@ -8479,7 +8497,7 @@ PyObject *PyUnicode_Format(PyObject *format,  	    if (fill == ' ') {  		if (sign)  		    *res++ = sign; -		if ((flags & F_ALT) && (c == 'x' || c == 'X')) { +		if ((flags & F_ALT) && (c == 'x' || c == 'X' || c == 'o')) {  		    assert(pbuf[0] == '0');  		    assert(pbuf[1] == c);  		    *res++ = *pbuf++;  | 
