diff -r 3544827d42e6 Modules/resource.c --- a/Modules/resource.c Tue Jan 28 12:26:24 2014 -0500 +++ b/Modules/resource.c Tue Jan 28 12:03:05 2014 -0600 @@ -18,6 +18,11 @@ #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) +/*[clinic input] +module resource +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e89d38ed52609d7c]*/ + PyDoc_STRVAR(struct_rusage__doc__, "struct_rusage: Result from getrusage.\n\n" "This object may be accessed either as a tuple of\n" @@ -55,16 +60,46 @@ static int initialized; static PyTypeObject StructRUsageType; +/*[clinic input] +resource.getrusage + + who: int + / + +[clinic start generated code]*/ + +PyDoc_STRVAR(resource_getrusage__doc__, +"sig=($module, who)"); + +#define RESOURCE_GETRUSAGE_METHODDEF \ + {"getrusage", (PyCFunction)resource_getrusage, METH_VARARGS, resource_getrusage__doc__}, + static PyObject * -resource_getrusage(PyObject *self, PyObject *args) +resource_getrusage_impl(PyModuleDef *module, int who); + +static PyObject * +resource_getrusage(PyModuleDef *module, PyObject *args) { + PyObject *return_value = NULL; int who; + + if (!PyArg_ParseTuple(args, + "i:getrusage", + &who)) + goto exit; + return_value = resource_getrusage_impl(module, who); + +exit: + return return_value; +} + +static PyObject * +resource_getrusage_impl(PyModuleDef *module, int who) +/*[clinic end generated code: output=e14bbe42e247fd84 input=5c857bcc5b9ccb1b]*/ +{ struct rusage ru; PyObject *result; - if (!PyArg_ParseTuple(args, "i:getrusage", &who)) - return NULL; - if (getrusage(who, &ru) == -1) { if (errno == EINVAL) { PyErr_SetString(PyExc_ValueError, @@ -145,14 +180,44 @@ return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max); } +/*[clinic input] +resource.getrlimit + + resource: int + / + +[clinic start generated code]*/ + +PyDoc_STRVAR(resource_getrlimit__doc__, +"sig=($module, resource)"); + +#define RESOURCE_GETRLIMIT_METHODDEF \ + {"getrlimit", (PyCFunction)resource_getrlimit, METH_VARARGS, resource_getrlimit__doc__}, + static PyObject * -resource_getrlimit(PyObject *self, PyObject *args) +resource_getrlimit_impl(PyModuleDef *module, int resource); + +static PyObject * +resource_getrlimit(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int resource; + + if (!PyArg_ParseTuple(args, + "i:getrlimit", + &resource)) + goto exit; + return_value = resource_getrlimit_impl(module, resource); + +exit: + return return_value; +} + +static PyObject * +resource_getrlimit_impl(PyModuleDef *module, int resource) +/*[clinic end generated code: output=cef80c84f30d73cc input=a697cb0004cb3c36]*/ { struct rlimit rl; - int resource; - - if (!PyArg_ParseTuple(args, "i:getrlimit", &resource)) - return NULL; if (resource < 0 || resource >= RLIM_NLIMITS) { PyErr_SetString(PyExc_ValueError, @@ -167,15 +232,47 @@ return rlimit2py(rl); } +/*[clinic input] +resource.setrlimit + + resource: int + limits: object + / + +[clinic start generated code]*/ + +PyDoc_STRVAR(resource_setrlimit__doc__, +"sig=($module, resource, limits)"); + +#define RESOURCE_SETRLIMIT_METHODDEF \ + {"setrlimit", (PyCFunction)resource_setrlimit, METH_VARARGS, resource_setrlimit__doc__}, + static PyObject * -resource_setrlimit(PyObject *self, PyObject *args) +resource_setrlimit_impl(PyModuleDef *module, int resource, PyObject *limits); + +static PyObject * +resource_setrlimit(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int resource; + PyObject *limits; + + if (!PyArg_ParseTuple(args, + "iO:setrlimit", + &resource, &limits)) + goto exit; + return_value = resource_setrlimit_impl(module, resource, limits); + +exit: + return return_value; +} + +static PyObject * +resource_setrlimit_impl(PyModuleDef *module, int resource, PyObject *limits) +/*[clinic end generated code: output=8fc397fae553b397 input=6235a6ce23b4ca75]*/ { struct rlimit rl; - int resource; - PyObject *limits, *curobj, *maxobj; - - if (!PyArg_ParseTuple(args, "iO:setrlimit", &resource, &limits)) - return NULL; + PyObject *curobj, *maxobj; if (resource < 0 || resource >= RLIM_NLIMITS) { PyErr_SetString(PyExc_ValueError, @@ -262,8 +359,28 @@ } #endif /* HAVE_PRLIMIT */ +/*[clinic input] +resource.getpagesize +[clinic start generated code]*/ + +PyDoc_STRVAR(resource_getpagesize__doc__, +"sig=($module)"); + +#define RESOURCE_GETPAGESIZE_METHODDEF \ + {"getpagesize", (PyCFunction)resource_getpagesize, METH_NOARGS, resource_getpagesize__doc__}, + static PyObject * -resource_getpagesize(PyObject *self, PyObject *unused) +resource_getpagesize_impl(PyModuleDef *module); + +static PyObject * +resource_getpagesize(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return resource_getpagesize_impl(module); +} + +static PyObject * +resource_getpagesize_impl(PyModuleDef *module) +/*[clinic end generated code: output=36216d29eeeced65 input=519cee80aaace7e6]*/ { long pagesize = 0; #if defined(HAVE_GETPAGESIZE) @@ -284,13 +401,13 @@ static struct PyMethodDef resource_methods[] = { - {"getrusage", resource_getrusage, METH_VARARGS}, - {"getrlimit", resource_getrlimit, METH_VARARGS}, + RESOURCE_GETRUSAGE_METHODDEF + RESOURCE_GETRLIMIT_METHODDEF #ifdef HAVE_PRLIMIT {"prlimit", resource_prlimit, METH_VARARGS}, #endif - {"setrlimit", resource_setrlimit, METH_VARARGS}, - {"getpagesize", resource_getpagesize, METH_NOARGS}, + RESOURCE_SETRLIMIT_METHODDEF + RESOURCE_GETPAGESIZE_METHODDEF {NULL, NULL} /* sentinel */ }; diff -r 3544827d42e6 Objects/floatobject.c --- a/Objects/floatobject.c Tue Jan 28 12:26:24 2014 -0500 +++ b/Objects/floatobject.c Tue Jan 28 12:03:05 2014 -0600 @@ -9,6 +9,10 @@ #include #include +/*[clinic input] +class float "PyObject *" "PyFloat_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=97f32f11d64908c6]*/ /* Special free list free_list is a singly-linked list of available PyFloatObjects, linked @@ -775,10 +779,33 @@ return v->ob_fval != 0.0; } +/*[clinic input] +float.is_integer + +Return True if the float is an integer. +[clinic start generated code]*/ + +PyDoc_STRVAR(float_is_integer__doc__, +"sig=($self)\n" +"Return True if the float is an integer."); + +#define FLOAT_IS_INTEGER_METHODDEF \ + {"is_integer", (PyCFunction)float_is_integer, METH_NOARGS, float_is_integer__doc__}, + static PyObject * -float_is_integer(PyObject *v) +float_is_integer_impl(PyObject *self); + +static PyObject * +float_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) { - double x = PyFloat_AsDouble(v); + return float_is_integer_impl(self); +} + +static PyObject * +float_is_integer_impl(PyObject *self) +/*[clinic end generated code: output=e0426e1b607170ed input=311810d3f777e10d]*/ +{ + double x = PyFloat_AsDouble(self); PyObject *o; if (x == -1.0 && PyErr_Occurred()) @@ -799,38 +826,130 @@ } #if 0 +/*[clinic input] +float.is_inf + +Return True if the float is positive or negative infinite. +[clinic start generated code]*/ + +PyDoc_STRVAR(float_is_inf__doc__, +"sig=($self)\n" +"Return True if the float is positive or negative infinite."); + +#define FLOAT_IS_INF_METHODDEF \ + {"is_inf", (PyCFunction)float_is_inf, METH_NOARGS, float_is_inf__doc__}, + static PyObject * -float_is_inf(PyObject *v) +float_is_inf_impl(PyObject *self); + +static PyObject * +float_is_inf(PyObject *self, PyObject *Py_UNUSED(ignored)) { - double x = PyFloat_AsDouble(v); + return float_is_inf_impl(self); +} + +static PyObject * +float_is_inf_impl(PyObject *self) +/*[clinic end generated code: output=e9c155e8d7a2697a input=dc0e6af911b2ad4d]*/ +{ + double x = PyFloat_AsDouble(self); if (x == -1.0 && PyErr_Occurred()) return NULL; return PyBool_FromLong((long)Py_IS_INFINITY(x)); } +/*[clinic input] +float.is_nan + +Return True if the float is not a number (NaN). +[clinic start generated code]*/ + +PyDoc_STRVAR(float_is_nan__doc__, +"sig=($self)\n" +"Return True if the float is not a number (NaN)."); + +#define FLOAT_IS_NAN_METHODDEF \ + {"is_nan", (PyCFunction)float_is_nan, METH_NOARGS, float_is_nan__doc__}, + static PyObject * -float_is_nan(PyObject *v) +float_is_nan_impl(PyObject *self); + +static PyObject * +float_is_nan(PyObject *self, PyObject *Py_UNUSED(ignored)) { - double x = PyFloat_AsDouble(v); + return float_is_nan_impl(self); +} + +static PyObject * +float_is_nan_impl(PyObject *self) +/*[clinic end generated code: output=6e5b443151b07b42 input=21d8976de7f3d18a]*/ +{ + double x = PyFloat_AsDouble(self); if (x == -1.0 && PyErr_Occurred()) return NULL; return PyBool_FromLong((long)Py_IS_NAN(x)); } +/*[clinic input] +float.is_finite + +Return True if the float is finite, neither infinite nor NaN. +[clinic start generated code]*/ + +PyDoc_STRVAR(float_is_finite__doc__, +"sig=($self)\n" +"Return True if the float is finite, neither infinite nor NaN."); + +#define FLOAT_IS_FINITE_METHODDEF \ + {"is_finite", (PyCFunction)float_is_finite, METH_NOARGS, float_is_finite__doc__}, + static PyObject * -float_is_finite(PyObject *v) +float_is_finite_impl(PyObject *self); + +static PyObject * +float_is_finite(PyObject *self, PyObject *Py_UNUSED(ignored)) { - double x = PyFloat_AsDouble(v); + return float_is_finite_impl(self); +} + +static PyObject * +float_is_finite_impl(PyObject *self) +/*[clinic end generated code: output=f1ab88db486d41e1 input=c4652845463686bd]*/ +{ + double x = PyFloat_AsDouble(self); if (x == -1.0 && PyErr_Occurred()) return NULL; return PyBool_FromLong((long)Py_IS_FINITE(x)); } #endif +/*[clinic input] +float.__trunc__ + +Return the Integral closest to x between 0 and x. +[clinic start generated code]*/ + +PyDoc_STRVAR(float___trunc____doc__, +"sig=($self)\n" +"Return the Integral closest to x between 0 and x."); + +#define FLOAT___TRUNC___METHODDEF \ + {"__trunc__", (PyCFunction)float___trunc__, METH_NOARGS, float___trunc____doc__}, + static PyObject * -float_trunc(PyObject *v) +float___trunc___impl(PyObject *self); + +static PyObject * +float___trunc__(PyObject *self, PyObject *Py_UNUSED(ignored)) { - double x = PyFloat_AsDouble(v); + return float___trunc___impl(self); +} + +static PyObject * +float___trunc___impl(PyObject *self) +/*[clinic end generated code: output=4efdc7a3eb91981f input=591b9ba0d650fdff]*/ +{ + double x = PyFloat_AsDouble(self); double wholepart; /* integral portion of x, rounded toward 0 */ (void)modf(x, &wholepart); @@ -1015,14 +1134,37 @@ #undef NDIGITS_MIN } +/*[clinic input] +float.conjugate + +Return self, the complex conjugate of any float. +[clinic start generated code]*/ + +PyDoc_STRVAR(float_conjugate__doc__, +"sig=($self)\n" +"Return self, the complex conjugate of any float."); + +#define FLOAT_CONJUGATE_METHODDEF \ + {"conjugate", (PyCFunction)float_conjugate, METH_NOARGS, float_conjugate__doc__}, + static PyObject * -float_float(PyObject *v) +float_conjugate_impl(PyObject *self); + +static PyObject * +float_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored)) { - if (PyFloat_CheckExact(v)) - Py_INCREF(v); + return float_conjugate_impl(self); +} + +static PyObject * +float_conjugate_impl(PyObject *self) +/*[clinic end generated code: output=d13ef30584ed1d0b input=82ba6f37a9ff91dd]*/ +{ + if (PyFloat_CheckExact(self)) + Py_INCREF(self); else - v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); - return v; + self = PyFloat_FromDouble(((PyFloatObject *)self)->ob_fval); + return self; } /* turn ASCII hex characters into integer values and vice versa */ @@ -1105,8 +1247,41 @@ of the form 4k+1. */ #define TOHEX_NBITS DBL_MANT_DIG + 3 - (DBL_MANT_DIG+2)%4 +/*[clinic input] +float.hex + +Return a hexadecimal representation of a floating-point number. + +>>> (-0.1).hex() +'-0x1.999999999999ap-4' +>>> 3.14159.hex() +'0x1.921f9f01b866ep+1' +[clinic start generated code]*/ + +PyDoc_STRVAR(float_hex__doc__, +"sig=($self)\n" +"Return a hexadecimal representation of a floating-point number.\n" +"\n" +">>> (-0.1).hex()\n" +"\'-0x1.999999999999ap-4\'\n" +">>> 3.14159.hex()\n" +"\'0x1.921f9f01b866ep+1\'"); + +#define FLOAT_HEX_METHODDEF \ + {"hex", (PyCFunction)float_hex, METH_NOARGS, float_hex__doc__}, + static PyObject * -float_hex(PyObject *v) +float_hex_impl(PyObject *self); + +static PyObject * +float_hex(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return float_hex_impl(self); +} + +static PyObject * +float_hex_impl(PyObject *self) +/*[clinic end generated code: output=b9d4b651b267df6f input=bec1271a33d47e67]*/ { double x, m; int e, shift, i, si, esign; @@ -1114,10 +1289,10 @@ trailing NUL byte. */ char s[(TOHEX_NBITS-1)/4+3]; - CONVERT_TO_DOUBLE(v, x); + CONVERT_TO_DOUBLE(self, x); if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) - return float_repr((PyFloatObject *)v); + return float_repr((PyFloatObject *)self); if (x == 0.0) { if (copysign(1.0, x) == -1.0) @@ -1158,19 +1333,39 @@ return PyUnicode_FromFormat("0x%sp%c%d", s, esign, e); } -PyDoc_STRVAR(float_hex_doc, -"float.hex() -> string\n\ -\n\ -Return a hexadecimal representation of a floating-point number.\n\ ->>> (-0.1).hex()\n\ -'-0x1.999999999999ap-4'\n\ ->>> 3.14159.hex()\n\ -'0x1.921f9f01b866ep+1'"); - /* Convert a hexadecimal string to a float. */ +/*[clinic input] +@classmethod +float.fromhex + + self: self(type="PyObject *") + string: object + / + +Create a floating-point number from a hexadecimal string. + +>>> float.fromhex('0x1.ffffp10') +2047.984375 +>>> float.fromhex('-0x1p-1074') +-5e-324 +[clinic start generated code]*/ + +PyDoc_STRVAR(float_fromhex__doc__, +"sig=($type, string)\n" +"Create a floating-point number from a hexadecimal string.\n" +"\n" +">>> float.fromhex(\'0x1.ffffp10\')\n" +"2047.984375\n" +">>> float.fromhex(\'-0x1p-1074\')\n" +"-5e-324"); + +#define FLOAT_FROMHEX_METHODDEF \ + {"fromhex", (PyCFunction)float_fromhex, METH_O|METH_CLASS, float_fromhex__doc__}, + static PyObject * -float_fromhex(PyObject *cls, PyObject *arg) +float_fromhex(PyObject *self, PyObject *string) +/*[clinic end generated code: output=f2538084a8cf0a07 input=d81049f790a912b1]*/ { PyObject *result_as_float, *result; double x; @@ -1224,7 +1419,7 @@ * exp+4*ndigits and exp-4*ndigits are within the range of a long. */ - s = _PyUnicode_AsStringAndSize(arg, &length); + s = _PyUnicode_AsStringAndSize(string, &length); if (s == NULL) return NULL; s_end = s + length; @@ -1390,7 +1585,7 @@ result_as_float = Py_BuildValue("(d)", negate ? -x : x); if (result_as_float == NULL) return NULL; - result = PyObject_CallObject(cls, result_as_float); + result = PyObject_CallObject(self, result_as_float); Py_DECREF(result_as_float); return result; @@ -1410,20 +1605,57 @@ return NULL; } -PyDoc_STRVAR(float_fromhex_doc, -"float.fromhex(string) -> float\n\ -\n\ -Create a floating-point number from a hexadecimal string.\n\ ->>> float.fromhex('0x1.ffffp10')\n\ -2047.984375\n\ ->>> float.fromhex('-0x1p-1074')\n\ --5e-324"); +/*[clinic input] +float.as_integer_ratio +Return integer ratio. + +Return a pair of integers, whose ratio is exactly equal to the original float +and with a positive denominator. + +Raise OverflowError on infinities and a ValueError on NaNs. + +>>> (10.0).as_integer_ratio() +(10, 1) +>>> (0.0).as_integer_ratio() +(0, 1) +>>> (-.25).as_integer_ratio() +(-1, 4) +[clinic start generated code]*/ + +PyDoc_STRVAR(float_as_integer_ratio__doc__, +"sig=($self)\n" +"Return integer ratio.\n" +"\n" +"Return a pair of integers, whose ratio is exactly equal to the original float\n" +"and with a positive denominator.\n" +"\n" +"Raise OverflowError on infinities and a ValueError on NaNs.\n" +"\n" +">>> (10.0).as_integer_ratio()\n" +"(10, 1)\n" +">>> (0.0).as_integer_ratio()\n" +"(0, 1)\n" +">>> (-.25).as_integer_ratio()\n" +"(-1, 4)"); + +#define FLOAT_AS_INTEGER_RATIO_METHODDEF \ + {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, float_as_integer_ratio__doc__}, static PyObject * -float_as_integer_ratio(PyObject *v, PyObject *unused) +float_as_integer_ratio_impl(PyObject *self); + +static PyObject * +float_as_integer_ratio(PyObject *self, PyObject *Py_UNUSED(ignored)) { - double self; + return float_as_integer_ratio_impl(self); +} + +static PyObject * +float_as_integer_ratio_impl(PyObject *self) +/*[clinic end generated code: output=5a763c6cad68f117 input=e21d08b4630c2e44]*/ +{ + double self_double; double float_part; int exponent; int i; @@ -1440,21 +1672,21 @@ obj = call; \ Py_DECREF(prev); \ - CONVERT_TO_DOUBLE(v, self); + CONVERT_TO_DOUBLE(self, self_double); - if (Py_IS_INFINITY(self)) { + if (Py_IS_INFINITY(self_double)) { PyErr_SetString(PyExc_OverflowError, "Cannot pass infinity to float.as_integer_ratio."); return NULL; } - if (Py_IS_NAN(self)) { + if (Py_IS_NAN(self_double)) { PyErr_SetString(PyExc_ValueError, "Cannot pass NaN to float.as_integer_ratio."); return NULL; } PyFPE_START_PROTECT("as_integer_ratio", goto error); - float_part = frexp(self, &exponent); /* self == float_part * 2**exponent exactly */ + float_part = frexp(self_double, &exponent); /* self_double == float_part * 2**exponent exactly */ PyFPE_END_PROTECT(float_part); for (i=0; i<300 && float_part != floor(float_part) ; i++) { @@ -1496,21 +1728,6 @@ return result_pair; } -PyDoc_STRVAR(float_as_integer_ratio_doc, -"float.as_integer_ratio() -> (int, int)\n" -"\n" -"Return a pair of integers, whose ratio is exactly equal to the original\n" -"float and with a positive denominator.\n" -"Raise OverflowError on infinities and a ValueError on NaNs.\n" -"\n" -">>> (10.0).as_integer_ratio()\n" -"(10, 1)\n" -">>> (0.0).as_integer_ratio()\n" -"(0, 1)\n" -">>> (-.25).as_integer_ratio()\n" -"(-1, 4)"); - - static PyObject * float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); @@ -1571,19 +1788,49 @@ static float_format_type double_format, float_format; static float_format_type detected_double_format, detected_float_format; +/*[clinic input] +@classmethod +float.__getformat__ + + typestr: object + / + +You probably don't want to use this function. + +It exists mainly to be used in Python's test suite. + +typestr must be 'double' or 'float'. This function returns whichever of +'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the +format of floating point numbers used by the C type named by typestr. +[clinic start generated code]*/ + +PyDoc_STRVAR(float___getformat____doc__, +"sig=($type, typestr)\n" +"You probably don\'t want to use this function.\n" +"\n" +"It exists mainly to be used in Python\'s test suite.\n" +"\n" +"typestr must be \'double\' or \'float\'. This function returns whichever of\n" +"\'unknown\', \'IEEE, big-endian\' or \'IEEE, little-endian\' best describes the\n" +"format of floating point numbers used by the C type named by typestr."); + +#define FLOAT___GETFORMAT___METHODDEF \ + {"__getformat__", (PyCFunction)float___getformat__, METH_O|METH_CLASS, float___getformat____doc__}, + static PyObject * -float_getformat(PyTypeObject *v, PyObject* arg) +float___getformat__(PyTypeObject *type, PyObject *typestr) +/*[clinic end generated code: output=06fd58eecb475a36 input=9804fe958a502d66]*/ { char* s; float_format_type r; - if (!PyUnicode_Check(arg)) { + if (!PyUnicode_Check(typestr)) { PyErr_Format(PyExc_TypeError, "__getformat__() argument must be string, not %.500s", - Py_TYPE(arg)->tp_name); + Py_TYPE(typestr)->tp_name); return NULL; } - s = _PyUnicode_AsString(arg); + s = _PyUnicode_AsString(typestr); if (s == NULL) return NULL; if (strcmp(s, "double") == 0) { @@ -1612,28 +1859,69 @@ } } -PyDoc_STRVAR(float_getformat_doc, -"float.__getformat__(typestr) -> string\n" +/*[clinic input] +float.__set_format__ + + typestr: str + fmt: str + / + +You probably don't want to use this function. + +It exists mainly to be used in Python's test suite. + +typestr must be 'double' or 'float'. fmt must be one of 'unknown', +'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be +one of the latter two if it appears to match the underlying C reality. + +Override the automatic determination of C-level floating point type. +This affects how floats are converted to and from binary strings. +[clinic start generated code]*/ + +PyDoc_STRVAR(float___set_format____doc__, +"sig=($self, typestr, fmt)\n" +"You probably don\'t want to use this function.\n" "\n" -"You probably don't want to use this function. It exists mainly to be\n" -"used in Python's test suite.\n" +"It exists mainly to be used in Python\'s test suite.\n" "\n" -"typestr must be 'double' or 'float'. This function returns whichever of\n" -"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n" -"format of floating point numbers used by the C type named by typestr."); +"typestr must be \'double\' or \'float\'. fmt must be one of \'unknown\',\n" +"\'IEEE, big-endian\' or \'IEEE, little-endian\', and in addition can only be\n" +"one of the latter two if it appears to match the underlying C reality.\n" +"\n" +"Override the automatic determination of C-level floating point type.\n" +"This affects how floats are converted to and from binary strings."); + +#define FLOAT___SET_FORMAT___METHODDEF \ + {"__set_format__", (PyCFunction)float___set_format__, METH_VARARGS, float___set_format____doc__}, static PyObject * -float_setformat(PyTypeObject *v, PyObject* args) +float___set_format___impl(PyObject *self, const char *typestr, const char *fmt); + +static PyObject * +float___set_format__(PyObject *self, PyObject *args) { - char* typestr; - char* format; + PyObject *return_value = NULL; + const char *typestr; + const char *fmt; + + if (!PyArg_ParseTuple(args, + "ss:__set_format__", + &typestr, &fmt)) + goto exit; + return_value = float___set_format___impl(self, typestr, fmt); + +exit: + return return_value; +} + +static PyObject * +float___set_format___impl(PyObject *self, const char *typestr, const char *fmt) +/*[clinic end generated code: output=2261f56c3c10d599 input=816f4307e5e45047]*/ +{ float_format_type f; float_format_type detected; float_format_type *p; - if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format)) - return NULL; - if (strcmp(typestr, "double") == 0) { p = &double_format; detected = detected_double_format; @@ -1649,13 +1937,13 @@ return NULL; } - if (strcmp(format, "unknown") == 0) { + if (strcmp(fmt, "unknown") == 0) { f = unknown_format; } - else if (strcmp(format, "IEEE, little-endian") == 0) { + else if (strcmp(fmt, "IEEE, little-endian") == 0) { f = ieee_little_endian_format; } - else if (strcmp(format, "IEEE, big-endian") == 0) { + else if (strcmp(fmt, "IEEE, big-endian") == 0) { f = ieee_big_endian_format; } else { @@ -1678,35 +1966,54 @@ Py_RETURN_NONE; } -PyDoc_STRVAR(float_setformat_doc, -"float.__setformat__(typestr, fmt) -> None\n" -"\n" -"You probably don't want to use this function. It exists mainly to be\n" -"used in Python's test suite.\n" -"\n" -"typestr must be 'double' or 'float'. fmt must be one of 'unknown',\n" -"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n" -"one of the latter two if it appears to match the underlying C reality.\n" -"\n" -"Override the automatic determination of C-level floating point type.\n" -"This affects how floats are converted to and from binary strings."); - static PyObject * float_getzero(PyObject *v, void *closure) { return PyFloat_FromDouble(0.0); } +/*[clinic input] +float.__format__ + + format_spec: unicode + / + +Formats the float according to format_spec. +[clinic start generated code]*/ + +PyDoc_STRVAR(float___format____doc__, +"sig=($self, format_spec)\n" +"Formats the float according to format_spec."); + +#define FLOAT___FORMAT___METHODDEF \ + {"__format__", (PyCFunction)float___format__, METH_VARARGS, float___format____doc__}, + static PyObject * -float__format__(PyObject *self, PyObject *args) +float___format___impl(PyObject *self, PyObject *format_spec); + +static PyObject * +float___format__(PyObject *self, PyObject *args) { + PyObject *return_value = NULL; PyObject *format_spec; + + if (!PyArg_ParseTuple(args, + "U:__format__", + &format_spec)) + goto exit; + return_value = float___format___impl(self, format_spec); + +exit: + return return_value; +} + +static PyObject * +float___format___impl(PyObject *self, PyObject *format_spec) +/*[clinic end generated code: output=c0392944bb650b0f input=2ece1052211fd0e6]*/ +{ _PyUnicodeWriter writer; int ret; - if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) - return NULL; - _PyUnicodeWriter_Init(&writer); ret = _PyFloat_FormatAdvancedWriter( &writer, @@ -1719,49 +2026,31 @@ return _PyUnicodeWriter_Finish(&writer); } -PyDoc_STRVAR(float__format__doc, -"float.__format__(format_spec) -> string\n" -"\n" -"Formats the float according to format_spec."); - - static PyMethodDef float_methods[] = { - {"conjugate", (PyCFunction)float_float, METH_NOARGS, - "Return self, the complex conjugate of any float."}, - {"__trunc__", (PyCFunction)float_trunc, METH_NOARGS, - "Return the Integral closest to x between 0 and x."}, + FLOAT_CONJUGATE_METHODDEF + FLOAT___TRUNC___METHODDEF {"__round__", (PyCFunction)float_round, METH_VARARGS, "Return the Integral closest to x, rounding half toward even.\n" "When an argument is passed, work like built-in round(x, ndigits)."}, - {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, - float_as_integer_ratio_doc}, - {"fromhex", (PyCFunction)float_fromhex, - METH_O|METH_CLASS, float_fromhex_doc}, - {"hex", (PyCFunction)float_hex, - METH_NOARGS, float_hex_doc}, - {"is_integer", (PyCFunction)float_is_integer, METH_NOARGS, - "Return True if the float is an integer."}, + FLOAT_AS_INTEGER_RATIO_METHODDEF + FLOAT_FROMHEX_METHODDEF + FLOAT_HEX_METHODDEF + FLOAT_IS_INTEGER_METHODDEF #if 0 - {"is_inf", (PyCFunction)float_is_inf, METH_NOARGS, - "Return True if the float is positive or negative infinite."}, - {"is_finite", (PyCFunction)float_is_finite, METH_NOARGS, - "Return True if the float is finite, neither infinite nor NaN."}, - {"is_nan", (PyCFunction)float_is_nan, METH_NOARGS, - "Return True if the float is not a number (NaN)."}, + FLOAT_IS_INF_METHODDEF + FLOAT_IS_FINITE_METHODDEF + FLOAT_IS_NAN_METHODDEF #endif {"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS}, - {"__getformat__", (PyCFunction)float_getformat, - METH_O|METH_CLASS, float_getformat_doc}, - {"__setformat__", (PyCFunction)float_setformat, - METH_VARARGS|METH_CLASS, float_setformat_doc}, - {"__format__", (PyCFunction)float__format__, - METH_VARARGS, float__format__doc}, + FLOAT___GETFORMAT___METHODDEF + FLOAT___SET_FORMAT___METHODDEF + FLOAT___FORMAT___METHODDEF {NULL, NULL} /* sentinel */ }; static PyGetSetDef float_getset[] = { {"real", - (getter)float_float, (setter)NULL, + (getter)float_conjugate_impl, (setter)NULL, "the real part of a complex number", NULL}, {"imag", @@ -1785,7 +2074,7 @@ float_divmod, /*nb_divmod*/ float_pow, /*nb_power*/ (unaryfunc)float_neg, /*nb_negative*/ - (unaryfunc)float_float, /*nb_positive*/ + (unaryfunc)float_conjugate_impl, /*nb_positive*/ (unaryfunc)float_abs, /*nb_absolute*/ (inquiry)float_bool, /*nb_bool*/ 0, /*nb_invert*/ @@ -1794,9 +2083,9 @@ 0, /*nb_and*/ 0, /*nb_xor*/ 0, /*nb_or*/ - float_trunc, /*nb_int*/ + float___trunc___impl, /*nb_int*/ 0, /*nb_reserved*/ - float_float, /*nb_float*/ + float_conjugate_impl, /*nb_float*/ 0, /* nb_inplace_add */ 0, /* nb_inplace_subtract */ 0, /* nb_inplace_multiply */ diff -r 3544827d42e6 Objects/listobject.c --- a/Objects/listobject.c Tue Jan 28 12:26:24 2014 -0500 +++ b/Objects/listobject.c Tue Jan 28 12:03:05 2014 -0600 @@ -9,6 +9,18 @@ #include /* For size_t */ #endif +/*[clinic input] +class list "PyListObject *" "PyList_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7af9b88840fe5baa]*/ + +/*[python input] +class slice_index_converter(CConverter): + type = "Py_ssize_t" + converter = "_PyEval_SliceIndex" +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=36a5d1c60a29c9f8]*/ + /* Ensure ob_item has room for at least newsize elements, and set * ob_size to newsize. If newsize > ob_size on entry, the content * of the new slots at exit is undefined heap trash; it's the caller's @@ -547,7 +559,7 @@ } static int -list_clear(PyListObject *a) +listclear(PyListObject *a) { Py_ssize_t i; PyObject **item = a->ob_item; @@ -629,7 +641,7 @@ d = n - norig; if (Py_SIZE(a) + d == 0) { Py_XDECREF(v_as_SF); - return list_clear(a); + return listclear(a); } item = a->ob_item; /* recycle the items that we are about to remove */ @@ -702,7 +714,7 @@ } if (n < 1) { - (void)list_clear(self); + (void)listclear(self); Py_INCREF(self); return (PyObject *)self; } @@ -745,41 +757,155 @@ return 0; } +/*[clinic input] +list.insert + + index: Py_ssize_t + object: object + / + +Insert object before index. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_insert__doc__, +"sig=($self, index, object)\n" +"Insert object before index."); + +#define LIST_INSERT_METHODDEF \ + {"insert", (PyCFunction)list_insert, METH_VARARGS, list_insert__doc__}, + static PyObject * -listinsert(PyListObject *self, PyObject *args) +list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object); + +static PyObject * +list_insert(PyListObject *self, PyObject *args) { - Py_ssize_t i; - PyObject *v; - if (!PyArg_ParseTuple(args, "nO:insert", &i, &v)) - return NULL; - if (ins1(self, i, v) == 0) + PyObject *return_value = NULL; + Py_ssize_t index; + PyObject *object; + + if (!PyArg_ParseTuple(args, + "nO:insert", + &index, &object)) + goto exit; + return_value = list_insert_impl(self, index, object); + +exit: + return return_value; +} + +static PyObject * +list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object) +/*[clinic end generated code: output=474023084a85b739 input=9b83a45858673f31]*/ +{ + if (ins1(self, index, object) == 0) Py_RETURN_NONE; return NULL; } +/*[clinic input] +list.clear + +Remove all items from list. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_clear__doc__, +"sig=($self)\n" +"Remove all items from list."); + +#define LIST_CLEAR_METHODDEF \ + {"clear", (PyCFunction)list_clear, METH_NOARGS, list_clear__doc__}, + static PyObject * -listclear(PyListObject *self) +list_clear_impl(PyListObject *self); + +static PyObject * +list_clear(PyListObject *self, PyObject *Py_UNUSED(ignored)) { - list_clear(self); + return list_clear_impl(self); +} + +static PyObject * +list_clear_impl(PyListObject *self) +/*[clinic end generated code: output=6a497c804fa3757e input=ca3c1646856742f6]*/ +{ + listclear(self); Py_RETURN_NONE; } +/*[clinic input] +list.copy + +Return a shallow copy of list. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_copy__doc__, +"sig=($self)\n" +"Return a shallow copy of list."); + +#define LIST_COPY_METHODDEF \ + {"copy", (PyCFunction)list_copy, METH_NOARGS, list_copy__doc__}, + static PyObject * -listcopy(PyListObject *self) +list_copy_impl(PyListObject *self); + +static PyObject * +list_copy(PyListObject *self, PyObject *Py_UNUSED(ignored)) +{ + return list_copy_impl(self); +} + +static PyObject * +list_copy_impl(PyListObject *self) +/*[clinic end generated code: output=73884d92ea3bc3e3 input=d8fb3c1e215992a5]*/ { return list_slice(self, 0, Py_SIZE(self)); } +/*[clinic input] +list.append + + object: object + / + +Append object to the end of list. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_append__doc__, +"sig=($self, object)\n" +"Append object to the end of list."); + +#define LIST_APPEND_METHODDEF \ + {"append", (PyCFunction)list_append, METH_O, list_append__doc__}, + static PyObject * -listappend(PyListObject *self, PyObject *v) +list_append(PyListObject *self, PyObject *object) +/*[clinic end generated code: output=d56957faada9e34e input=0ac3972bd94bb687]*/ { - if (app1(self, v) == 0) + if (app1(self, object) == 0) Py_RETURN_NONE; return NULL; } +/*[clinic input] +list.extend + + iterable: object + / + +Extend list by appending elements from the iterable. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_extend__doc__, +"sig=($self, iterable)\n" +"Extend list by appending elements from the iterable."); + +#define LIST_EXTEND_METHODDEF \ + {"extend", (PyCFunction)list_extend, METH_O, list_extend__doc__}, + static PyObject * -listextend(PyListObject *self, PyObject *b) +list_extend(PyListObject *self, PyObject *iterable) +/*[clinic end generated code: output=9767f557a88706a1 input=9ec5ba3a81be3a4d]*/ { PyObject *it; /* iter(v) */ Py_ssize_t m; /* size of self */ @@ -792,46 +918,47 @@ 1) lists and tuples which can use PySequence_Fast ops 2) extending self to self requires making a copy first */ - if (PyList_CheckExact(b) || PyTuple_CheckExact(b) || (PyObject *)self == b) { + if (PyList_CheckExact(iterable) || PyTuple_CheckExact(iterable) || + (PyObject *)self == iterable) { PyObject **src, **dest; - b = PySequence_Fast(b, "argument must be iterable"); - if (!b) + iterable = PySequence_Fast(iterable, "argument must be iterable"); + if (!iterable) return NULL; - n = PySequence_Fast_GET_SIZE(b); + n = PySequence_Fast_GET_SIZE(iterable); if (n == 0) { /* short circuit when b is empty */ - Py_DECREF(b); + Py_DECREF(iterable); Py_RETURN_NONE; } m = Py_SIZE(self); if (list_resize(self, m + n) == -1) { - Py_DECREF(b); + Py_DECREF(iterable); return NULL; } - /* note that we may still have self == b here for the + /* note that we may still have self == iterable here for the * situation a.extend(a), but the following code works * in that case too. Just make sure to resize self * before calling PySequence_Fast_ITEMS. */ /* populate the end of self with b's items */ - src = PySequence_Fast_ITEMS(b); + src = PySequence_Fast_ITEMS(iterable); dest = self->ob_item + m; for (i = 0; i < n; i++) { PyObject *o = src[i]; Py_INCREF(o); dest[i] = o; } - Py_DECREF(b); + Py_DECREF(iterable); Py_RETURN_NONE; } - it = PyObject_GetIter(b); + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; iternext = *it->ob_type->tp_iternext; /* Guess a result list size. */ - n = PyObject_LengthHint(b, 8); + n = PyObject_LengthHint(iterable, 8); if (n == -1) { Py_DECREF(it); return NULL; @@ -890,9 +1017,9 @@ } PyObject * -_PyList_Extend(PyListObject *self, PyObject *b) +_PyList_Extend(PyListObject *self, PyObject *iterable) { - return listextend(self, b); + return list_extend(self, iterable); } static PyObject * @@ -900,7 +1027,7 @@ { PyObject *result; - result = listextend(self, other); + result = list_extend(self, other); if (result == NULL) return result; Py_DECREF(result); @@ -908,29 +1035,65 @@ return (PyObject *)self; } +/*[clinic input] +list.pop + + index: Py_ssize_t = -1 + / + +Remove and return item at index (default last). + +Raises IndexError if list is empty or index is out of range. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_pop__doc__, +"sig=($self, index=-1)\n" +"Remove and return item at index (default last).\n" +"\n" +"Raises IndexError if list is empty or index is out of range."); + +#define LIST_POP_METHODDEF \ + {"pop", (PyCFunction)list_pop, METH_VARARGS, list_pop__doc__}, + static PyObject * -listpop(PyListObject *self, PyObject *args) +list_pop_impl(PyListObject *self, Py_ssize_t index); + +static PyObject * +list_pop(PyListObject *self, PyObject *args) { - Py_ssize_t i = -1; + PyObject *return_value = NULL; + Py_ssize_t index = -1; + + if (!PyArg_ParseTuple(args, + "|n:pop", + &index)) + goto exit; + return_value = list_pop_impl(self, index); + +exit: + return return_value; +} + +static PyObject * +list_pop_impl(PyListObject *self, Py_ssize_t index) +/*[clinic end generated code: output=eb85915917ba2dd5 input=da3c2df3a89795eb]*/ +{ PyObject *v; int status; - if (!PyArg_ParseTuple(args, "|n:pop", &i)) - return NULL; - if (Py_SIZE(self) == 0) { /* Special-case most common failure cause */ PyErr_SetString(PyExc_IndexError, "pop from empty list"); return NULL; } - if (i < 0) - i += Py_SIZE(self); - if (i < 0 || i >= Py_SIZE(self)) { + if (index < 0) + index += Py_SIZE(self); + if (index < 0 || index >= Py_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "pop index out of range"); return NULL; } - v = self->ob_item[i]; - if (i == Py_SIZE(self) - 1) { + v = self->ob_item[index]; + if (index == Py_SIZE(self) - 1) { status = list_resize(self, Py_SIZE(self) - 1); if (status >= 0) return v; /* and v now owns the reference the list had */ @@ -938,7 +1101,7 @@ return NULL; } Py_INCREF(v); - status = list_ass_slice(self, i, i+1, (PyObject *)NULL); + status = list_ass_slice(self, index, index+1, (PyObject *)NULL); if (status < 0) { Py_DECREF(v); return NULL; @@ -1905,8 +2068,47 @@ * list will be some permutation of its input state (nothing is lost or * duplicated). */ +/*[clinic input] +list.sort + + * + key: object = None + reverse: int(c_default="0") = False + +Stable sort *IN PLACE*. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_sort__doc__, +"sig=($self, *, key=None, reverse=False)\n" +"Stable sort *IN PLACE*."); + +#define LIST_SORT_METHODDEF \ + {"sort", (PyCFunction)list_sort, METH_VARARGS|METH_KEYWORDS, list_sort__doc__}, + static PyObject * -listsort(PyListObject *self, PyObject *args, PyObject *kwds) +list_sort_impl(PyListObject *self, PyObject *key, int reverse); + +static PyObject * +list_sort(PyListObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"key", "reverse", NULL}; + PyObject *key = Py_None; + int reverse = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|$Oi:sort", _keywords, + &key, &reverse)) + goto exit; + return_value = list_sort_impl(self, key, reverse); + +exit: + return return_value; +} + +static PyObject * +list_sort_impl(PyListObject *self, PyObject *key, int reverse) +/*[clinic end generated code: output=38e247a69e274a75 input=d3c4abb182537319]*/ { MergeState ms; Py_ssize_t nremaining; @@ -1916,26 +2118,13 @@ PyObject **saved_ob_item; PyObject **final_ob_item; PyObject *result = NULL; /* guilty until proved innocent */ - int reverse = 0; - PyObject *keyfunc = NULL; Py_ssize_t i; - static char *kwlist[] = {"key", "reverse", 0}; PyObject **keys; assert(self != NULL); - assert (PyList_Check(self)); - if (args != NULL) { - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:sort", - kwlist, &keyfunc, &reverse)) - return NULL; - if (Py_SIZE(args) > 0) { - PyErr_SetString(PyExc_TypeError, - "must use keyword argument for key function"); - return NULL; - } - } - if (keyfunc == Py_None) - keyfunc = NULL; + assert(PyList_Check(self)); + if (key == Py_None) + key = NULL; /* The list is temporarily made empty, so that mutations performed * by comparison functions can't affect the slice of memory we're @@ -1949,7 +2138,7 @@ self->ob_item = NULL; self->allocated = -1; /* any operation will reset it to >= 0 */ - if (keyfunc == NULL) { + if (key == NULL) { keys = NULL; lo.keys = saved_ob_item; lo.values = NULL; @@ -1965,7 +2154,7 @@ } for (i = 0; i < saved_ob_size ; i++) { - keys[i] = PyObject_CallFunctionObjArgs(keyfunc, saved_ob_item[i], + keys[i] = PyObject_CallFunctionObjArgs(key, saved_ob_item[i], NULL); if (keys[i] == NULL) { for (i=i-1 ; i>=0 ; i--) @@ -2067,7 +2256,7 @@ self->ob_item = saved_ob_item; self->allocated = saved_allocated; if (final_ob_item != NULL) { - /* we cannot use list_clear() for this because it does not + /* we cannot use listclear() for this because it does not guarantee that the list is really empty when it returns */ while (--i >= 0) { Py_XDECREF(final_ob_item[i]); @@ -2087,15 +2276,38 @@ PyErr_BadInternalCall(); return -1; } - v = listsort((PyListObject *)v, (PyObject *)NULL, (PyObject *)NULL); + v = list_sort_impl((PyListObject *)v, (PyObject *)NULL, 0); if (v == NULL) return -1; Py_DECREF(v); return 0; } +/*[clinic input] +list.reverse + +Reverse *IN PLACE*. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_reverse__doc__, +"sig=($self)\n" +"Reverse *IN PLACE*."); + +#define LIST_REVERSE_METHODDEF \ + {"reverse", (PyCFunction)list_reverse, METH_NOARGS, list_reverse__doc__}, + static PyObject * -listreverse(PyListObject *self) +list_reverse_impl(PyListObject *self); + +static PyObject * +list_reverse(PyListObject *self, PyObject *Py_UNUSED(ignored)) +{ + return list_reverse_impl(self); +} + +static PyObject * +list_reverse_impl(PyListObject *self) +/*[clinic end generated code: output=5a8502611542afad input=eefd4c3ae1bc9887]*/ { if (Py_SIZE(self) > 1) reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self)); @@ -2141,16 +2353,55 @@ return w; } +/*[clinic input] +list.index + + value: object + start: slice_index = 0 + stop: slice_index(c_default="Py_SIZE(self)") = sys.maxsize + / + +Return first index of value. + +Raises ValueError if the value is not present. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_index__doc__, +"sig=($self, value, start=0, stop=sys.maxsize)\n" +"Return first index of value.\n" +"\n" +"Raises ValueError if the value is not present."); + +#define LIST_INDEX_METHODDEF \ + {"index", (PyCFunction)list_index, METH_VARARGS, list_index__doc__}, + static PyObject * -listindex(PyListObject *self, PyObject *args) +list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start, Py_ssize_t stop); + +static PyObject * +list_index(PyListObject *self, PyObject *args) { - Py_ssize_t i, start=0, stop=Py_SIZE(self); - PyObject *v; - - if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, - _PyEval_SliceIndex, &start, - _PyEval_SliceIndex, &stop)) - return NULL; + PyObject *return_value = NULL; + PyObject *value; + Py_ssize_t start = 0; + Py_ssize_t stop = Py_SIZE(self); + + if (!PyArg_ParseTuple(args, + "O|O&O&:index", + &value, _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &stop)) + goto exit; + return_value = list_index_impl(self, value, start, stop); + +exit: + return return_value; +} + +static PyObject * +list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start, Py_ssize_t stop) +/*[clinic end generated code: output=6bbebcdc0ecfb6b3 input=3b6d2598c621f461]*/ +{ + Py_ssize_t i; + if (start < 0) { start += Py_SIZE(self); if (start < 0) @@ -2162,24 +2413,41 @@ stop = 0; } for (i = start; i < stop && i < Py_SIZE(self); i++) { - int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ); + int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ); if (cmp > 0) return PyLong_FromSsize_t(i); else if (cmp < 0) return NULL; } - PyErr_Format(PyExc_ValueError, "%R is not in list", v); + PyErr_Format(PyExc_ValueError, "%R is not in list", value); return NULL; } +/*[clinic input] +list.count + + value: object + / + +Return number of occurrences of value. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_count__doc__, +"sig=($self, value)\n" +"Return number of occurrences of value."); + +#define LIST_COUNT_METHODDEF \ + {"count", (PyCFunction)list_count, METH_O, list_count__doc__}, + static PyObject * -listcount(PyListObject *self, PyObject *v) +list_count(PyListObject *self, PyObject *value) +/*[clinic end generated code: output=54a3891921cf2e5d input=3bdc3a5e6f749565]*/ { Py_ssize_t count = 0; Py_ssize_t i; for (i = 0; i < Py_SIZE(self); i++) { - int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ); + int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ); if (cmp > 0) count++; else if (cmp < 0) @@ -2188,13 +2456,34 @@ return PyLong_FromSsize_t(count); } +/*[clinic input] +list.remove + + value: object + / + +Remove first occurrence of value. + +Raises ValueError if the value is not present. +[clinic start generated code]*/ + +PyDoc_STRVAR(list_remove__doc__, +"sig=($self, value)\n" +"Remove first occurrence of value.\n" +"\n" +"Raises ValueError if the value is not present."); + +#define LIST_REMOVE_METHODDEF \ + {"remove", (PyCFunction)list_remove, METH_O, list_remove__doc__}, + static PyObject * -listremove(PyListObject *self, PyObject *v) +list_remove(PyListObject *self, PyObject *value) +/*[clinic end generated code: output=a86e4068ef105a05 input=2dc2ba5bb2fb1f82]*/ { Py_ssize_t i; for (i = 0; i < Py_SIZE(self); i++) { - int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ); + int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ); if (cmp > 0) { if (list_ass_slice(self, i, i+1, (PyObject *)NULL) == 0) @@ -2288,15 +2577,48 @@ return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op); } +/*[clinic input] +list.__init__ + + sequence: object(c_default="NULL") = () + +Initialize list. + +Initialize new empty list if sequence is not specified, or from sequence's +items otherwise. +[clinic start generated code]*/ + +PyDoc_STRVAR(list___init____doc__, +"sig=(sequence=())\n" +"Initialize list.\n" +"\n" +"Initialize new empty list if sequence is not specified, or from sequence\'s\n" +"items otherwise."); + static int -list_init(PyListObject *self, PyObject *args, PyObject *kw) +list___init___impl(PyListObject *self, PyObject *sequence); + +static int +list___init__(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *arg = NULL; - static char *kwlist[] = {"sequence", 0}; - - if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:list", kwlist, &arg)) - return -1; - + int return_value = -1; + static char *_keywords[] = {"sequence", NULL}; + PyObject *sequence = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|O:list", _keywords, + &sequence)) + goto exit; + return_value = list___init___impl((PyListObject *)self, sequence); + +exit: + return return_value; +} + +static int +list___init___impl(PyListObject *self, PyObject *sequence) +/*[clinic end generated code: output=64fe47bec5cd9e28 input=82b44dd0c77460c7]*/ +{ /* Verify list invariants established by PyType_GenericAlloc() */ assert(0 <= Py_SIZE(self)); assert(Py_SIZE(self) <= self->allocated || self->allocated == -1); @@ -2305,10 +2627,10 @@ /* Empty previous contents */ if (self->ob_item != NULL) { - (void)list_clear(self); + (void)listclear(self); } - if (arg != NULL) { - PyObject *rv = listextend(self, arg); + if (sequence != NULL) { + PyObject *rv = list_extend(self, sequence); if (rv == NULL) return -1; Py_DECREF(rv); @@ -2316,12 +2638,33 @@ return 0; } +/*[clinic input] +list.__sizeof__ + +Return the size of list in memory, in bytes +[clinic start generated code]*/ + +PyDoc_STRVAR(list___sizeof____doc__, +"sig=($self)\n" +"Return the size of list in memory, in bytes"); + +#define LIST___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)list___sizeof__, METH_NOARGS, list___sizeof____doc__}, + static PyObject * -list_sizeof(PyListObject *self) +list___sizeof___impl(PyListObject *self); + +static PyObject * +list___sizeof__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { - Py_ssize_t res; - - res = sizeof(PyListObject) + self->allocated * sizeof(void*); + return list___sizeof___impl(self); +} + +static PyObject * +list___sizeof___impl(PyListObject *self) +/*[clinic end generated code: output=cda4d0ada0232468 input=13ea4a9d06694264]*/ +{ + Py_ssize_t res = sizeof(PyListObject) + self->allocated * sizeof(void*); return PyLong_FromSsize_t(res); } @@ -2330,56 +2673,9 @@ PyDoc_STRVAR(getitem_doc, "x.__getitem__(y) <==> x[y]"); -PyDoc_STRVAR(reversed_doc, -"L.__reversed__() -- return a reverse iterator over the list"); -PyDoc_STRVAR(sizeof_doc, -"L.__sizeof__() -- size of L in memory, in bytes"); -PyDoc_STRVAR(clear_doc, -"L.clear() -> None -- remove all items from L"); -PyDoc_STRVAR(copy_doc, -"L.copy() -> list -- a shallow copy of L"); -PyDoc_STRVAR(append_doc, -"L.append(object) -> None -- append object to end"); -PyDoc_STRVAR(extend_doc, -"L.extend(iterable) -> None -- extend list by appending elements from the iterable"); -PyDoc_STRVAR(insert_doc, -"L.insert(index, object) -- insert object before index"); -PyDoc_STRVAR(pop_doc, -"L.pop([index]) -> item -- remove and return item at index (default last).\n" -"Raises IndexError if list is empty or index is out of range."); -PyDoc_STRVAR(remove_doc, -"L.remove(value) -> None -- remove first occurrence of value.\n" -"Raises ValueError if the value is not present."); -PyDoc_STRVAR(index_doc, -"L.index(value, [start, [stop]]) -> integer -- return first index of value.\n" -"Raises ValueError if the value is not present."); -PyDoc_STRVAR(count_doc, -"L.count(value) -> integer -- return number of occurrences of value"); -PyDoc_STRVAR(reverse_doc, -"L.reverse() -- reverse *IN PLACE*"); -PyDoc_STRVAR(sort_doc, -"L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*"); static PyObject *list_subscript(PyListObject*, PyObject*); -static PyMethodDef list_methods[] = { - {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc}, - {"__reversed__",(PyCFunction)list_reversed, METH_NOARGS, reversed_doc}, - {"__sizeof__", (PyCFunction)list_sizeof, METH_NOARGS, sizeof_doc}, - {"clear", (PyCFunction)listclear, METH_NOARGS, clear_doc}, - {"copy", (PyCFunction)listcopy, METH_NOARGS, copy_doc}, - {"append", (PyCFunction)listappend, METH_O, append_doc}, - {"insert", (PyCFunction)listinsert, METH_VARARGS, insert_doc}, - {"extend", (PyCFunction)listextend, METH_O, extend_doc}, - {"pop", (PyCFunction)listpop, METH_VARARGS, pop_doc}, - {"remove", (PyCFunction)listremove, METH_O, remove_doc}, - {"index", (PyCFunction)listindex, METH_VARARGS, index_doc}, - {"count", (PyCFunction)listcount, METH_O, count_doc}, - {"reverse", (PyCFunction)listreverse, METH_NOARGS, reverse_doc}, - {"sort", (PyCFunction)listsort, METH_VARARGS | METH_KEYWORDS, sort_doc}, - {NULL, NULL} /* sentinel */ -}; - static PySequenceMethods list_as_sequence = { (lenfunc)list_length, /* sq_length */ (binaryfunc)list_concat, /* sq_concat */ @@ -2393,10 +2689,6 @@ (ssizeargfunc)list_inplace_repeat, /* sq_inplace_repeat */ }; -PyDoc_STRVAR(list_doc, -"list() -> new empty list\n" -"list(iterable) -> new list initialized from iterable's items"); - static PyObject * list_subscript(PyListObject* self, PyObject* item) { @@ -2620,50 +2912,6 @@ (objobjargproc)list_ass_subscript }; -PyTypeObject PyList_Type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "list", - sizeof(PyListObject), - 0, - (destructor)list_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)list_repr, /* tp_repr */ - 0, /* tp_as_number */ - &list_as_sequence, /* tp_as_sequence */ - &list_as_mapping, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */ - list_doc, /* tp_doc */ - (traverseproc)list_traverse, /* tp_traverse */ - (inquiry)list_clear, /* tp_clear */ - list_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - list_iter, /* tp_iter */ - 0, /* tp_iternext */ - list_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)list_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - PyObject_GC_Del, /* tp_free */ -}; - - /*********************** List Iterator **************************/ typedef struct { @@ -2872,18 +3120,41 @@ 0, }; +/*[clinic input] +list.__reversed__ + +Return a reverse iterator over the list. +[clinic start generated code]*/ + +PyDoc_STRVAR(list___reversed____doc__, +"sig=($self)\n" +"Return a reverse iterator over the list."); + +#define LIST___REVERSED___METHODDEF \ + {"__reversed__", (PyCFunction)list___reversed__, METH_NOARGS, list___reversed____doc__}, + static PyObject * -list_reversed(PyListObject *seq, PyObject *unused) +list___reversed___impl(PyListObject *self); + +static PyObject * +list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) +{ + return list___reversed___impl(self); +} + +static PyObject * +list___reversed___impl(PyListObject *self) +/*[clinic end generated code: output=54fb47190936479f input=eadb6e17f8a6a280]*/ { listreviterobject *it; it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type); if (it == NULL) return NULL; - assert(PyList_Check(seq)); - it->it_index = PyList_GET_SIZE(seq) - 1; - Py_INCREF(seq); - it->it_seq = seq; + assert(PyList_Check(self)); + it->it_index = PyList_GET_SIZE(self) - 1; + Py_INCREF(self); + it->it_seq = self; PyObject_GC_Track(it); return (PyObject *)it; } @@ -2980,3 +3251,64 @@ return NULL; return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list); } + +static PyMethodDef list_methods[] = { + {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc}, + LIST___REVERSED___METHODDEF + LIST___SIZEOF___METHODDEF + LIST_CLEAR_METHODDEF + LIST_COPY_METHODDEF + LIST_APPEND_METHODDEF + LIST_INSERT_METHODDEF + LIST_EXTEND_METHODDEF + LIST_POP_METHODDEF + LIST_REMOVE_METHODDEF + LIST_INDEX_METHODDEF + LIST_COUNT_METHODDEF + LIST_REVERSE_METHODDEF + LIST_SORT_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +PyTypeObject PyList_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "list", + sizeof(PyListObject), + 0, + (destructor)list_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)list_repr, /* tp_repr */ + 0, /* tp_as_number */ + &list_as_sequence, /* tp_as_sequence */ + &list_as_mapping, /* tp_as_mapping */ + PyObject_HashNotImplemented, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */ + list___init____doc__, /* tp_doc */ + (traverseproc)list_traverse, /* tp_traverse */ + (inquiry)listclear, /* tp_clear */ + list_richcompare, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + list_iter, /* tp_iter */ + 0, /* tp_iternext */ + list_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)list___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ + PyObject_GC_Del, /* tp_free */ +}; diff -r 3544827d42e6 Objects/typeobject.c --- a/Objects/typeobject.c Tue Jan 28 12:26:24 2014 -0500 +++ b/Objects/typeobject.c Tue Jan 28 12:03:05 2014 -0600 @@ -6,6 +6,10 @@ #include +/*[clinic input] +class type "PyObject *" "PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a479340358cb835d]*/ /* Support type attribute cache */ @@ -3980,28 +3984,91 @@ return res; } +/*[clinic input] +type.__reduce__ + + proto: int = 0 + / + +Helper for pickle +[clinic start generated code]*/ + +PyDoc_STRVAR(type___reduce____doc__, +"sig=($self, proto=0)\n" +"Helper for pickle"); + +#define TYPE___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)type___reduce__, METH_VARARGS, type___reduce____doc__}, + static PyObject * -object_reduce(PyObject *self, PyObject *args) -{ +type___reduce___impl(PyObject *self, int proto); + +static PyObject * +type___reduce__(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; int proto = 0; - if (!PyArg_ParseTuple(args, "|i:__reduce__", &proto)) - return NULL; - + if (!PyArg_ParseTuple(args, + "|i:__reduce__", + &proto)) + goto exit; + return_value = type___reduce___impl(self, proto); + +exit: + return return_value; +} + +static PyObject * +type___reduce___impl(PyObject *self, int proto) +/*[clinic end generated code: output=159ce62e46d5834e input=0a01461d1610b4fb]*/ +{ return _common_reduce(self, proto); } +/*[clinic input] +type.__reduce_ex__ + + proto: int = 0 + / + +Helper for pickle +[clinic start generated code]*/ + +PyDoc_STRVAR(type___reduce_ex____doc__, +"sig=($self, proto=0)\n" +"Helper for pickle"); + +#define TYPE___REDUCE_EX___METHODDEF \ + {"__reduce_ex__", (PyCFunction)type___reduce_ex__, METH_VARARGS, type___reduce_ex____doc__}, + static PyObject * -object_reduce_ex(PyObject *self, PyObject *args) +type___reduce_ex___impl(PyObject *self, int proto); + +static PyObject * +type___reduce_ex__(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int proto = 0; + + if (!PyArg_ParseTuple(args, + "|i:__reduce_ex__", + &proto)) + goto exit; + return_value = type___reduce_ex___impl(self, proto); + +exit: + return return_value; +} + +static PyObject * +type___reduce_ex___impl(PyObject *self, int proto) +/*[clinic end generated code: output=b38e18a31c2e9a4c input=296f921e4dd9e00d]*/ { static PyObject *objreduce; PyObject *reduce, *res; - int proto = 0; _Py_IDENTIFIER(__reduce__); - if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) - return NULL; - if (objreduce == NULL) { objreduce = _PyDict_GetItemId(PyBaseObject_Type.tp_dict, &PyId___reduce__); @@ -4057,16 +4124,48 @@ def __format__(self, format_spec): return format(str(self), format_spec) */ +/*[clinic input] +type.__format__ + + format_spec: unicode + / + +Default object formatter +[clinic start generated code]*/ + +PyDoc_STRVAR(type___format____doc__, +"sig=($self, format_spec)\n" +"Default object formatter"); + +#define TYPE___FORMAT___METHODDEF \ + {"__format__", (PyCFunction)type___format__, METH_VARARGS, type___format____doc__}, + static PyObject * -object_format(PyObject *self, PyObject *args) -{ +type___format___impl(PyObject *self, PyObject *format_spec); + +static PyObject * +type___format__(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; PyObject *format_spec; + + if (!PyArg_ParseTuple(args, + "U:__format__", + &format_spec)) + goto exit; + return_value = type___format___impl(self, format_spec); + +exit: + return return_value; +} + +static PyObject * +type___format___impl(PyObject *self, PyObject *format_spec) +/*[clinic end generated code: output=4044407781ee484d input=14d3d04e3424f9e1]*/ +{ PyObject *self_as_str = NULL; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) - return NULL; - self_as_str = PyObject_Str(self); if (self_as_str != NULL) { /* Issue 7994: If we're converting to a string, we @@ -4086,8 +4185,35 @@ return result; } +/*[clinic input] +type.__sizeof__ + +__sizeof__() -> int + +size of object in memory, in bytes +[clinic start generated code]*/ + +PyDoc_STRVAR(type___sizeof____doc__, +"sig=($self)\n" +"__sizeof__() -> int\n" +"\n" +"size of object in memory, in bytes"); + +#define TYPE___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)type___sizeof__, METH_NOARGS, type___sizeof____doc__}, + static PyObject * -object_sizeof(PyObject *self, PyObject *args) +type___sizeof___impl(PyObject *self); + +static PyObject * +type___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return type___sizeof___impl(self); +} + +static PyObject * +type___sizeof___impl(PyObject *self) +/*[clinic end generated code: output=29649de7aea286d0 input=e27180d11eec46a3]*/ { Py_ssize_t res, isize; @@ -4103,8 +4229,35 @@ /* __dir__ for generic objects: returns __dict__, __class__, and recursively up the __class__.__bases__ chain. */ +/*[clinic input] +type.__dir__ + +__dir__() -> list + +default dir() implementation +[clinic start generated code]*/ + +PyDoc_STRVAR(type___dir____doc__, +"sig=($self)\n" +"__dir__() -> list\n" +"\n" +"default dir() implementation"); + +#define TYPE___DIR___METHODDEF \ + {"__dir__", (PyCFunction)type___dir__, METH_NOARGS, type___dir____doc__}, + static PyObject * -object_dir(PyObject *self, PyObject *args) +type___dir___impl(PyObject *self); + +static PyObject * +type___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return type___dir___impl(self); +} + +static PyObject * +type___dir___impl(PyObject *self) +/*[clinic end generated code: output=2bd18d34dde5250a input=73b0631b411bee76]*/ { PyObject *result = NULL; PyObject *dict = NULL; @@ -4148,18 +4301,13 @@ } static PyMethodDef object_methods[] = { - {"__reduce_ex__", object_reduce_ex, METH_VARARGS, - PyDoc_STR("helper for pickle")}, - {"__reduce__", object_reduce, METH_VARARGS, - PyDoc_STR("helper for pickle")}, + TYPE___REDUCE_EX___METHODDEF + TYPE___REDUCE___METHODDEF {"__subclasshook__", object_subclasshook, METH_CLASS | METH_VARARGS, object_subclasshook_doc}, - {"__format__", object_format, METH_VARARGS, - PyDoc_STR("default object formatter")}, - {"__sizeof__", object_sizeof, METH_NOARGS, - PyDoc_STR("__sizeof__() -> int\nsize of object in memory, in bytes")}, - {"__dir__", object_dir, METH_NOARGS, - PyDoc_STR("__dir__() -> list\ndefault dir() implementation")}, + TYPE___FORMAT___METHODDEF + TYPE___SIZEOF___METHODDEF + TYPE___DIR___METHODDEF {0} }; diff -r 3544827d42e6 Python/marshal.c --- a/Python/marshal.c Tue Jan 28 12:26:24 2014 -0500 +++ b/Python/marshal.c Tue Jan 28 12:03:05 2014 -0600 @@ -13,6 +13,11 @@ #include "code.h" #include "marshal.h" +/*[clinic input] +module marshal +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c982b7930dee17db]*/ + #define ABS(x) ((x) < 0 ? -(x) : (x)) /* High water mark to determine when the marshalled object is dangerously deep @@ -1553,43 +1558,115 @@ } /* And an interface for Python programs... */ +/*[clinic input] +marshal.dump + + value: object + file: object + version: int(c_default="Py_MARSHAL_VERSION") = version + / + +Write the value on the open file. + +The value must be a supported type. The file must be an open file object such +as sys.stdout or returned by open() or os.popen(). It must be opened in binary +mode ('wb' or 'w+b'). + +If the value has (or contains an object that has) an unsupported type, a +ValueError exception is raised — but garbage data will also be written to the +file. The object will not be properly read back by load(). + +The version argument indicates the data format that dump should use. +[clinic start generated code]*/ + +PyDoc_STRVAR(marshal_dump__doc__, +"sig=($module, value, file, version=version)\n" +"Write the value on the open file.\n" +"\n" +"The value must be a supported type. The file must be an open file object such\n" +"as sys.stdout or returned by open() or os.popen(). It must be opened in binary\n" +"mode (\'wb\' or \'w+b\').\n" +"\n" +"If the value has (or contains an object that has) an unsupported type, a\n" +"ValueError exception is raised — but garbage data will also be written to the\n" +"file. The object will not be properly read back by load().\n" +"\n" +"The version argument indicates the data format that dump should use."); + +#define MARSHAL_DUMP_METHODDEF \ + {"dump", (PyCFunction)marshal_dump, METH_VARARGS, marshal_dump__doc__}, static PyObject * -marshal_dump(PyObject *self, PyObject *args) +marshal_dump_impl(PyModuleDef *module, PyObject *value, PyObject *file, int version); + +static PyObject * +marshal_dump(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *value; + PyObject *file; + int version = Py_MARSHAL_VERSION; + + if (!PyArg_ParseTuple(args, + "OO|i:dump", + &value, &file, &version)) + goto exit; + return_value = marshal_dump_impl(module, value, file, version); + +exit: + return return_value; +} + +static PyObject * +marshal_dump_impl(PyModuleDef *module, PyObject *value, PyObject *file, int version) +/*[clinic end generated code: output=60c06ad7d305246e input=2fe0647c0f9f1b3d]*/ { /* XXX Quick hack -- need to do this differently */ - PyObject *x; - PyObject *f; - int version = Py_MARSHAL_VERSION; PyObject *s; PyObject *res; _Py_IDENTIFIER(write); - if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version)) - return NULL; - s = PyMarshal_WriteObjectToString(x, version); + s = PyMarshal_WriteObjectToString(value, version); if (s == NULL) return NULL; - res = _PyObject_CallMethodId(f, &PyId_write, "O", s); + res = _PyObject_CallMethodId(file, &PyId_write, "O", s); Py_DECREF(s); return res; } -PyDoc_STRVAR(dump_doc, -"dump(value, file[, version])\n\ -\n\ -Write the value on the open file. The value must be a supported type.\n\ -The file must be an open file object such as sys.stdout or returned by\n\ -open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\ -\n\ -If the value has (or contains an object that has) an unsupported type, a\n\ -ValueError exception is raised — but garbage data will also be written\n\ -to the file. The object will not be properly read back by load()\n\ -\n\ -The version argument indicates the data format that dump should use."); +/*[clinic input] +marshal.load + + file: object + / + +Read one value from the open file and return it. + +If no valid value is read (e.g. because the data has a different Python +version’s incompatible marshal format), raise EOFError, ValueError or TypeError. +The file must be an open file object opened in binary mode ('rb' or 'r+b'). + +Note: If an object containing an unsupported type was marshalled with dump(), +load() will substitute None for the unmarshallable type. +[clinic start generated code]*/ + +PyDoc_STRVAR(marshal_load__doc__, +"sig=($module, file)\n" +"Read one value from the open file and return it.\n" +"\n" +"If no valid value is read (e.g. because the data has a different Python\n" +"version’s incompatible marshal format), raise EOFError, ValueError or TypeError.\n" +"The file must be an open file object opened in binary mode (\'rb\' or \'r+b\').\n" +"\n" +"Note: If an object containing an unsupported type was marshalled with dump(),\n" +"load() will substitute None for the unmarshallable type."); + +#define MARSHAL_LOAD_METHODDEF \ + {"load", (PyCFunction)marshal_load, METH_O, marshal_load__doc__}, static PyObject * -marshal_load(PyObject *self, PyObject *f) +marshal_load(PyModuleDef *module, PyObject *file) +/*[clinic end generated code: output=25c45dd32bfff3f3 input=9e187658e19392f7]*/ { PyObject *data, *result; _Py_IDENTIFIER(read); @@ -1602,19 +1679,19 @@ * This can be removed if we guarantee good error handling * for r_string() */ - data = _PyObject_CallMethodId(f, &PyId_read, "i", 0); + data = _PyObject_CallMethodId(file, &PyId_read, "i", 0); if (data == NULL) return NULL; if (!PyBytes_Check(data)) { PyErr_Format(PyExc_TypeError, - "f.read() returned not bytes but %.100s", + "file.read() returned not bytes but %.100s", data->ob_type->tp_name); result = NULL; } else { rf.depth = 0; rf.fp = NULL; - rf.readable = f; + rf.readable = file; rf.current_filename = NULL; rf.ptr = rf.end = NULL; rf.buf = NULL; @@ -1630,51 +1707,113 @@ return result; } -PyDoc_STRVAR(load_doc, -"load(file)\n\ -\n\ -Read one value from the open file and return it. If no valid value is\n\ -read (e.g. because the data has a different Python version’s\n\ -incompatible marshal format), raise EOFError, ValueError or TypeError.\n\ -The file must be an open file object opened in binary mode ('rb' or\n\ -'r+b').\n\ -\n\ -Note: If an object containing an unsupported type was marshalled with\n\ -dump(), load() will substitute None for the unmarshallable type."); +/*[clinic input] +marshal.dumps + value: object + version: int(c_default="Py_MARSHAL_VERSION") = version + / + +Return the string that would be written to a file by dump(value, file). + +The value must be a supported type. Raise a ValueError exception if +value has (or contains an object that has) an unsupported type. + +The version argument indicates the data format that dumps should use. +[clinic start generated code]*/ + +PyDoc_STRVAR(marshal_dumps__doc__, +"sig=($module, value, version=version)\n" +"Return the string that would be written to a file by dump(value, file).\n" +"\n" +"The value must be a supported type. Raise a ValueError exception if\n" +"value has (or contains an object that has) an unsupported type.\n" +"\n" +"The version argument indicates the data format that dumps should use."); + +#define MARSHAL_DUMPS_METHODDEF \ + {"dumps", (PyCFunction)marshal_dumps, METH_VARARGS, marshal_dumps__doc__}, static PyObject * -marshal_dumps(PyObject *self, PyObject *args) +marshal_dumps_impl(PyModuleDef *module, PyObject *value, int version); + +static PyObject * +marshal_dumps(PyModuleDef *module, PyObject *args) { - PyObject *x; + PyObject *return_value = NULL; + PyObject *value; int version = Py_MARSHAL_VERSION; - if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version)) - return NULL; - return PyMarshal_WriteObjectToString(x, version); + + if (!PyArg_ParseTuple(args, + "O|i:dumps", + &value, &version)) + goto exit; + return_value = marshal_dumps_impl(module, value, version); + +exit: + return return_value; } -PyDoc_STRVAR(dumps_doc, -"dumps(value[, version])\n\ -\n\ -Return the string that would be written to a file by dump(value, file).\n\ -The value must be a supported type. Raise a ValueError exception if\n\ -value has (or contains an object that has) an unsupported type.\n\ -\n\ -The version argument indicates the data format that dumps should use."); +static PyObject * +marshal_dumps_impl(PyModuleDef *module, PyObject *value, int version) +/*[clinic end generated code: output=1d9380a3a338d781 input=f050a6e6e66a8dbc]*/ +{ + return PyMarshal_WriteObjectToString(value, version); +} +/*[clinic input] +marshal.loads + + bytes: Py_buffer + / + +Convert the bytes object to a value. + +If no valid value is found, raise EOFError, ValueError or TypeError. Extra +characters in the input are ignored. +[clinic start generated code]*/ + +PyDoc_STRVAR(marshal_loads__doc__, +"sig=($module, bytes)\n" +"Convert the bytes object to a value.\n" +"\n" +"If no valid value is found, raise EOFError, ValueError or TypeError. Extra\n" +"characters in the input are ignored."); + +#define MARSHAL_LOADS_METHODDEF \ + {"loads", (PyCFunction)marshal_loads, METH_VARARGS, marshal_loads__doc__}, static PyObject * -marshal_loads(PyObject *self, PyObject *args) +marshal_loads_impl(PyModuleDef *module, Py_buffer *bytes); + +static PyObject * +marshal_loads(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer bytes = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:loads", + &bytes)) + goto exit; + return_value = marshal_loads_impl(module, &bytes); + +exit: + /* Cleanup for bytes */ + if (bytes.obj) + PyBuffer_Release(&bytes); + + return return_value; +} + +static PyObject * +marshal_loads_impl(PyModuleDef *module, Py_buffer *bytes) +/*[clinic end generated code: output=5a12f528fc4c3258 input=5090c2c130991b2f]*/ { RFILE rf; - Py_buffer p; - char *s; - Py_ssize_t n; + char *s = bytes->buf; + Py_ssize_t n = bytes->len; PyObject* result; - if (!PyArg_ParseTuple(args, "y*:loads", &p)) - return NULL; - s = p.buf; - n = p.len; rf.fp = NULL; rf.readable = NULL; rf.current_filename = NULL; @@ -1684,23 +1823,15 @@ if ((rf.refs = PyList_New(0)) == NULL) return NULL; result = read_object(&rf); - PyBuffer_Release(&p); Py_DECREF(rf.refs); return result; } -PyDoc_STRVAR(loads_doc, -"loads(bytes)\n\ -\n\ -Convert the bytes object to a value. If no valid value is found, raise\n\ -EOFError, ValueError or TypeError. Extra characters in the input are\n\ -ignored."); - static PyMethodDef marshal_methods[] = { - {"dump", marshal_dump, METH_VARARGS, dump_doc}, - {"load", marshal_load, METH_O, load_doc}, - {"dumps", marshal_dumps, METH_VARARGS, dumps_doc}, - {"loads", marshal_loads, METH_VARARGS, loads_doc}, + MARSHAL_DUMP_METHODDEF + MARSHAL_LOAD_METHODDEF + MARSHAL_DUMPS_METHODDEF + MARSHAL_LOADS_METHODDEF {NULL, NULL} /* sentinel */ };