]> granicus.if.org Git - python/commitdiff
Make Py_BuildValue, PyObject_CallFunction and
authorMartin v. Löwis <martin@v.loewis.de>
Fri, 14 Apr 2006 09:08:42 +0000 (09:08 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Fri, 14 Apr 2006 09:08:42 +0000 (09:08 +0000)
PyObject_CallMethod aware of PY_SSIZE_T_CLEAN.

Include/abstract.h
Include/modsupport.h
Objects/abstract.c
Objects/stringobject.c
Objects/unicodeobject.c
Python/exceptions.c
Python/getargs.c
Python/modsupport.c

index 9ec18fa1f26f302c4c9bdc4184d4567af7b4505c..3dcc0b03714025b565b7bb07552f6b842f6c079c 100644 (file)
@@ -4,6 +4,11 @@
 extern "C" {
 #endif
 
+#ifdef PY_SSIZE_T_CLEAN
+#define PyObject_CallFunction _PyObject_CallFunction_SizeT
+#define PyObject_CallMethod _PyObject_CallMethod_SizeT
+#endif
+
 /* Abstract Object Interface (many thanks to Jim Fulton) */
 
 /*
index 5471197c69013dd40ac9e76c06cc99a7a19145b6..1141d6ab5d6d25a544ccaedb4031a3afd091d937 100644 (file)
@@ -17,21 +17,11 @@ extern "C" {
 #define PyArg_ParseTupleAndKeywords    _PyArg_ParseTupleAndKeywords_SizeT
 #define PyArg_VaParse                  _PyArg_VaParse_SizeT
 #define PyArg_VaParseTupleAndKeywords  _PyArg_VaParseTupleAndKeywords_SizeT
-#define PyArg_BuildValue               _PyArg_BuildValue_SizeT
-#define PyArg_VaBuildValue             _PyArg_VaBuildValue_SizeT
+#define Py_BuildValue                  _Py_BuildValue_SizeT
+#define Py_VaBuildValue                        _Py_VaBuildValue_SizeT
 #else
-#ifdef HAVE_DECLSPEC_DLL
-PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
-PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...);
-PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
-                                                  const char *, char **, ...);
-PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
-PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list);
-PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
-                                              const char *, char **, va_list);
 PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list);
 #endif
-#endif
 
 PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...);
 PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);
index 4ef3e5a9f118ab497005f85bdb5e93ab9728afd9..7e2cdbcfa09b86d0f010400f4b7a6b07a640752d 100644 (file)
 
 #define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
 
+#ifdef HAVE_DECLSPEC_DLL
+PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable_object,
+                                                   char *format, ...);
+PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *o, char *m,
+                                                 char *format, ...);
+#endif
+
+
 /* Shorthands to return certain errors */
 
 static PyObject *
@@ -1800,11 +1808,37 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
        return NULL;
 }
 
+static PyObject*
+call_function_tail(PyObject *callable, PyObject *args)
+{
+       PyObject *retval;
+
+       if (args == NULL)
+               return NULL;
+
+       if (!PyTuple_Check(args)) {
+               PyObject *a;
+
+               a = PyTuple_New(1);
+               if (a == NULL) {
+                       Py_DECREF(args);
+                       return NULL;
+               }
+               PyTuple_SET_ITEM(a, 0, args);
+               args = a;
+       }
+       retval = PyObject_Call(callable, args, NULL);
+
+       Py_DECREF(args);
+
+       return retval;
+}
+
 PyObject *
 PyObject_CallFunction(PyObject *callable, char *format, ...)
 {
        va_list va;
-       PyObject *args, *retval;
+       PyObject *args;
 
        if (callable == NULL)
                return null_error();
@@ -1817,31 +1851,34 @@ PyObject_CallFunction(PyObject *callable, char *format, ...)
        else
                args = PyTuple_New(0);
 
-       if (args == NULL)
-               return NULL;
+       return call_function_tail(callable, args);
+}
 
-       if (!PyTuple_Check(args)) {
-               PyObject *a;
+PyObject *
+_PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...)
+{
+       va_list va;
+       PyObject *args;
 
-               a = PyTuple_New(1);
-               if (a == NULL)
-                       return NULL;
-               if (PyTuple_SetItem(a, 0, args) < 0)
-                       return NULL;
-               args = a;
-       }
-       retval = PyObject_Call(callable, args, NULL);
+       if (callable == NULL)
+               return null_error();
 
-       Py_DECREF(args);
+       if (format && *format) {
+               va_start(va, format);
+               args = _Py_VaBuildValue_SizeT(format, va);
+               va_end(va);
+       }
+       else
+               args = PyTuple_New(0);
 
-       return retval;
+       return call_function_tail(callable, args);
 }
 
 PyObject *
 PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
 {
        va_list va;
-       PyObject *args = NULL;
+       PyObject *args;
        PyObject *func = NULL;
        PyObject *retval = NULL;
 
@@ -1867,24 +1904,49 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
        else
                args = PyTuple_New(0);
 
-       if (!args)
-               goto exit;
+       retval = call_function_tail(func, args);
 
-       if (!PyTuple_Check(args)) {
-               PyObject *a;
+  exit:
+       /* args gets consumed in call_function_tail */
+       Py_XDECREF(func);
 
-               a = PyTuple_New(1);
-               if (a == NULL)
-                       goto exit;
-               if (PyTuple_SetItem(a, 0, args) < 0)
-                       goto exit;
-               args = a;
+       return retval;
+}
+
+PyObject *
+_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+{
+       va_list va;
+       PyObject *args;
+       PyObject *func = NULL;
+       PyObject *retval = NULL;
+
+       if (o == NULL || name == NULL)
+               return null_error();
+
+       func = PyObject_GetAttrString(o, name);
+       if (func == NULL) {
+               PyErr_SetString(PyExc_AttributeError, name);
+               return 0;
+       }
+
+       if (!PyCallable_Check(func)) {
+               type_error("call of non-callable attribute"); 
+               goto exit;
+       }
+
+       if (format && *format) {
+               va_start(va, format);
+               args = _Py_VaBuildValue_SizeT(format, va);
+               va_end(va);
        }
+       else
+               args = PyTuple_New(0);
 
-       retval = PyObject_Call(func, args, NULL);
+       retval = call_function_tail(func, args);
 
   exit:
-       Py_XDECREF(args);
+       /* args gets consumed in call_function_tail */
        Py_XDECREF(func);
 
        return retval;
index b399415e4e206f8aa08e4b230b406f90760b7bd7..99cadca8fc87da1dd39129a46a20bb4c05f4946e 100644 (file)
@@ -1,5 +1,6 @@
 /* String object implementation */
 
+#define PY_SSIZE_T_CLEAN
 #include "Python.h"
 
 #include <ctype.h>
index 668d6e4d6886c6e282941bacbb6f83a5e5e8b908..f6996c71eaaa2b3b88d1a5c3156592bfd4eceff8 100644 (file)
@@ -36,6 +36,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 */
 
+#define PY_SSIZE_T_CLEAN
 #include "Python.h"
 
 #include "unicodeobject.h"
index e5f8f05cfb70df8448ce86939e362df84fab8405..5c824e650cf9c73001ec0b7186dbef4d87f301d1 100644 (file)
@@ -14,6 +14,7 @@
  * Copyright (c) 1998-2000 by Secret Labs AB.  All rights reserved.
  */
 
+#define PY_SSIZE_T_CLEAN
 #include "Python.h"
 #include "osdefs.h"
 
@@ -1450,8 +1451,8 @@ PyObject * PyUnicodeDecodeError_Create(
        assert(length < INT_MAX);
        assert(start < INT_MAX);
        assert(end < INT_MAX);
-    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#iis",
-       encoding, object, (int)length, (int)start, (int)end, reason);
+    return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
+       encoding, object, length, start, end, reason);
 }
 
 
