diff -r 11205ffc537a Modules/posixmodule.c --- a/Modules/posixmodule.c Fri May 04 09:44:39 2012 +0100 +++ b/Modules/posixmodule.c Fri May 04 02:15:53 2012 -0700 @@ -3658,9 +3658,17 @@ /* * utime_read_time_arguments() processes arguments for the utime * family of functions. - * returns zero on failure. */ -static int + +typedef enum { + utime_success = 0, + utime_parse_failure = 1, + utime_times_and_ns_collision = 2, + utime_times_conversion_failure = 3, + utime_ns_conversion_failure = 4, +} utime_status; + +static utime_status utime_read_time_arguments(utime_arguments *ua) { PyObject *times = NULL; @@ -3668,7 +3676,8 @@ char format[24]; char *kwlist[4]; char **kw = kwlist; - int return_value; + utime_status return_value; + int parse_result; *kw++ = ua->first_argument_name; *kw++ = "times"; @@ -3681,20 +3690,21 @@ ua->function_name); if (ua->converter) - return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs, + parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs, format, kwlist, ua->converter, ua->path, ×, &ns); else - return_value = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs, + parse_result = PyArg_ParseTupleAndKeywords(ua->args, ua->kwargs, format, kwlist, ua->path, ×, &ns); - if (!return_value) - return 0; + if (!parse_result) + return utime_parse_failure; if (times && ns) { PyErr_Format(PyExc_RuntimeError, "%s: you may specify either 'times'" " or 'ns' but not both", ua->function_name); + return_value = utime_times_and_ns_collision; goto fail; } @@ -3704,15 +3714,18 @@ "%s: 'time' must be either" " a tuple of two ints or None", ua->function_name); + return_value = utime_times_conversion_failure; goto fail; } ua->now = 0; if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), &ua->atime_s, &ua->atime_ns) == -1 || _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), - &ua->mtime_s, &ua->mtime_ns) == -1) + &ua->mtime_s, &ua->mtime_ns) == -1) { + return_value = utime_times_conversion_failure; goto fail; - return 1; + } + return utime_success; } if (ns) { @@ -3720,25 +3733,28 @@ PyErr_Format(PyExc_TypeError, "%s: 'ns' must be a tuple of two ints", ua->function_name); + return_value = utime_ns_conversion_failure; goto fail; } ua->now = 0; if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0), &ua->atime_s, &ua->atime_ns) || !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1), - &ua->mtime_s, &ua->mtime_ns)) + &ua->mtime_s, &ua->mtime_ns)) { + return_value = utime_ns_conversion_failure; goto fail; - return 1; + } + return utime_success; } /* either times=None, or neither times nor ns was specified. use "now". */ ua->now = 1; - return 1; + return utime_success; fail: if (ua->converter) Py_DECREF(ua->path); - return 0; + return return_value; } @@ -3767,7 +3783,10 @@ ua.path_format = 'U'; ua.path = &upath; - if (!utime_read_time_arguments(&ua)) { + switch (utime_read_time_arguments(&ua)) { + default: + return NULL; + case utime_success: { wchar_t *wpath = PyUnicode_AsUnicode(upath); if (wpath == NULL) return NULL; @@ -3778,8 +3797,9 @@ Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) return win32_error_object("utime", upath); - } - else { + break; + } + case utime_parse_failure: { const char *apath; /* Drop the argument parsing error as narrow strings are also valid. */ @@ -3787,7 +3807,7 @@ ua.path_format = 'y'; ua.path = (PyObject **)&apath; - if (!utime_read_time_arguments(&ua)) + if (utime_read_time_arguments(&ua) != utime_success) return NULL; if (win32_warn_bytes_api()) return NULL; @@ -3801,6 +3821,9 @@ win32_error("utime", apath); return NULL; } + break; + } + } if (ua.now) { @@ -3839,7 +3862,7 @@ ua.path = &opath; ua.converter = PyUnicode_FSConverter; - if (!utime_read_time_arguments(&ua)) + if (utime_read_time_arguments(&ua) != utime_success) return NULL; path = PyBytes_AsString(opath); if (ua.now) { @@ -3892,7 +3915,7 @@ ua.path = (PyObject **)&fd; ua.first_argument_name = "fd"; - if (!utime_read_time_arguments(&ua)) + if (utime_read_time_arguments(&ua) != utime_success) return NULL; if (ua.now) { @@ -3937,7 +3960,7 @@ ua.path = &opath; ua.converter = PyUnicode_FSConverter; - if (!utime_read_time_arguments(&ua)) + if (utime_read_time_arguments(&ua) != utime_success) return NULL; path = PyBytes_AsString(opath);