summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-02-01 23:12:20 +0200
committerSerhiy Storchaka <storchaka@gmail.com>2017-02-01 23:12:20 +0200
commit62992ef31b28b380da92b990a53e2105a4612309 (patch)
tree38393ded5ed732e6a1dae129aaf6857ea6b0de26
parentb64c0079822007c7846e7d3eb6e6f6b5d82d3a03 (diff)
downloadcpython-62992ef31b28b380da92b990a53e2105a4612309.tar.gz
Issue #20185: Converted the int class to Argument Clinic.
Based on patch by Vajrasky Kok.
-rw-r--r--Objects/clinic/longobject.c.h192
-rw-r--r--Objects/longobject.c246
2 files changed, 303 insertions, 135 deletions
diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h
new file mode 100644
index 0000000000..6a7b7debd2
--- /dev/null
+++ b/Objects/clinic/longobject.c.h
@@ -0,0 +1,192 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(int___getnewargs____doc__,
+"__getnewargs__($self, /)\n"
+"--\n"
+"\n");
+
+#define INT___GETNEWARGS___METHODDEF \
+ {"__getnewargs__", (PyCFunction)int___getnewargs__, METH_NOARGS, int___getnewargs____doc__},
+
+static PyObject *
+int___getnewargs___impl(PyObject *self);
+
+static PyObject *
+int___getnewargs__(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return int___getnewargs___impl(self);
+}
+
+PyDoc_STRVAR(int___format____doc__,
+"__format__($self, format_spec, /)\n"
+"--\n"
+"\n");
+
+#define INT___FORMAT___METHODDEF \
+ {"__format__", (PyCFunction)int___format__, METH_O, int___format____doc__},
+
+static PyObject *
+int___format___impl(PyObject *self, PyObject *format_spec);
+
+static PyObject *
+int___format__(PyObject *self, PyObject *arg)
+{
+ PyObject *return_value = NULL;
+ PyObject *format_spec;
+
+ if (!PyArg_Parse(arg, "U:__format__", &format_spec)) {
+ goto exit;
+ }
+ return_value = int___format___impl(self, format_spec);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(int___sizeof____doc__,
+"__sizeof__($self, /)\n"
+"--\n"
+"\n"
+"Returns size in memory, in bytes.");
+
+#define INT___SIZEOF___METHODDEF \
+ {"__sizeof__", (PyCFunction)int___sizeof__, METH_NOARGS, int___sizeof____doc__},
+
+static Py_ssize_t
+int___sizeof___impl(PyObject *self);
+
+static PyObject *
+int___sizeof__(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ PyObject *return_value = NULL;
+ Py_ssize_t _return_value;
+
+ _return_value = int___sizeof___impl(self);
+ if ((_return_value == -1) && PyErr_Occurred()) {
+ goto exit;
+ }
+ return_value = PyLong_FromSsize_t(_return_value);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(int_bit_length__doc__,
+"bit_length($self, /)\n"
+"--\n"
+"\n"
+"Number of bits necessary to represent self in binary.\n"
+"\n"
+">>> bin(37)\n"
+"\'0b100101\'\n"
+">>> (37).bit_length()\n"
+"6");
+
+#define INT_BIT_LENGTH_METHODDEF \
+ {"bit_length", (PyCFunction)int_bit_length, METH_NOARGS, int_bit_length__doc__},
+
+static PyObject *
+int_bit_length_impl(PyObject *self);
+
+static PyObject *
+int_bit_length(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ return int_bit_length_impl(self);
+}
+
+PyDoc_STRVAR(int_to_bytes__doc__,
+"to_bytes($self, /, length, byteorder, *, signed=False)\n"
+"--\n"
+"\n"
+"Return an array of bytes representing an integer.\n"
+"\n"
+" length\n"
+" Length of bytes object to use. An OverflowError is raised if the\n"
+" integer is not representable with the given number of bytes.\n"
+" byteorder\n"
+" The byte order used to represent the integer. If byteorder is \'big\',\n"
+" the most significant byte is at the beginning of the byte array. If\n"
+" byteorder is \'little\', the most significant byte is at the end of the\n"
+" byte array. To request the native byte order of the host system, use\n"
+" `sys.byteorder\' as the byte order value.\n"
+" signed\n"
+" Determines whether two\'s complement is used to represent the integer.\n"
+" If signed is False and a negative integer is given, an OverflowError\n"
+" is raised.");
+
+#define INT_TO_BYTES_METHODDEF \
+ {"to_bytes", (PyCFunction)int_to_bytes, METH_FASTCALL, int_to_bytes__doc__},
+
+static PyObject *
+int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder,
+ int is_signed);
+
+static PyObject *
+int_to_bytes(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"length", "byteorder", "signed", NULL};
+ static _PyArg_Parser _parser = {"nU|$p:to_bytes", _keywords, 0};
+ Py_ssize_t length;
+ PyObject *byteorder;
+ int is_signed = 0;
+
+ if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+ &length, &byteorder, &is_signed)) {
+ goto exit;
+ }
+ return_value = int_to_bytes_impl(self, length, byteorder, is_signed);
+
+exit:
+ return return_value;
+}
+
+PyDoc_STRVAR(int_from_bytes__doc__,
+"from_bytes($type, /, bytes, byteorder, *, signed=False)\n"
+"--\n"
+"\n"
+"Return the integer represented by the given array of bytes.\n"
+"\n"
+" bytes\n"
+" Holds the array of bytes to convert. The argument must either\n"
+" support the buffer protocol or be an iterable object producing bytes.\n"
+" Bytes and bytearray are examples of built-in objects that support the\n"
+" buffer protocol.\n"
+" byteorder\n"
+" The byte order used to represent the integer. If byteorder is \'big\',\n"
+" the most significant byte is at the beginning of the byte array. If\n"
+" byteorder is \'little\', the most significant byte is at the end of the\n"
+" byte array. To request the native byte order of the host system, use\n"
+" `sys.byteorder\' as the byte order value.\n"
+" signed\n"
+" Indicates whether two\'s complement is used to represent the integer.");
+
+#define INT_FROM_BYTES_METHODDEF \
+ {"from_bytes", (PyCFunction)int_from_bytes, METH_FASTCALL|METH_CLASS, int_from_bytes__doc__},
+
+static PyObject *
+int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj,
+ PyObject *byteorder, int is_signed);
+
+static PyObject *
+int_from_bytes(PyTypeObject *type, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
+{
+ PyObject *return_value = NULL;
+ static const char * const _keywords[] = {"bytes", "byteorder", "signed", NULL};
+ static _PyArg_Parser _parser = {"OU|$p:from_bytes", _keywords, 0};
+ PyObject *bytes_obj;
+ PyObject *byteorder;
+ int is_signed = 0;
+
+ if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
+ &bytes_obj, &byteorder, &is_signed)) {
+ goto exit;
+ }
+ return_value = int_from_bytes_impl(type, bytes_obj, byteorder, is_signed);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: output=a9bae2fd016e7b85 input=a9049054013a1b77]*/
diff --git a/Objects/longobject.c b/Objects/longobject.c
index c95f9467ad..f37fbd7222 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -9,6 +9,12 @@
#include <ctype.h>
#include <stddef.h>
+#include "clinic/longobject.c.h"
+/*[clinic input]
+class int "PyObject *" "&PyLong_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec0275e3422a36e3]*/
+
#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS 257
#endif
@@ -4863,10 +4869,15 @@ long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return (PyObject *)newobj;
}
+/*[clinic input]
+int.__getnewargs__
+[clinic start generated code]*/
+
static PyObject *
-long_getnewargs(PyLongObject *v)
+int___getnewargs___impl(PyObject *self)
+/*[clinic end generated code: output=839a49de3f00b61b input=5904770ab1fb8c75]*/
{
- return Py_BuildValue("(N)", _PyLong_Copy(v));
+ return Py_BuildValue("(N)", _PyLong_Copy((PyLongObject *)self));
}
static PyObject *
@@ -4879,16 +4890,20 @@ long_get1(PyLongObject *v, void *context) {
return PyLong_FromLong(1L);
}
+/*[clinic input]
+int.__format__
+
+ format_spec: unicode
+ /
+[clinic start generated code]*/
+
static PyObject *
-long__format__(PyObject *self, PyObject *args)
+int___format___impl(PyObject *self, PyObject *format_spec)
+/*[clinic end generated code: output=b4929dee9ae18689 input=e31944a9b3e428b7]*/
{
- PyObject *format_spec;
_PyUnicodeWriter writer;
int ret;
- if (!PyArg_ParseTuple(args, "U:__format__", &format_spec))
- return NULL;
-
_PyUnicodeWriter_Init(&writer);
ret = _PyLong_FormatAdvancedWriter(
&writer,
@@ -5066,31 +5081,50 @@ long_round(PyObject *self, PyObject *args)
return result;
}
-static PyObject *
-long_sizeof(PyLongObject *v)
+/*[clinic input]
+int.__sizeof__ -> Py_ssize_t
+
+Returns size in memory, in bytes.
+[clinic start generated code]*/
+
+static Py_ssize_t
+int___sizeof___impl(PyObject *self)
+/*[clinic end generated code: output=3303f008eaa6a0a5 input=9b51620c76fc4507]*/
{
Py_ssize_t res;
- res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(v))*sizeof(digit);
- return PyLong_FromSsize_t(res);
+ res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(self))*sizeof(digit);
+ return res;
}
+/*[clinic input]
+int.bit_length
+
+Number of bits necessary to represent self in binary.
+
+>>> bin(37)
+'0b100101'
+>>> (37).bit_length()
+6
+[clinic start generated code]*/
+
static PyObject *
-long_bit_length(PyLongObject *v)
+int_bit_length_impl(PyObject *self)
+/*[clinic end generated code: output=fc1977c9353d6a59 input=e4eb7a587e849a32]*/
{
PyLongObject *result, *x, *y;
Py_ssize_t ndigits;
int msd_bits;
digit msd;
- assert(v != NULL);
- assert(PyLong_Check(v));
+ assert(self != NULL);
+ assert(PyLong_Check(self));
- ndigits = Py_ABS(Py_SIZE(v));
+ ndigits = Py_ABS(Py_SIZE(self));
if (ndigits == 0)
return PyLong_FromLong(0);
- msd = v->ob_digit[ndigits-1];
+ msd = ((PyLongObject *)self)->ob_digit[ndigits-1];
msd_bits = bits_in_digit(msd);
if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT)
@@ -5127,15 +5161,6 @@ long_bit_length(PyLongObject *v)
return NULL;
}
-PyDoc_STRVAR(long_bit_length_doc,
-"int.bit_length() -> int\n\
-\n\
-Number of bits necessary to represent self in binary.\n\
->>> bin(37)\n\
-'0b100101'\n\
->>> (37).bit_length()\n\
-6");
-
#if 0
static PyObject *
long_is_finite(PyObject *v)
@@ -5144,32 +5169,38 @@ long_is_finite(PyObject *v)
}
#endif
+/*[clinic input]
+int.to_bytes
+
+ length: Py_ssize_t
+ Length of bytes object to use. An OverflowError is raised if the
+ integer is not representable with the given number of bytes.
+ byteorder: unicode
+ The byte order used to represent the integer. If byteorder is 'big',
+ the most significant byte is at the beginning of the byte array. If
+ byteorder is 'little', the most significant byte is at the end of the
+ byte array. To request the native byte order of the host system, use
+ `sys.byteorder' as the byte order value.
+ *
+ signed as is_signed: bool = False
+ Determines whether two's complement is used to represent the integer.
+ If signed is False and a negative integer is given, an OverflowError
+ is raised.
+
+Return an array of bytes representing an integer.
+[clinic start generated code]*/
static PyObject *
-long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds)
+int_to_bytes_impl(PyObject *self, Py_ssize_t length, PyObject *byteorder,
+ int is_signed)
+/*[clinic end generated code: output=89c801df114050a3 input=ddac63f4c7bf414c]*/
{
- PyObject *byteorder_str;
- PyObject *is_signed_obj = NULL;
- Py_ssize_t length;
int little_endian;
- int is_signed;
PyObject *bytes;
- static char *kwlist[] = {"length", "byteorder", "signed", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "nU|O:to_bytes", kwlist,
- &length, &byteorder_str,
- &is_signed_obj))
- return NULL;
-
- if (args != NULL && Py_SIZE(args) > 2) {
- PyErr_SetString(PyExc_TypeError,
- "'signed' is a keyword-only argument");
- return NULL;
- }
- if (_PyUnicode_EqualToASCIIString(byteorder_str, "little"))
+ if (_PyUnicode_EqualToASCIIString(byteorder, "little"))
little_endian = 1;
- else if (_PyUnicode_EqualToASCIIString(byteorder_str, "big"))
+ else if (_PyUnicode_EqualToASCIIString(byteorder, "big"))
little_endian = 0;
else {
PyErr_SetString(PyExc_ValueError,
@@ -5177,18 +5208,6 @@ long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds)
return NULL;
}
- if (is_signed_obj != NULL) {
- int cmp = PyObject_IsTrue(is_signed_obj);
- if (cmp < 0)
- return NULL;
- is_signed = cmp ? 1 : 0;
- }
- else {
- /* If the signed argument was omitted, use False as the
- default. */
- is_signed = 0;
- }
-
if (length < 0) {
PyErr_SetString(PyExc_ValueError,
"length argument must be non-negative");
@@ -5199,7 +5218,8 @@ long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds)
if (bytes == NULL)
return NULL;
- if (_PyLong_AsByteArray(v, (unsigned char *)PyBytes_AS_STRING(bytes),
+ if (_PyLong_AsByteArray((PyLongObject *)self,
+ (unsigned char *)PyBytes_AS_STRING(bytes),
length, little_endian, is_signed) < 0) {
Py_DECREF(bytes);
return NULL;
@@ -5208,51 +5228,39 @@ long_to_bytes(PyLongObject *v, PyObject *args, PyObject *kwds)
return bytes;
}
-PyDoc_STRVAR(long_to_bytes_doc,
-"int.to_bytes(length, byteorder, *, signed=False) -> bytes\n\
-\n\
-Return an array of bytes representing an integer.\n\
-\n\
-The integer is represented using length bytes. An OverflowError is\n\
-raised if the integer is not representable with the given number of\n\
-bytes.\n\
-\n\
-The byteorder argument determines the byte order used to represent the\n\
-integer. If byteorder is 'big', the most significant byte is at the\n\
-beginning of the byte array. If byteorder is 'little', the most\n\
-significant byte is at the end of the byte array. To request the native\n\
-byte order of the host system, use `sys.byteorder' as the byte order value.\n\
-\n\
-The signed keyword-only argument determines whether two's complement is\n\
-used to represent the integer. If signed is False and a negative integer\n\
-is given, an OverflowError is raised.");
+/*[clinic input]
+@classmethod
+int.from_bytes
+
+ bytes as bytes_obj: object
+ Holds the array of bytes to convert. The argument must either
+ support the buffer protocol or be an iterable object producing bytes.
+ Bytes and bytearray are examples of built-in objects that support the
+ buffer protocol.
+ byteorder: unicode
+ The byte order used to represent the integer. If byteorder is 'big',
+ the most significant byte is at the beginning of the byte array. If
+ byteorder is 'little', the most significant byte is at the end of the
+ byte array. To request the native byte order of the host system, use
+ `sys.byteorder' as the byte order value.
+ *
+ signed as is_signed: bool = False
+ Indicates whether two's complement is used to represent the integer.
+
+Return the integer represented by the given array of bytes.
+[clinic start generated code]*/
static PyObject *
-long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds)
+int_from_bytes_impl(PyTypeObject *type, PyObject *bytes_obj,
+ PyObject *byteorder, int is_signed)
+/*[clinic end generated code: output=efc5d68e31f9314f input=cdf98332b6a821b0]*/
{
- PyObject *byteorder_str;
- PyObject *is_signed_obj = NULL;
int little_endian;
- int is_signed;
- PyObject *obj;
- PyObject *bytes;
- PyObject *long_obj;
- static char *kwlist[] = {"bytes", "byteorder", "signed", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OU|O:from_bytes", kwlist,
- &obj, &byteorder_str,
- &is_signed_obj))
- return NULL;
+ PyObject *long_obj, *bytes;
- if (args != NULL && Py_SIZE(args) > 2) {
- PyErr_SetString(PyExc_TypeError,
- "'signed' is a keyword-only argument");
- return NULL;
- }
-
- if (_PyUnicode_EqualToASCIIString(byteorder_str, "little"))
+ if (_PyUnicode_EqualToASCIIString(byteorder, "little"))
little_endian = 1;
- else if (_PyUnicode_EqualToASCIIString(byteorder_str, "big"))
+ else if (_PyUnicode_EqualToASCIIString(byteorder, "big"))
little_endian = 0;
else {
PyErr_SetString(PyExc_ValueError,
@@ -5260,19 +5268,7 @@ long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
- if (is_signed_obj != NULL) {
- int cmp = PyObject_IsTrue(is_signed_obj);
- if (cmp < 0)
- return NULL;
- is_signed = cmp ? 1 : 0;
- }
- else {
- /* If the signed argument was omitted, use False as the
- default. */
- is_signed = 0;
- }
-
- bytes = PyObject_Bytes(obj);
+ bytes = PyObject_Bytes(bytes_obj);
if (bytes == NULL)
return NULL;
@@ -5289,35 +5285,16 @@ long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds)
return long_obj;
}
-PyDoc_STRVAR(long_from_bytes_doc,
-"int.from_bytes(bytes, byteorder, *, signed=False) -> int\n\
-\n\
-Return the integer represented by the given array of bytes.\n\
-\n\
-The bytes argument must be a bytes-like object (e.g. bytes or bytearray).\n\
-\n\
-The byteorder argument determines the byte order used to represent the\n\
-integer. If byteorder is 'big', the most significant byte is at the\n\
-beginning of the byte array. If byteorder is 'little', the most\n\
-significant byte is at the end of the byte array. To request the native\n\
-byte order of the host system, use `sys.byteorder' as the byte order value.\n\
-\n\
-The signed keyword-only argument indicates whether two's complement is\n\
-used to represent the integer.");
-
static PyMethodDef long_methods[] = {
{"conjugate", (PyCFunction)long_long, METH_NOARGS,
"Returns self, the complex conjugate of any int."},
- {"bit_length", (PyCFunction)long_bit_length, METH_NOARGS,
- long_bit_length_doc},
+ INT_BIT_LENGTH_METHODDEF
#if 0
{"is_finite", (PyCFunction)long_is_finite, METH_NOARGS,
"Returns always True."},
#endif
- {"to_bytes", (PyCFunction)long_to_bytes,
- METH_VARARGS|METH_KEYWORDS, long_to_bytes_doc},
- {"from_bytes", (PyCFunction)long_from_bytes,
- METH_VARARGS|METH_KEYWORDS|METH_CLASS, long_from_bytes_doc},
+ INT_TO_BYTES_METHODDEF
+ INT_FROM_BYTES_METHODDEF
{"__trunc__", (PyCFunction)long_long, METH_NOARGS,
"Truncating an Integral returns itself."},
{"__floor__", (PyCFunction)long_long, METH_NOARGS,
@@ -5327,10 +5304,9 @@ static PyMethodDef long_methods[] = {
{"__round__", (PyCFunction)long_round, METH_VARARGS,
"Rounding an Integral returns itself.\n"
"Rounding with an ndigits argument also returns an integer."},
- {"__getnewargs__", (PyCFunction)long_getnewargs, METH_NOARGS},
- {"__format__", (PyCFunction)long__format__, METH_VARARGS},
- {"__sizeof__", (PyCFunction)long_sizeof, METH_NOARGS,
- "Returns size in memory, in bytes"},
+ INT___GETNEWARGS___METHODDEF
+ INT___FORMAT___METHODDEF
+ INT___SIZEOF___METHODDEF
{NULL, NULL} /* sentinel */
};