summaryrefslogtreecommitdiff
path: root/Objects
diff options
context:
space:
mode:
Diffstat (limited to 'Objects')
-rw-r--r--Objects/abstract.c16
-rw-r--r--Objects/bufferobject.c2
-rw-r--r--Objects/exceptions.c70
-rw-r--r--Objects/intobject.c26
-rw-r--r--Objects/longobject.c69
-rw-r--r--Objects/stringobject.c78
-rw-r--r--Objects/typeobject.c84
-rw-r--r--Objects/unicodeobject.c34
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++;