[Python-checkins] cpython: Issue #20185: Converted the int class to Argument Clinic.

serhiy.storchaka python-checkins at python.org
Wed Feb 1 16:12:43 EST 2017


https://hg.python.org/cpython/rev/aa7ac93d23b2
changeset:   106373:aa7ac93d23b2
parent:      106370:0990a071751f
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Wed Feb 01 23:12:20 2017 +0200
summary:
  Issue #20185: Converted the int class to Argument Clinic.
Based on patch by Vajrasky Kok.

files:
  Objects/clinic/longobject.c.h |  192 ++++++++++++++++
  Objects/longobject.c          |  252 +++++++++------------
  2 files changed, 306 insertions(+), 138 deletions(-)


diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h
new file mode 100644
--- /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
--- 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 @@
     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 @@
     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 @@
     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));
-
-    ndigits = Py_ABS(Py_SIZE(v));
+    assert(self != NULL);
+    assert(PyLong_Check(self));
+
+    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 @@
     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 @@
 }
 #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 @@
         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 @@
     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 @@
     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]
+ at 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;
-
-    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"))
+    PyObject *long_obj, *bytes;
+
+    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 @@
         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 @@
     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 @@
     {"__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 */
 };
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list