Commit 3bc35aef authored by Eli Bendersky's avatar Eli Bendersky

merge heads

parents bfc48cd0 c1da75ed
...@@ -33,16 +33,33 @@ PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *, ...@@ -33,16 +33,33 @@ PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
#define FLAG_COMPAT 1 #define FLAG_COMPAT 1
#define FLAG_SIZE_T 2 #define FLAG_SIZE_T 2
typedef int (*destr_t)(PyObject *, void *);
/* Keep track of "objects" that have been allocated or initialized and
which will need to be deallocated or cleaned up somehow if overall
parsing fails.
*/
typedef struct {
void *item;
destr_t destructor;
} freelistentry_t;
typedef struct {
int first_available;
freelistentry_t *entries;
} freelist_t;
/* Forward */ /* Forward */
static int vgetargs1(PyObject *, const char *, va_list *, int); static int vgetargs1(PyObject *, const char *, va_list *, int);
static void seterror(int, const char *, int *, const char *, const char *); static void seterror(int, const char *, int *, const char *, const char *);
static char *convertitem(PyObject *, const char **, va_list *, int, int *, static char *convertitem(PyObject *, const char **, va_list *, int, int *,
char *, size_t, PyObject **); char *, size_t, freelist_t *);
static char *converttuple(PyObject *, const char **, va_list *, int, static char *converttuple(PyObject *, const char **, va_list *, int,
int *, char *, size_t, int, PyObject **); int *, char *, size_t, int, freelist_t *);
static char *convertsimple(PyObject *, const char **, va_list *, int, char *, static char *convertsimple(PyObject *, const char **, va_list *, int, char *,
size_t, PyObject **); size_t, freelist_t *);
static Py_ssize_t convertbuffer(PyObject *, void **p, char **); static Py_ssize_t convertbuffer(PyObject *, void **p, char **);
static int getbuffer(PyObject *, Py_buffer *, char**); static int getbuffer(PyObject *, Py_buffer *, char**);
...@@ -127,111 +144,54 @@ _PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va) ...@@ -127,111 +144,54 @@ _PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer" #define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
#define GETARGS_CAPSULE_NAME_CLEANUP_CONVERT "getargs.cleanup_convert" #define GETARGS_CAPSULE_NAME_CLEANUP_CONVERT "getargs.cleanup_convert"
static void static int
cleanup_ptr(PyObject *self) cleanup_ptr(PyObject *self, void *ptr)
{ {
void *ptr = PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_PTR);
if (ptr) { if (ptr) {
PyMem_FREE(ptr); PyMem_FREE(ptr);
} }
return 0;
} }
static void static int
cleanup_buffer(PyObject *self) cleanup_buffer(PyObject *self, void *ptr)
{ {
Py_buffer *ptr = (Py_buffer *)PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_BUFFER); Py_buffer *buf = (Py_buffer *)ptr;
if (ptr) { if (buf) {
PyBuffer_Release(ptr); PyBuffer_Release(buf);
} }
return 0;
} }
static int static int
addcleanup(void *ptr, PyObject **freelist, int is_buffer) addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
{ {
PyObject *cobj; int index;
const char *name;
PyCapsule_Destructor destr;
if (is_buffer) { index = freelist->first_available;
destr = cleanup_buffer; freelist->first_available += 1;
name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER;
} else {
destr = cleanup_ptr;
name = GETARGS_CAPSULE_NAME_CLEANUP_PTR;
}
if (!*freelist) { freelist->entries[index].item = ptr;
*freelist = PyList_New(0); freelist->entries[index].destructor = destructor;
if (!*freelist) {
destr(ptr);
return -1;
}
}
cobj = PyCapsule_New(ptr, name, destr);
if (!cobj) {
destr(ptr);
return -1;
}
if (PyList_Append(*freelist, cobj)) {
Py_DECREF(cobj);
return -1;
}
Py_DECREF(cobj);
return 0; return 0;
} }
static void
cleanup_convert(PyObject *self)
{
typedef int (*destr_t)(PyObject *, void *);
destr_t destr = (destr_t)PyCapsule_GetContext(self);
void *ptr = PyCapsule_GetPointer(self,
GETARGS_CAPSULE_NAME_CLEANUP_CONVERT);
if (ptr && destr)
destr(NULL, ptr);
}
static int static int
addcleanup_convert(void *ptr, PyObject **freelist, int (*destr)(PyObject*,void*)) cleanreturn(int retval, freelist_t *freelist)
{ {
PyObject *cobj; int index;
if (!*freelist) {
*freelist = PyList_New(0); if (retval == 0) {
if (!*freelist) { /* A failure occurred, therefore execute all of the cleanup
destr(NULL, ptr); functions.
return -1; */
} for (index = 0; index < freelist->first_available; ++index) {
} freelist->entries[index].destructor(NULL,
cobj = PyCapsule_New(ptr, GETARGS_CAPSULE_NAME_CLEANUP_CONVERT, freelist->entries[index].item);
cleanup_convert);
if (!cobj) {
destr(NULL, ptr);
return -1;
} }
if (PyCapsule_SetContext(cobj, destr) == -1) {
/* This really should not happen. */
Py_FatalError("capsule refused setting of context.");
} }
if (PyList_Append(*freelist, cobj)) { PyMem_Free(freelist->entries);
Py_DECREF(cobj); /* This will also call destr. */
return -1;
}
Py_DECREF(cobj);
return 0;
}
static int
cleanreturn(int retval, PyObject *freelist)
{
if (freelist && retval != 0) {
/* We were successful, reset the destructors so that they
don't get called. */
Py_ssize_t len = PyList_GET_SIZE(freelist), i;
for (i = 0; i < len; i++)
PyCapsule_SetDestructor(PyList_GET_ITEM(freelist, i), NULL);
}
Py_XDECREF(freelist);
return retval; return retval;
} }
...@@ -250,7 +210,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -250,7 +210,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
const char *formatsave = format; const char *formatsave = format;
Py_ssize_t i, len; Py_ssize_t i, len;
char *msg; char *msg;
PyObject *freelist = NULL; freelist_t freelist = {0, NULL};
int compat = flags & FLAG_COMPAT; int compat = flags & FLAG_COMPAT;
assert(compat || (args != (PyObject*)NULL)); assert(compat || (args != (PyObject*)NULL));
...@@ -306,6 +266,8 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -306,6 +266,8 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
format = formatsave; format = formatsave;
freelist.entries = PyMem_New(freelistentry_t, max);
if (compat) { if (compat) {
if (max == 0) { if (max == 0) {
if (args == NULL) if (args == NULL)
...@@ -314,7 +276,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -314,7 +276,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
"%.200s%s takes no arguments", "%.200s%s takes no arguments",
fname==NULL ? "function" : fname, fname==NULL ? "function" : fname,
fname==NULL ? "" : "()"); fname==NULL ? "" : "()");
return 0; return cleanreturn(0, &freelist);
} }
else if (min == 1 && max == 1) { else if (min == 1 && max == 1) {
if (args == NULL) { if (args == NULL) {
...@@ -322,26 +284,26 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -322,26 +284,26 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
"%.200s%s takes at least one argument", "%.200s%s takes at least one argument",
fname==NULL ? "function" : fname, fname==NULL ? "function" : fname,
fname==NULL ? "" : "()"); fname==NULL ? "" : "()");
return 0; return cleanreturn(0, &freelist);
} }
msg = convertitem(args, &format, p_va, flags, levels, msg = convertitem(args, &format, p_va, flags, levels,
msgbuf, sizeof(msgbuf), &freelist); msgbuf, sizeof(msgbuf), &freelist);
if (msg == NULL) if (msg == NULL)
return cleanreturn(1, freelist); return cleanreturn(1, &freelist);
seterror(levels[0], msg, levels+1, fname, message); seterror(levels[0], msg, levels+1, fname, message);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
else { else {
PyErr_SetString(PyExc_SystemError, PyErr_SetString(PyExc_SystemError,
"old style getargs format uses new features"); "old style getargs format uses new features");
return 0; return cleanreturn(0, &freelist);
} }
} }
if (!PyTuple_Check(args)) { if (!PyTuple_Check(args)) {
PyErr_SetString(PyExc_SystemError, PyErr_SetString(PyExc_SystemError,
"new style getargs format but argument is not a tuple"); "new style getargs format but argument is not a tuple");
return 0; return cleanreturn(0, &freelist);
} }
len = PyTuple_GET_SIZE(args); len = PyTuple_GET_SIZE(args);
...@@ -359,7 +321,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -359,7 +321,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
Py_SAFE_DOWNCAST(len, Py_ssize_t, long)); Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
else else
PyErr_SetString(PyExc_TypeError, message); PyErr_SetString(PyExc_TypeError, message);
return 0; return cleanreturn(0, &freelist);
} }
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
...@@ -370,7 +332,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -370,7 +332,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
sizeof(msgbuf), &freelist); sizeof(msgbuf), &freelist);
if (msg) { if (msg) {
seterror(i+1, msg, levels, fname, msg); seterror(i+1, msg, levels, fname, msg);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
} }
...@@ -379,10 +341,10 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) ...@@ -379,10 +341,10 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
*format != '|' && *format != ':' && *format != ';') { *format != '|' && *format != ':' && *format != ';') {
PyErr_Format(PyExc_SystemError, PyErr_Format(PyExc_SystemError,
"bad format string: %.200s", formatsave); "bad format string: %.200s", formatsave);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
return cleanreturn(1, freelist); return cleanreturn(1, &freelist);
} }
...@@ -446,7 +408,7 @@ seterror(int iarg, const char *msg, int *levels, const char *fname, ...@@ -446,7 +408,7 @@ seterror(int iarg, const char *msg, int *levels, const char *fname,
static char * static char *
converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
int *levels, char *msgbuf, size_t bufsize, int toplevel, int *levels, char *msgbuf, size_t bufsize, int toplevel,
PyObject **freelist) freelist_t *freelist)
{ {
int level = 0; int level = 0;
int n = 0; int n = 0;
...@@ -521,7 +483,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags, ...@@ -521,7 +483,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
static char * static char *
convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags, convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
int *levels, char *msgbuf, size_t bufsize, PyObject **freelist) int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist)
{ {
char *msg; char *msg;
const char *format = *p_format; const char *format = *p_format;
...@@ -586,7 +548,7 @@ float_argument_error(PyObject *arg) ...@@ -586,7 +548,7 @@ float_argument_error(PyObject *arg)
static char * static char *
convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
char *msgbuf, size_t bufsize, PyObject **freelist) char *msgbuf, size_t bufsize, freelist_t *freelist)
{ {
/* For # codes */ /* For # codes */
#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\ #define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
...@@ -863,7 +825,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, ...@@ -863,7 +825,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
return converterr(buf, arg, msgbuf, bufsize); return converterr(buf, arg, msgbuf, bufsize);
format++; format++;
if (addcleanup(p, freelist, 1)) { if (addcleanup(p, freelist, cleanup_buffer)) {
return converterr( return converterr(
"(cleanup problem)", "(cleanup problem)",
arg, msgbuf, bufsize); arg, msgbuf, bufsize);
...@@ -908,7 +870,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, ...@@ -908,7 +870,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if (getbuffer(arg, p, &buf) < 0) if (getbuffer(arg, p, &buf) < 0)
return converterr(buf, arg, msgbuf, bufsize); return converterr(buf, arg, msgbuf, bufsize);
} }
if (addcleanup(p, freelist, 1)) { if (addcleanup(p, freelist, cleanup_buffer)) {
return converterr( return converterr(
"(cleanup problem)", "(cleanup problem)",
arg, msgbuf, bufsize); arg, msgbuf, bufsize);
...@@ -1120,7 +1082,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, ...@@ -1120,7 +1082,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
PyErr_NoMemory(); PyErr_NoMemory();
RETURN_ERR_OCCURRED; RETURN_ERR_OCCURRED;
} }
if (addcleanup(*buffer, freelist, 0)) { if (addcleanup(*buffer, freelist, cleanup_ptr)) {
Py_DECREF(s); Py_DECREF(s);
return converterr( return converterr(
"(cleanup problem)", "(cleanup problem)",
...@@ -1162,7 +1124,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, ...@@ -1162,7 +1124,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
PyErr_NoMemory(); PyErr_NoMemory();
RETURN_ERR_OCCURRED; RETURN_ERR_OCCURRED;
} }
if (addcleanup(*buffer, freelist, 0)) { if (addcleanup(*buffer, freelist, cleanup_ptr)) {
Py_DECREF(s); Py_DECREF(s);
return converterr("(cleanup problem)", return converterr("(cleanup problem)",
arg, msgbuf, bufsize); arg, msgbuf, bufsize);
...@@ -1223,7 +1185,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, ...@@ -1223,7 +1185,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
return converterr("(unspecified)", return converterr("(unspecified)",
arg, msgbuf, bufsize); arg, msgbuf, bufsize);
if (res == Py_CLEANUP_SUPPORTED && if (res == Py_CLEANUP_SUPPORTED &&
addcleanup_convert(addr, freelist, convert) == -1) addcleanup(addr, freelist, convert) == -1)
return converterr("(cleanup problem)", return converterr("(cleanup problem)",
arg, msgbuf, bufsize); arg, msgbuf, bufsize);
} }
...@@ -1254,7 +1216,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, ...@@ -1254,7 +1216,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
PyBuffer_Release((Py_buffer*)p); PyBuffer_Release((Py_buffer*)p);
return converterr("contiguous buffer", arg, msgbuf, bufsize); return converterr("contiguous buffer", arg, msgbuf, bufsize);
} }
if (addcleanup(p, freelist, 1)) { if (addcleanup(p, freelist, cleanup_buffer)) {
return converterr( return converterr(
"(cleanup problem)", "(cleanup problem)",
arg, msgbuf, bufsize); arg, msgbuf, bufsize);
...@@ -1442,7 +1404,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1442,7 +1404,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
const char *fname, *msg, *custom_msg, *keyword; const char *fname, *msg, *custom_msg, *keyword;
int min = INT_MAX; int min = INT_MAX;
int i, len, nargs, nkeywords; int i, len, nargs, nkeywords;
PyObject *freelist = NULL, *current_arg; PyObject *current_arg;
freelist_t freelist = {0, NULL};
assert(args != NULL && PyTuple_Check(args)); assert(args != NULL && PyTuple_Check(args));
assert(keywords == NULL || PyDict_Check(keywords)); assert(keywords == NULL || PyDict_Check(keywords));
...@@ -1466,6 +1429,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1466,6 +1429,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
for (len=0; kwlist[len]; len++) for (len=0; kwlist[len]; len++)
continue; continue;
freelist.entries = PyMem_New(freelistentry_t, len);
nargs = PyTuple_GET_SIZE(args); nargs = PyTuple_GET_SIZE(args);
nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords); nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
if (nargs + nkeywords > len) { if (nargs + nkeywords > len) {
...@@ -1490,7 +1455,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1490,7 +1455,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
PyErr_Format(PyExc_RuntimeError, PyErr_Format(PyExc_RuntimeError,
"More keyword list entries (%d) than " "More keyword list entries (%d) than "
"format specifiers (%d)", len, i); "format specifiers (%d)", len, i);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
current_arg = NULL; current_arg = NULL;
if (nkeywords) { if (nkeywords) {
...@@ -1504,11 +1469,11 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1504,11 +1469,11 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
"Argument given by name ('%s') " "Argument given by name ('%s') "
"and position (%d)", "and position (%d)",
keyword, i+1); keyword, i+1);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
} }
else if (nkeywords && PyErr_Occurred()) else if (nkeywords && PyErr_Occurred())
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
else if (i < nargs) else if (i < nargs)
current_arg = PyTuple_GET_ITEM(args, i); current_arg = PyTuple_GET_ITEM(args, i);
...@@ -1517,7 +1482,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1517,7 +1482,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
levels, msgbuf, sizeof(msgbuf), &freelist); levels, msgbuf, sizeof(msgbuf), &freelist);
if (msg) { if (msg) {
seterror(i+1, msg, levels, fname, custom_msg); seterror(i+1, msg, levels, fname, custom_msg);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
continue; continue;
} }
...@@ -1526,14 +1491,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1526,14 +1491,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
PyErr_Format(PyExc_TypeError, "Required argument " PyErr_Format(PyExc_TypeError, "Required argument "
"'%s' (pos %d) not found", "'%s' (pos %d) not found",
keyword, i+1); keyword, i+1);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
/* current code reports success when all required args /* current code reports success when all required args
* fulfilled and no keyword args left, with no further * fulfilled and no keyword args left, with no further
* validation. XXX Maybe skip this in debug build ? * validation. XXX Maybe skip this in debug build ?
*/ */
if (!nkeywords) if (!nkeywords)
return cleanreturn(1, freelist); return cleanreturn(1, &freelist);
/* We are into optional args, skip thru to any remaining /* We are into optional args, skip thru to any remaining
* keyword args */ * keyword args */
...@@ -1541,7 +1506,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1541,7 +1506,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
if (msg) { if (msg) {
PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg, PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg,
format); format);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
} }
...@@ -1549,7 +1514,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1549,7 +1514,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
PyErr_Format(PyExc_RuntimeError, PyErr_Format(PyExc_RuntimeError,
"more argument specifiers than keyword list entries " "more argument specifiers than keyword list entries "
"(remaining format:'%s')", format); "(remaining format:'%s')", format);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
/* make sure there are no extraneous keyword arguments */ /* make sure there are no extraneous keyword arguments */
...@@ -1562,7 +1527,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1562,7 +1527,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
if (!PyUnicode_Check(key)) { if (!PyUnicode_Check(key)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"keywords must be strings"); "keywords must be strings");
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
/* check that _PyUnicode_AsString() result is not NULL */ /* check that _PyUnicode_AsString() result is not NULL */
ks = _PyUnicode_AsString(key); ks = _PyUnicode_AsString(key);
...@@ -1579,12 +1544,12 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, ...@@ -1579,12 +1544,12 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
"'%U' is an invalid keyword " "'%U' is an invalid keyword "
"argument for this function", "argument for this function",
key); key);
return cleanreturn(0, freelist); return cleanreturn(0, &freelist);
} }
} }
} }
return cleanreturn(1, freelist); return cleanreturn(1, &freelist);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment