Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (revision 72598) +++ Modules/posixmodule.c (working copy) @@ -568,21 +568,31 @@ return PyErr_SetFromWindowsErr(errno); } +/* Functions suitable for O$ conversion */ static int -convert_to_unicode(PyObject **param) +convert_to_unicode(PyObject *arg, void* _param) { - if (PyUnicode_CheckExact(*param)) - Py_INCREF(*param); - else if (PyUnicode_Check(*param)) - /* For a Unicode subtype that's not a Unicode object, - return a true Unicode object with the same data. */ - *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param), - PyUnicode_GET_SIZE(*param)); - else - *param = PyUnicode_FromEncodedObject(*param, - Py_FileSystemDefaultEncoding, - "strict"); - return (*param) != NULL; + PyObject **param = (PyObject**)_param; + if (arg) { + if (PyUnicode_CheckExact(arg)) { + Py_INCREF(arg); + *param = arg; + } + else if (PyUnicode_Check(arg)) + /* For a Unicode subtype that's not a Unicode object, + return a true Unicode object with the same data. */ + *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg), + PyUnicode_GET_SIZE(arg)); + else + *param = PyUnicode_FromEncodedObject(arg, + Py_FileSystemDefaultEncoding, + "strict"); + return (*param) != NULL; + } + else { + Py_DECREF(*param); + return 1; + } } #endif /* Py_WIN_WIDE_FILENAMES */ @@ -2648,26 +2658,22 @@ char *p1, *p2; BOOL result; if (unicode_file_names()) { - if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2)) - goto error; - if (!convert_to_unicode(&o1)) - goto error; - if (!convert_to_unicode(&o2)) { - Py_DECREF(o1); - goto error; + if (!PyArg_ParseTuple(args, "O$O$:rename", + convert_to_unicode, &o1, + convert_to_unicode, &o2)) + PyErr_Clear(); + else { + Py_BEGIN_ALLOW_THREADS + result = MoveFileW(PyUnicode_AsUnicode(o1), + PyUnicode_AsUnicode(o2)); + Py_END_ALLOW_THREADS + Py_DECREF(o1); + Py_DECREF(o2); + if (!result) + return win32_error("rename", NULL); + Py_INCREF(Py_None); + return Py_None; } - Py_BEGIN_ALLOW_THREADS - result = MoveFileW(PyUnicode_AsUnicode(o1), - PyUnicode_AsUnicode(o2)); - Py_END_ALLOW_THREADS - Py_DECREF(o1); - Py_DECREF(o2); - if (!result) - return win32_error("rename", NULL); - Py_INCREF(Py_None); - return Py_None; -error: - PyErr_Clear(); } if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2)) return NULL; Index: Python/getargs.c =================================================================== --- Python/getargs.c (revision 72598) +++ Python/getargs.c (working copy) @@ -175,7 +175,39 @@ return 0; } +static void +cleanup_convert(void *ptr, void *desc) +{ + typedef int (*destr_t)(PyObject *, void *); + destr_t destr = (destr_t)desc; + destr(NULL, ptr); +} + static int +addcleanup_convert(void *ptr, PyObject **freelist, int (*destr)(PyObject *, void *)) +{ + PyObject *cobj; + if (!*freelist) { + *freelist = PyList_New(0); + if (!*freelist) { + destr(NULL, ptr); + return -1; + } + } + cobj = PyCObject_FromVoidPtrAndDesc(ptr, destr, cleanup_convert); + if (!cobj) { + destr(NULL, ptr); + return -1; + } + if (PyList_Append(*freelist, cobj)) { + Py_DECREF(cobj); + return -1; + } + Py_DECREF(cobj); + return 0; +} + +static int cleanreturn(int retval, PyObject *freelist) { if (freelist && retval != 0) { @@ -1208,6 +1240,18 @@ return converterr("(unspecified)", arg, msgbuf, bufsize); } + else if (*format == '$') { + typedef int (*converter)(PyObject *, void *); + converter convert = va_arg(*p_va, converter); + void *addr = va_arg(*p_va, void *); + format++; + if (! (*convert)(arg, addr)) + return converterr("(unspecified)", + arg, msgbuf, bufsize); + if (addcleanup_convert(addr, freelist, convert)) + return converterr("(cleanup problem)", + arg, msgbuf, bufsize); + } else { p = va_arg(*p_va, PyObject **); *p = arg;