diff -r 4e67dce9721b Objects/methodobject.c --- a/Objects/methodobject.c Mon Jan 16 23:52:00 2017 +0100 +++ b/Objects/methodobject.c Tue Jan 17 09:06:02 2017 +0900 @@ -237,15 +237,21 @@ case METH_FASTCALL: { PyObject **stack; PyObject *kwnames; _PyCFunctionFast fastmeth = (_PyCFunctionFast)meth; - stack = _PyStack_UnpackDict(args, nargs, kwargs, &kwnames, func_obj); - if (stack == NULL) { - return NULL; + if (nargs) { + stack = _PyStack_UnpackDict(args, nargs, kwargs, &kwnames, func_obj); + if (stack == NULL) { + return NULL; + } + } + else { + stack = args; + kwnames = NULL; } result = (*fastmeth) (self, stack, nargs, kwnames); if (stack != args) { PyMem_Free(stack); } diff -r 4e67dce9721b Tools/clinic/clinic.py --- a/Tools/clinic/clinic.py Mon Jan 16 23:52:00 2017 +0100 +++ b/Tools/clinic/clinic.py Tue Jan 17 09:06:02 2017 +0900 @@ -814,64 +814,59 @@ # positional parameters with option groups # (we have to generate lots of PyArg_ParseTuple calls # in a big switch statement) flags = "METH_VARARGS" parser_prototype = parser_prototype_varargs - parser_definition = parser_body(parser_prototype, ' {option_group_parsing}') elif positional and all_boring_objects: # positional-only, but no option groups, # and nothing but normal objects: # PyArg_UnpackTuple! - flags = "METH_VARARGS" parser_prototype = parser_prototype_varargs parser_definition = parser_body(parser_prototype, normalize_snippet(""" if (!PyArg_UnpackTuple(args, "{name}", {unpack_min}, {unpack_max}, {parse_arguments})) {{ goto exit; }} """, indent=4)) - elif positional: - # positional-only, but no option groups - # we only need one call to PyArg_ParseTuple - - flags = "METH_VARARGS" - parser_prototype = parser_prototype_varargs - - parser_definition = parser_body(parser_prototype, normalize_snippet(""" - if (!PyArg_ParseTuple(args, "{format_units}:{name}", - {parse_arguments})) {{ - goto exit; - }} - """, indent=4)) + # TODO: Support PyArg_UnpackStack added by http://bugs.python.org/issue29259 elif not new_or_init: flags = "METH_FASTCALL" - parser_prototype = parser_prototype_fastcall - body = normalize_snippet(""" if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser, {parse_arguments})) {{ goto exit; }} """, indent=4) parser_definition = parser_body(parser_prototype, body) parser_definition = insert_keywords(parser_definition) + + elif positional: + # positional-only, but no option groups + # we only need one call to PyArg_ParseTuple + flags = "METH_VARARGS" + parser_prototype = parser_prototype_varargs + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_ParseTuple(args, "{format_units}:{name}", + {parse_arguments})) {{ + goto exit; + }} + """, indent=4)) + else: # positional-or-keyword arguments flags = "METH_VARARGS|METH_KEYWORDS" - parser_prototype = parser_prototype_keyword - body = normalize_snippet(""" if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, {parse_arguments})) {{ goto exit; }} """, indent=4)