@@ -1565,7 +1566,7 @@ PyObject * PyUnicodeTranslateError_Create(
        const Py_UNICODE *object, Py_ssize_t length,
        Py_ssize_t start, Py_ssize_t end, const char *reason)
 {
-    return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#iis",
+    return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
        object, length, start, end, reason);
 }
 #endif
index 5908e6beba656740529c8cb0a9ba7a1c65ecb979..f5e21546fc1fd4de0fd9dfce169c905e9265fa70 100644 (file)
@@ -18,6 +18,18 @@ int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
 int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
                                const char *, char **, va_list);
 
+#ifdef HAVE_DECLSPEC_DLL
+/* Export functions */
+PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+                                                  const char *, char **, ...);
+PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list);
+PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+                                              const char *, char **, va_list);
+#endif
+
 #define FLAG_COMPAT 1
 #define FLAG_SIZE_T 2
 
index 65480c823a52f7d095bf47037d43c432b5a4edd7..dd7454cf9f4a303715c77b05c844b2e06a5bdfdf 100644 (file)
@@ -3,8 +3,14 @@
 
 #include "Python.h"
 
+#define FLAG_SIZE_T 1
 typedef double va_double;
 
+static PyObject *va_build_value(const char *, va_list, int);
+#ifdef HAVE_DECLSPEC_DLL
+PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+#endif
+
 /* Package context -- the full module name for package imports */
 char *_Py_PackageContext = NULL;
 
@@ -146,14 +152,14 @@ countformat(const char *format, int endchar)
 /* Generic function to create a value -- the inverse of getargs() */
 /* After an original idea and first implementation by Steven Miale */
 
-static PyObject *do_mktuple(const char**, va_list *, int, int);
-static PyObject *do_mklist(const char**, va_list *, int, int);
-static PyObject *do_mkdict(const char**, va_list *, int, int);
-static PyObject *do_mkvalue(const char**, va_list *);
+static PyObject *do_mktuple(const char**, va_list *, int, int, int);
+static PyObject *do_mklist(const char**, va_list *, int, int, int);
+static PyObject *do_mkdict(const char**, va_list *, int, int, int);
+static PyObject *do_mkvalue(const char**, va_list *, int);
 
 
 static PyObject *
-do_mkdict(const char **p_format, va_list *p_va, int endchar, int n)
+do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
 {
        PyObject *d;
        int i;
@@ -167,13 +173,13 @@ do_mkdict(const char **p_format, va_list *p_va, int endchar, int n)
        for (i = 0; i < n; i+= 2) {
                PyObject *k, *v;
                int err;
-               k = do_mkvalue(p_format, p_va);
+               k = do_mkvalue(p_format, p_va, flags);
                if (k == NULL) {
                        itemfailed = 1;
                        Py_INCREF(Py_None);
                        k = Py_None;
                }
-               v = do_mkvalue(p_format, p_va);
+               v = do_mkvalue(p_format, p_va, flags);
                if (v == NULL) {
                        itemfailed = 1;
                        Py_INCREF(Py_None);
@@ -199,7 +205,7 @@ do_mkdict(const char **p_format, va_list *p_va, int endchar, int n)
 }
 
 static PyObject *
-do_mklist(const char **p_format, va_list *p_va, int endchar, int n)
+do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
 {
        PyObject *v;
        int i;
@@ -212,7 +218,7 @@ do_mklist(const char **p_format, va_list *p_va, int endchar, int n)
        /* Note that we can't bail immediately on error as this will leak
           refcounts on any 'N' arguments. */
        for (i = 0; i < n; i++) {
-               PyObject *w = do_mkvalue(p_format, p_va);
+               PyObject *w = do_mkvalue(p_format, p_va, flags);
                if (w == NULL) {
                        itemfailed = 1;
                        Py_INCREF(Py_None);
@@ -249,7 +255,7 @@ _ustrlen(Py_UNICODE *u)
 #endif
 
 static PyObject *
-do_mktuple(const char **p_format, va_list *p_va, int endchar, int n)
+do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
 {
        PyObject *v;
        int i;
@@ -261,7 +267,7 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n)
        /* Note that we can't bail immediately on error as this will leak
           refcounts on any 'N' arguments. */
        for (i = 0; i < n; i++) {
-               PyObject *w = do_mkvalue(p_format, p_va);
+               PyObject *w = do_mkvalue(p_format, p_va, flags);
                if (w == NULL) {
                        itemfailed = 1;
                        Py_INCREF(Py_None);
@@ -286,21 +292,21 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n)
 }
 
 static PyObject *
-do_mkvalue(const char **p_format, va_list *p_va)
+do_mkvalue(const char **p_format, va_list *p_va, int flags)
 {
        for (;;) {
                switch (*(*p_format)++) {
                case '(':
                        return do_mktuple(p_format, p_va, ')',
-                                         countformat(*p_format, ')'));
+                                         countformat(*p_format, ')'), flags);
 
                case '[':
                        return do_mklist(p_format, p_va, ']',
-                                        countformat(*p_format, ']'));
+                                        countformat(*p_format, ']'), flags);
 
                case '{':
                        return do_mkdict(p_format, p_va, '}',
-                                        countformat(*p_format, '}'));
+                                        countformat(*p_format, '}'), flags);
 
                case 'b':
                case 'B':
@@ -351,10 +357,13 @@ do_mkvalue(const char **p_format, va_list *p_va)
                {
                        PyObject *v;
                        Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
-                       int n;
+                       Py_ssize_t n;   
                        if (**p_format == '#') {
                                ++*p_format;
-                               n = va_arg(*p_va, int);
+                               if (flags & FLAG_SIZE_T)
+                                       n = va_arg(*p_va, Py_ssize_t);
+                               else
+                                       n = va_arg(*p_va, int);
                        }
                        else
                                n = -1;
@@ -393,10 +402,13 @@ do_mkvalue(const char **p_format, va_list *p_va)
                {
                        PyObject *v;
                        char *str = va_arg(*p_va, char *);
-                       int n;
+                       Py_ssize_t n;
                        if (**p_format == '#') {
                                ++*p_format;
-                               n = va_arg(*p_va, int);
+                               if (flags & FLAG_SIZE_T)
+                                       n = va_arg(*p_va, Py_ssize_t);
+                               else
+                                       n = va_arg(*p_va, int);
                        }
                        else
                                n = -1;
@@ -472,13 +484,36 @@ Py_BuildValue(const char *format, ...)
        va_list va;
        PyObject* retval;
        va_start(va, format);
-       retval = Py_VaBuildValue(format, va);
+       retval = va_build_value(format, va, 0);
+       va_end(va);
+       return retval;
+}
+
+PyObject *
+_Py_BuildValue_SizeT(const char *format, ...)
+{
+       va_list va;
+       PyObject* retval;
+       va_start(va, format);
+       retval = va_build_value(format, va, FLAG_SIZE_T);
        va_end(va);
        return retval;
 }
 
 PyObject *
 Py_VaBuildValue(const char *format, va_list va)
+{
+       return va_build_value(format, va, 0);
+}
+
+PyObject *
+_Py_VaBuildValue_SizeT(const char *format, va_list va)
+{
+       return va_build_value(format, va, FLAG_SIZE_T);
+}
+
+static PyObject *
+va_build_value(const char *format, va_list va, int flags)
 {
        const char *f = format;
        int n = countformat(f, '\0');
@@ -501,8 +536,8 @@ Py_VaBuildValue(const char *format, va_list va)
                return Py_None;
        }
        if (n == 1)
-               return do_mkvalue(&f, &lva);
-       return do_mktuple(&f, &lva, '\0', n);
+               return do_mkvalue(&f, &lva, flags);
+       return do_mktuple(&f, &lva, '\0', n, flags);
 }