Index: configure =================================================================== --- configure (.../py3k) (Revision 72215) +++ configure (.../pep-0383) (Revision 72247) @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 71731 . +# From configure.in Revision: 72144 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for python 3.1. # @@ -16299,11 +16299,12 @@ + for ac_func in alarm setitimer getitimer bind_textdomain_codeset chown \ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getpwent getspnam getspent getsid getwd \ - kill killpg lchmod lchown lstat mkfifo mknod mktime \ + kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ Index: Python/codecs.c =================================================================== --- Python/codecs.c (.../py3k) (Revision 72215) +++ Python/codecs.c (.../pep-0383) (Revision 72247) @@ -826,6 +826,80 @@ } } +static PyObject * +PyCodec_UTF8bErrors(PyObject *exc) +{ + PyObject *restuple; + PyObject *object; + Py_ssize_t start; + Py_ssize_t end; + PyObject *res; + if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + Py_UNICODE *p; + Py_UNICODE *startp; + char *outp; + if (PyUnicodeEncodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeEncodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeEncodeError_GetObject(exc))) + return NULL; + startp = PyUnicode_AS_UNICODE(object); + res = PyBytes_FromStringAndSize(NULL, end-start); + if (!res) + return NULL; + outp = PyBytes_AsString(res); + for (p = startp+start; p < startp+end; p++) { + Py_UNICODE ch = *p; + if (ch < 0xdc80 || ch > 0xdcff) { + /* Not a UTF-8b surrogate, fail with original exception */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + Py_DECREF(res); + Py_DECREF(object); + return NULL; + } + *outp++ = ch - 0xdc00; + } + restuple = Py_BuildValue("(On)", res, end); + Py_DECREF(res); + Py_DECREF(object); + return restuple; + } + else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { + unsigned char *p; + Py_UNICODE ch[4]; /* decode up to 4 bad bytes. */ + int consumed = 0; + if (PyUnicodeDecodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeDecodeError_GetObject(exc))) + return NULL; + if (!(p = (unsigned char*)PyBytes_AsString(object))) { + Py_DECREF(object); + return NULL; + } + while (consumed < 4 && consumed < end-start) { + /* Refuse to escape ASCII bytes. */ + if (p[start+consumed] < 128) + break; + ch[consumed] = 0xdc00 + p[start+consumed]; + consumed++; + } + if (!consumed) { + /* codec complained about ASCII byte. */ + PyErr_SetObject(PyExceptionInstance_Class(exc), exc); + return NULL; + } + Py_DECREF(object); + return Py_BuildValue("(u#n)", ch, consumed, start+consumed); + } + else { + wrong_exception_type(exc); + return NULL; + } +} + static PyObject *strict_errors(PyObject *self, PyObject *exc) { @@ -861,6 +935,11 @@ return PyCodec_SurrogateErrors(exc); } +static PyObject *utf8b_errors(PyObject *self, PyObject *exc) +{ + return PyCodec_UTF8bErrors(exc); +} + static int _PyCodecRegistry_Init(void) { static struct { @@ -915,6 +994,14 @@ surrogates_errors, METH_O } + }, + { + "utf8b", + { + "utf8b", + utf8b_errors, + METH_O + } } }; Index: Python/pythonrun.c =================================================================== --- Python/pythonrun.c (.../py3k) (Revision 72215) +++ Python/pythonrun.c (.../pep-0383) (Revision 72247) @@ -262,6 +262,22 @@ _PyImportHooks_Init(); +#if defined(HAVE_LANGINFO_H) && defined(CODESET) + /* On Unix, set the file system encoding according to the + user's preference, if the CODESET names a well-known + Python codec, and Py_FileSystemDefaultEncoding isn't + initialized by other means. Also set the encoding of + stdin and stdout if these are terminals. */ + + codeset = get_codeset(); + if (codeset) { + if (!Py_FileSystemDefaultEncoding) + Py_FileSystemDefaultEncoding = codeset; + else + free(codeset); + } +#endif + if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ @@ -285,22 +301,6 @@ #ifdef WITH_THREAD _PyGILState_Init(interp, tstate); #endif /* WITH_THREAD */ - -#if defined(HAVE_LANGINFO_H) && defined(CODESET) - /* On Unix, set the file system encoding according to the - user's preference, if the CODESET names a well-known - Python codec, and Py_FileSystemDefaultEncoding isn't - initialized by other means. Also set the encoding of - stdin and stdout if these are terminals. */ - - codeset = get_codeset(); - if (codeset) { - if (!Py_FileSystemDefaultEncoding) - Py_FileSystemDefaultEncoding = codeset; - else - free(codeset); - } -#endif } void Index: Include/unicodeobject.h =================================================================== --- Include/unicodeobject.h (.../py3k) (Revision 72215) +++ Include/unicodeobject.h (.../pep-0383) (Revision 72247) @@ -198,6 +198,7 @@ # define PyUnicode_FromStringAndSize PyUnicodeUCS2_FromStringAndSize # define PyUnicode_FromUnicode PyUnicodeUCS2_FromUnicode # define PyUnicode_FromWideChar PyUnicodeUCS2_FromWideChar +# define PyUnicode_FSConverter PyUnicodeUCS2_FSConverter # define PyUnicode_GetDefaultEncoding PyUnicodeUCS2_GetDefaultEncoding # define PyUnicode_GetMax PyUnicodeUCS2_GetMax # define PyUnicode_GetSize PyUnicodeUCS2_GetSize @@ -296,6 +297,7 @@ # define PyUnicode_FromStringAndSize PyUnicodeUCS4_FromStringAndSize # define PyUnicode_FromUnicode PyUnicodeUCS4_FromUnicode # define PyUnicode_FromWideChar PyUnicodeUCS4_FromWideChar +# define PyUnicode_FSConverter PyUnicodeUCS4_FSConverter # define PyUnicode_GetDefaultEncoding PyUnicodeUCS4_GetDefaultEncoding # define PyUnicode_GetMax PyUnicodeUCS4_GetMax # define PyUnicode_GetSize PyUnicodeUCS4_GetSize @@ -693,25 +695,6 @@ PyObject *unicode, const char *errors); -/* Decode a null-terminated string using Py_FileSystemDefaultEncoding. - - If the encoding is supported by one of the built-in codecs (i.e., UTF-8, - UTF-16, UTF-32, Latin-1 or MBCS), otherwise fallback to UTF-8 and replace - invalid characters with '?'. - - The function is intended to be used for paths and file names only - during bootstrapping process where the codecs are not set up. -*/ - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefault( - const char *s /* encoded string */ - ); - -PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefaultAndSize( - const char *s, /* encoded string */ - Py_ssize_t size /* size */ - ); - /* Returns a pointer to the default encoding (normally, UTF-8) of the Unicode object unicode and the size of the encoded representation in bytes stored in *size. @@ -1254,6 +1237,33 @@ const char *errors /* error handling */ ); +/* --- File system encoding ---------------------------------------------- */ + +/* ParseTuple converter which converts a Unicode object into the file + system encoding, using the PEP 383 error handler; bytes objects are + output as-is. */ + +PyAPI_FUNC(int) PyUnicode_FSConverter(PyObject*, void*); + +/* Decode a null-terminated string using Py_FileSystemDefaultEncoding. + + If the encoding is supported by one of the built-in codecs (i.e., UTF-8, + UTF-16, UTF-32, Latin-1 or MBCS), otherwise fallback to UTF-8 and replace + invalid characters with '?'. + + The function is intended to be used for paths and file names only + during bootstrapping process where the codecs are not set up. +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefault( + const char *s /* encoded string */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefaultAndSize( + const char *s, /* encoded string */ + Py_ssize_t size /* size */ + ); + /* --- Methods & Slots ---------------------------------------------------- These are capable of handling Unicode objects and strings on input Index: configure.in =================================================================== --- configure.in (.../py3k) (Revision 72215) +++ configure.in (.../pep-0383) (Revision 72247) @@ -2403,7 +2403,7 @@ clock confstr ctermid execv fchmod fchown fork fpathconf ftime ftruncate \ gai_strerror getgroups getlogin getloadavg getpeername getpgid getpid \ getpriority getpwent getspnam getspent getsid getwd \ - kill killpg lchmod lchown lstat mkfifo mknod mktime \ + kill killpg lchmod lchown lstat mbrtowc mkfifo mknod mktime \ mremap nice pathconf pause plock poll pthread_init \ putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ Index: Objects/unicodeobject.c =================================================================== --- Objects/unicodeobject.c (.../py3k) (Revision 72215) +++ Objects/unicodeobject.c (.../pep-0383) (Revision 72247) @@ -1546,6 +1546,53 @@ } } +/* Convert the argument to a bytes object, according to the file + system encoding */ + +int +PyUnicode_FSConverter(PyObject* arg, void* addr) +{ + PyObject *output = NULL; + Py_ssize_t size; + void *data; + if (PyBytes_Check(arg) || PyByteArray_Check(arg)) { + output = arg; + Py_INCREF(output); + } + else { + arg = PyUnicode_FromObject(arg); + if (!arg) + return 0; + output = PyUnicode_AsEncodedObject(arg, + Py_FileSystemDefaultEncoding, + "utf8b"); + Py_DECREF(arg); + if (!output) + return 0; + if (!PyBytes_Check(output)) { + Py_DECREF(output); + PyErr_SetString(PyExc_TypeError, "encoder failed to return bytes"); + return 0; + } + } + if (PyBytes_Check(output)) { + size = PyBytes_GET_SIZE(output); + data = PyBytes_AS_STRING(output); + } + else { + size = PyByteArray_GET_SIZE(output); + data = PyByteArray_AS_STRING(output); + } + if (size != strlen(data)) { + PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + Py_DECREF(output); + return 0; + } + *(PyObject**)addr = output; + return 1; +} + + char* _PyUnicode_AsStringAndSize(PyObject *unicode, Py_ssize_t *psize) { @@ -4107,11 +4154,22 @@ collstart-startp, collend-startp, &newpos); if (repunicode == NULL) goto onError; - if (!PyUnicode_Check(repunicode)) { - /* Implementation limitation: byte results not supported yet. */ - PyErr_SetString(PyExc_TypeError, "error handler should return unicode"); + if (PyBytes_Check(repunicode)) { + /* Directly copy bytes result to output. */ + repsize = PyBytes_Size(repunicode); + if (repsize > 1) { + /* Make room for all additional bytes. */ + if (_PyBytes_Resize(&res, ressize+repsize-1)) { + Py_DECREF(repunicode); + goto onError; + } + ressize += repsize-1; + } + memcpy(str, PyBytes_AsString(repunicode), repsize); + str += repsize; + p = startp + newpos; Py_DECREF(repunicode); - goto onError; + break; } /* need more space? (at least enough for what we have+the replacement+the rest of the string, so @@ -5076,11 +5134,24 @@ collstartpos, collendpos, &newpos); if (repunicode == NULL) return -1; - if (!PyUnicode_Check(repunicode)) { - /* Implementation limitation: byte results not supported yet. */ - PyErr_SetString(PyExc_TypeError, "error handler should return unicode"); + if (PyBytes_Check(repunicode)) { + /* Directly copy bytes result to output. */ + Py_ssize_t outsize = PyBytes_Size(*res); + Py_ssize_t requiredsize; + repsize = PyBytes_Size(repunicode); + requiredsize = *respos + repsize; + if (requiredsize > outsize) + /* Make room for all additional bytes. */ + if (charmapencode_resize(res, respos, requiredsize)) { + Py_DECREF(repunicode); + return -1; + } + memcpy(PyBytes_AsString(*res) + *respos, + PyBytes_AsString(repunicode), repsize); + *respos += repsize; + *inpos = newpos; Py_DECREF(repunicode); - return -1; + break; } /* generate replacement */ repsize = PyUnicode_GET_SIZE(repunicode); @@ -5644,7 +5715,7 @@ if (repunicode == NULL) goto onError; if (!PyUnicode_Check(repunicode)) { - /* Implementation limitation: byte results not supported yet. */ + /* Byte results not supported, since they have no decimal property. */ PyErr_SetString(PyExc_TypeError, "error handler should return unicode"); Py_DECREF(repunicode); goto onError; Index: Doc/library/codecs.rst =================================================================== --- Doc/library/codecs.rst (.../py3k) (Revision 72215) +++ Doc/library/codecs.rst (.../pep-0383) (Revision 72247) @@ -322,6 +322,8 @@ | ``'backslashreplace'`` | Replace with backslashed escape sequences | | | (only for encoding). | +-------------------------+-----------------------------------------------+ +| ``'utf8b'`` | Replace byte with surrogate U+DCxx. | ++-------------------------+-----------------------------------------------+ In addition, the following error handlers are specific to a single codec: Index: Doc/library/os.rst =================================================================== --- Doc/library/os.rst (.../py3k) (Revision 72215) +++ Doc/library/os.rst (.../pep-0383) (Revision 72247) @@ -50,7 +50,27 @@ have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, ``'os2'``, ``'ce'``, ``'java'``. +.. _os-filenames: +File Names, Command Line Arguments, and Environment Variables +------------------------------------------------------------- + +In Python, file names, command line arguments, and environment +variables are represented using the string type. On some systems, +decoding these strings to and from bytes is necessary before passing +them to the operating system. Python uses the file system encoding to +perform this conversion (see :func:`sys.getfilesystemencoding`). + +.. versionchanged:: 3.1 + On some systems, conversion using the file system encoding may + fail. In this case, Python uses the ``utf8b`` encoding error + handler. + + +The file system encoding must guarantee to successfully decode all +bytes below 128. If the file system encoding fails to provide this +guarantee, API functions may raise UnicodeErrors. + .. _os-procinfo: Process Parameters @@ -688,13 +708,8 @@ .. function:: getcwd() - Return a string representing the current working directory. On Unix - platforms, this function may raise :exc:`UnicodeDecodeError` if the name of - the current directory is not decodable in the file system encoding. Use - :func:`getcwdb` if you need the call to never fail. Availability: Unix, - Windows. + Return a string representing the current working directory. - .. function:: getcwdb() Return a bytestring representing the current working directory. @@ -800,10 +815,8 @@ entries ``'.'`` and ``'..'`` even if they are present in the directory. Availability: Unix, Windows. - This function can be called with a bytes or string argument. In the bytes - case, all filenames will be listed as returned by the underlying API. In the - string case, filenames will be decoded using the file system encoding, and - skipped if a decoding error occurs. + This function can be called with a bytes or string argument, and return + filenames of the same datatype. .. function:: lstat(path) Index: Lib/test/test_pep383.py =================================================================== --- Lib/test/test_pep383.py (.../py3k) (Revision 0) +++ Lib/test/test_pep383.py (.../pep-0383) (Revision 72247) @@ -0,0 +1,76 @@ +from test import support +import unittest, shutil, os, sys + +class Utf8bTest(unittest.TestCase): + + def test_utf8(self): + # Bad byte + self.assertEqual(b"foo\x80bar".decode("utf-8", "utf8b"), + "foo\udc80bar") + self.assertEqual("foo\udc80bar".encode("utf-8", "utf8b"), + b"foo\x80bar") + # bad-utf-8 encoded surrogate + self.assertEqual(b"\xed\xb0\x80".decode("utf-8", "utf8b"), + "\udced\udcb0\udc80") + self.assertEqual("\udced\udcb0\udc80".encode("utf-8", "utf8b"), + b"\xed\xb0\x80") + + def test_ascii(self): + # bad byte + self.assertEqual(b"foo\x80bar".decode("ascii", "utf8b"), + "foo\udc80bar") + self.assertEqual("foo\udc80bar".encode("ascii", "utf8b"), + b"foo\x80bar") + + def test_charmap(self): + # bad byte: \xa5 is unmapped in iso-8859-3 + self.assertEqual(b"foo\xa5bar".decode("iso-8859-3", "utf8b"), + "foo\udca5bar") + self.assertEqual("foo\udca5bar".encode("iso-8859-4", "utf8b"), + b"foo\xa5bar") + +class FileTests(unittest.TestCase): + if os.name != 'win32': + filenames = [b'foo\xf6bar', b'foo\xf6bar'] + else: + # PEP 383 has no effect on file name handling on Windows + filenames = [] + + def setUp(self): + self.fsencoding = sys.getfilesystemencoding() + sys.setfilesystemencoding("utf-8") + self.dir = support.TESTFN + self.bdir = self.dir.encode("utf-8", "utf8b") + os.mkdir(self.dir) + self.unicodefn = [] + for fn in self.filenames: + f = open(self.bdir + b"/" + fn, "w") + f.close() + self.unicodefn.append(fn.decode("utf-8", "utf8b")) + + def tearDown(self): + shutil.rmtree(self.dir) + sys.setfilesystemencoding(self.fsencoding) + + def test_listdir(self): + expected = set(self.unicodefn) + found = set(os.listdir(support.TESTFN)) + self.assertEquals(found, expected) + + def test_open(self): + for fn in self.unicodefn: + f = open(os.path.join(self.dir, fn)) + f.close() + + def test_stat(self): + for fn in self.unicodefn: + os.stat(os.path.join(self.dir, fn)) + +def test_main(): + support.run_unittest( + Utf8bTest, + FileTests) + + +if __name__ == "__main__": + test_main() Eigenschaftsänderungen: Lib/test/test_pep383.py ___________________________________________________________________ Hinzugefügt: svn:keywords + Id Hinzugefügt: svn:eol-style + native Index: Modules/_io/fileio.c =================================================================== --- Modules/_io/fileio.c (.../py3k) (Revision 72215) +++ Modules/_io/fileio.c (.../pep-0383) (Revision 72247) @@ -245,7 +245,7 @@ return -1; stringobj = PyUnicode_AsEncodedString( - u, Py_FileSystemDefaultEncoding, NULL); + u, Py_FileSystemDefaultEncoding, "utf8b"); Py_DECREF(u); if (stringobj == NULL) return -1; Index: Modules/python.c =================================================================== --- Modules/python.c (.../py3k) (Revision 72215) +++ Modules/python.c (.../pep-0383) (Revision 72247) @@ -14,6 +14,93 @@ return Py_Main(argc, argv); } #else +static wchar_t* +char2wchar(char* arg) +{ + wchar_t *res; +#ifdef HAVE_BROKEN_MBSTOWCS + /* Some platforms have a broken implementation of + * mbstowcs which does not count the characters that + * would result from conversion. Use an upper bound. + */ + size_t argsize = strlen(arg); +#else + size_t argsize = mbstowcs(NULL, arg, 0); +#endif + size_t count; + unsigned char *in; + wchar_t *out; +#ifdef HAVE_MBRTOWC + mbstate_t mbs; +#endif + if (argsize != (size_t)-1) { + res = (wchar_t *)PyMem_Malloc((argsize+1)*sizeof(wchar_t)); + if (!res) + goto oom; + count = mbstowcs(res, arg, argsize+1); + if (count != (size_t)-1) + return res; + PyMem_Free(res); + } + /* Conversion failed. Fall back to escaping with utf8b. */ +#ifdef HAVE_MBRTOWC + /* Try conversion with mbsrtwocs (C99), and escape non-decodable bytes. */ + + /* Overallocate; as multi-byte characters are in the argument, the + actual output could use less memory. */ + argsize = strlen(arg) + 1; + res = PyMem_Malloc(argsize*sizeof(wchar_t)); + if (!res) goto oom; + in = (unsigned char*)arg; + out = res; + memset(&mbs, 0, sizeof mbs); + while (argsize) { + size_t converted = mbrtowc(out, (char*)in, argsize, &mbs); + if (converted == 0) + /* Reached end of string; null char stored. */ + break; + if (converted == (size_t)-2) { + /* Incomplete character. This should never happen, + since we provide everything that we have - + unless there is a bug in the C library, or I + misunderstood how mbrtowc works. */ + fprintf(stderr, "unexpected mbrtowc result -2\n"); + return NULL; + } + if (converted == (size_t)-1) { + /* Conversion error. Escape as UTF-8b, and start over + in the initial shift state. */ + *out++ = 0xdc00 + *in++; + argsize--; + memset(&mbs, 0, sizeof mbs); + continue; + } + /* successfully converted some bytes */ + in += converted; + argsize -= converted; + out++; + } +#else + /* Cannot use C locale for escaping; manually escape as if charset + is ASCII (i.e. escape all bytes > 128. This will still roundtrip + correctly in the locale's charset, which must be an ASCII superset. */ + res = PyMem_Malloc((strlen(arg)+1)*sizeof(wchar_t)); + if (!res) goto oom; + in = (unsigned char*)arg; + out = res; + while(*in) + if(*in < 128) + *out++ = *in++; + else + *out++ = 0xdc00 + *in++; + *out = 0; +#endif + return res; +oom: + fprintf(stderr, "out of memory\n"); + return NULL; +} + int main(int argc, char **argv) { @@ -40,31 +127,9 @@ oldloc = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { -#ifdef HAVE_BROKEN_MBSTOWCS - /* Some platforms have a broken implementation of - * mbstowcs which does not count the characters that - * would result from conversion. Use an upper bound. - */ - size_t argsize = strlen(argv[i]); -#else - size_t argsize = mbstowcs(NULL, argv[i], 0); -#endif - size_t count; - if (argsize == (size_t)-1) { - fprintf(stderr, "Could not convert argument %d to string\n", i); + argv_copy2[i] = argv_copy[i] = char2wchar(argv[i]); + if (!argv_copy[i]) return 1; - } - argv_copy[i] = (wchar_t *)PyMem_Malloc((argsize+1)*sizeof(wchar_t)); - argv_copy2[i] = argv_copy[i]; - if (!argv_copy[i]) { - fprintf(stderr, "out of memory\n"); - return 1; - } - count = mbstowcs(argv_copy[i], argv[i], argsize+1); - if (count == (size_t)-1) { - fprintf(stderr, "Could not convert argument %d to string\n", i); - return 1; - } } setlocale(LC_ALL, oldloc); free(oldloc); Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (.../py3k) (Revision 72215) +++ Modules/posixmodule.c (.../pep-0383) (Revision 72247) @@ -493,12 +493,14 @@ char *p = strchr(*e, '='); if (p == NULL) continue; - k = PyUnicode_FromStringAndSize(*e, (int)(p-*e)); + k = PyUnicode_Decode(*e, (int)(p-*e), + Py_FileSystemDefaultEncoding, "utf8b"); if (k == NULL) { PyErr_Clear(); continue; } - v = PyUnicode_FromString(p+1); + v = PyUnicode_Decode(p+1, strlen(p+1), + Py_FileSystemDefaultEncoding, "utf8b"); if (v == NULL) { PyErr_Clear(); Py_DECREF(k); @@ -534,7 +536,37 @@ return d; } +/* Convert a bytes object to a char*. Optionally lock the buffer if it is a + bytes array. */ +static char* +bytes2str(PyObject* o, int lock) +{ + if(PyBytes_Check(o)) + return PyBytes_AsString(o); + else if(PyByteArray_Check(o)) { + if (lock && o->ob_type->tp_as_buffer->bf_getbuffer(o, NULL, 0) < 0) + /* On a bytearray, this should not fail. */ + PyErr_BadInternalCall(); + return PyByteArray_AsString(o); + } else { + /* The FS converter should have verified that this + is either bytes or bytearray. */ + PyErr_BadInternalCall(); + return NULL; + } +} + +/* Release the lock, decref the object. */ +static void +release_bytes(PyObject* o) +{ + if (PyByteArray_Check(o)) + o->ob_type->tp_as_buffer->bf_releasebuffer(NULL, 0); + Py_DECREF(o); +} + + /* Set a POSIX-specific error from errno, and return NULL */ static PyObject * @@ -558,10 +590,11 @@ static PyObject * -posix_error_with_allocated_filename(char* name) +posix_error_with_allocated_filename(PyObject* name) { - PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); - PyMem_Free(name); + PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, + bytes2str(name, 0)); + release_bytes(name); return rc; } @@ -728,17 +761,19 @@ static PyObject * posix_1str(PyObject *args, char *format, int (*func)(const char*)) { - char *path1 = NULL; + PyObject *opath1 = NULL; + char *path1; int res; if (!PyArg_ParseTuple(args, format, - Py_FileSystemDefaultEncoding, &path1)) + PyUnicode_FSConverter, &opath1)) return NULL; + path1 = bytes2str(opath1, 1); Py_BEGIN_ALLOW_THREADS res = (*func)(path1); Py_END_ALLOW_THREADS if (res < 0) - return posix_error_with_allocated_filename(path1); - PyMem_Free(path1); + return posix_error_with_allocated_filename(opath1); + release_bytes(opath1); Py_INCREF(Py_None); return Py_None; } @@ -748,17 +783,20 @@ char *format, int (*func)(const char *, const char *)) { - char *path1 = NULL, *path2 = NULL; + PyObject *opath1, *opath2; + char *path1, *path2; int res; if (!PyArg_ParseTuple(args, format, - Py_FileSystemDefaultEncoding, &path1, - Py_FileSystemDefaultEncoding, &path2)) + PyUnicode_FSConverter, &opath1, + PyUnicode_FSConverter, &opath2)) return NULL; + path1 = bytes2str(opath1, 1); + path2 = bytes2str(opath2, 1); Py_BEGIN_ALLOW_THREADS res = (*func)(path1, path2); Py_END_ALLOW_THREADS - PyMem_Free(path1); - PyMem_Free(path2); + release_bytes(opath1); + release_bytes(opath2); if (res != 0) /* XXX how to report both path1 and path2??? */ return posix_error(); @@ -1560,8 +1598,8 @@ int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *)) { STRUCT_STAT st; - char *path = NULL; /* pass this to stat; do not free() it */ - char *pathfree = NULL; /* this memory must be free'd */ + PyObject *opath; + char *path; int res; PyObject *result; @@ -1590,25 +1628,24 @@ #endif if (!PyArg_ParseTuple(args, format, - Py_FileSystemDefaultEncoding, &path)) + PyUnicode_FSConverter, &opath)) return NULL; - pathfree = path; - + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS res = (*statfunc)(path, &st); Py_END_ALLOW_THREADS if (res != 0) { #ifdef MS_WINDOWS - result = win32_error("stat", pathfree); + result = win32_error("stat", path); #else - result = posix_error_with_filename(pathfree); + result = posix_error_with_filename(path); #endif } else result = _pystat_fromstructstat(&st); - PyMem_Free(pathfree); + release_bytes(opath); return result; } @@ -1625,6 +1662,7 @@ static PyObject * posix_access(PyObject *self, PyObject *args) { + PyObject *opath; char *path; int mode; @@ -1644,13 +1682,14 @@ are also valid. */ PyErr_Clear(); } - if (!PyArg_ParseTuple(args, "eti:access", - Py_FileSystemDefaultEncoding, &path, &mode)) + if (!PyArg_ParseTuple(args, "O&i:access", + PyUnicode_FSConverter, &opath, &mode)) return 0; + path = bytes2str(opath); Py_BEGIN_ALLOW_THREADS attr = GetFileAttributesA(path); Py_END_ALLOW_THREADS - PyMem_Free(path); + release_bytes(opath); finish: if (attr == 0xFFFFFFFF) /* File does not exist, or cannot read attributes */ @@ -1663,13 +1702,14 @@ || (attr & FILE_ATTRIBUTE_DIRECTORY)); #else int res; - if (!PyArg_ParseTuple(args, "eti:access", - Py_FileSystemDefaultEncoding, &path, &mode)) + if (!PyArg_ParseTuple(args, "O&i:access", + PyUnicode_FSConverter, &opath, &mode)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS res = access(path, mode); Py_END_ALLOW_THREADS - PyMem_Free(path); + release_bytes(opath); return PyBool_FromLong(res == 0); #endif } @@ -1750,11 +1790,11 @@ #ifdef MS_WINDOWS return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir); #elif defined(PYOS_OS2) && defined(PYCC_GCC) - return posix_1str(args, "et:chdir", _chdir2); + return posix_1str(args, "O&:chdir", _chdir2); #elif defined(__VMS) - return posix_1str(args, "et:chdir", (int (*)(const char *))chdir); + return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir); #else - return posix_1str(args, "et:chdir", chdir); + return posix_1str(args, "O&:chdir", chdir); #endif } @@ -1779,6 +1819,7 @@ static PyObject * posix_chmod(PyObject *self, PyObject *args) { + PyObject *opath = NULL; char *path = NULL; int i; int res; @@ -1809,9 +1850,10 @@ are also valid. */ PyErr_Clear(); } - if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding, - &path, &i)) + if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter, + &opath, &i)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS attr = GetFileAttributesA(path); if (attr != 0xFFFFFFFF) { @@ -1826,22 +1868,23 @@ Py_END_ALLOW_THREADS if (!res) { win32_error("chmod", path); - PyMem_Free(path); + release_bytes(opath); return NULL; } - PyMem_Free(path); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; #else /* Py_WIN_WIDE_FILENAMES */ - if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding, - &path, &i)) + if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter, + &opath, &i)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS res = chmod(path, i); Py_END_ALLOW_THREADS if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); + return posix_error_with_allocated_filename(opath); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; #endif @@ -1877,18 +1920,20 @@ static PyObject * posix_lchmod(PyObject *self, PyObject *args) { - char *path = NULL; + PyObject *opath; + char *path; int i; int res; - if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding, - &path, &i)) + if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter, + &opath, &i)) return NULL; + path = bytes2str(opath, 1) Py_BEGIN_ALLOW_THREADS res = lchmod(path, i); Py_END_ALLOW_THREADS if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); + return posix_error_with_allocated_filename(opath); + release_bytes(opath); Py_RETURN_NONE; } #endif /* HAVE_LCHMOD */ @@ -1902,18 +1947,20 @@ static PyObject * posix_chflags(PyObject *self, PyObject *args) { + PyObject *opath; char *path; unsigned long flags; int res; - if (!PyArg_ParseTuple(args, "etk:chflags", - Py_FileSystemDefaultEncoding, &path, &flags)) + if (!PyArg_ParseTuple(args, "O&k:chflags", + PyUnicode_FSConverter, &opath, &flags)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS res = chflags(path, flags); Py_END_ALLOW_THREADS if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); + return posix_error_with_allocated_filename(opath); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; } @@ -1928,18 +1975,20 @@ static PyObject * posix_lchflags(PyObject *self, PyObject *args) { + PyObject *opath; char *path; unsigned long flags; int res; - if (!PyArg_ParseTuple(args, "etk:lchflags", - Py_FileSystemDefaultEncoding, &path, &flags)) + if (!PyArg_ParseTuple(args, "O&k:lchflags", + PyUnicode_FSConverter, &path, &flags)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS res = lchflags(path, flags); Py_END_ALLOW_THREADS if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); + return posix_error_with_allocated_filename(opath); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; } @@ -1953,7 +2002,7 @@ static PyObject * posix_chroot(PyObject *self, PyObject *args) { - return posix_1str(args, "et:chroot", chroot); + return posix_1str(args, "O&:chroot", chroot); } #endif @@ -1996,19 +2045,21 @@ static PyObject * posix_chown(PyObject *self, PyObject *args) { - char *path = NULL; + PyObject *opath; + char *path; long uid, gid; int res; - if (!PyArg_ParseTuple(args, "etll:chown", - Py_FileSystemDefaultEncoding, &path, + if (!PyArg_ParseTuple(args, "O&ll:chown", + PyUnicode_FSConverter, &opath, &uid, &gid)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS res = chown(path, (uid_t) uid, (gid_t) gid); Py_END_ALLOW_THREADS if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); + return posix_error_with_allocated_filename(opath); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; } @@ -2045,19 +2096,21 @@ static PyObject * posix_lchown(PyObject *self, PyObject *args) { - char *path = NULL; + PyObject *opath; + char *path; int uid, gid; int res; - if (!PyArg_ParseTuple(args, "etii:lchown", - Py_FileSystemDefaultEncoding, &path, + if (!PyArg_ParseTuple(args, "O&ii:lchown", + PyUnicode_FSConverter, &opath, &uid, &gid)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS res = lchown(path, (uid_t) uid, (gid_t) gid); Py_END_ALLOW_THREADS if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); + return posix_error_with_allocated_filename(opath); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; } @@ -2113,7 +2166,7 @@ return posix_error(); if (use_bytes) return PyBytes_FromStringAndSize(buf, strlen(buf)); - return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict"); + return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"utf8b"); } PyDoc_STRVAR(posix_getcwd__doc__, @@ -2146,7 +2199,7 @@ static PyObject * posix_link(PyObject *self, PyObject *args) { - return posix_2str(args, "etet:link", link); + return posix_2str(args, "O&O&:link", link); } #endif /* HAVE_LINK */ @@ -2259,9 +2312,16 @@ } #endif - if (!PyArg_ParseTuple(args, "et#:listdir", - Py_FileSystemDefaultEncoding, &bufptr, &len)) + if (!PyArg_ParseTuple(args, "O&:listdir", + PyUnicode_FSConverter, &opath)) return NULL; + if (PyObject_Size(opath)+1 > MAX_PATH) { + PyErr_SetString(PyExc_ValueError, "path too long"); + Py_DECREF(opath); + return NULL; + } + strcpy(namebuf, bytes2str(opath, 0)); + len = PyObject_Size(opath); if (len > 0) { char ch = namebuf[len-1]; if (ch != SEP && ch != ALTSEP && ch != ':') @@ -2323,6 +2383,7 @@ #ifndef MAX_PATH #define MAX_PATH CCHMAXPATH #endif + PyObject *oname; char *name, *pt; Py_ssize_t len; PyObject *d, *v; @@ -2332,11 +2393,13 @@ FILEFINDBUF3 ep; APIRET rc; - if (!PyArg_ParseTuple(args, "et#:listdir", - Py_FileSystemDefaultEncoding, &name, &len)) + if (!PyArg_ParseTuple(args, "O&:listdir", + PyUnicode_FSConverter, &oname)) return NULL; + name = bytes2str(oname); + len = PyObject_Size(oname); if (len >= MAX_PATH) { - PyMem_Free(name); + release_bytes(oname); PyErr_SetString(PyExc_ValueError, "path too long"); return NULL; } @@ -2349,7 +2412,7 @@ strcpy(namebuf + len, "*.*"); if ((d = PyList_New(0)) == NULL) { - PyMem_Free(name); + release_bytes(oname); return NULL; } @@ -2362,7 +2425,7 @@ if (rc != NO_ERROR) { errno = ENOENT; - return posix_error_with_allocated_filename(name); + return posix_error_with_allocated_filename(oname); } if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */ @@ -2392,11 +2455,11 @@ } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0); } - PyMem_Free(name); + release_bytes(oname); return d; #else - - char *name = NULL; + PyObject *oname; + char *name; PyObject *d, *v; DIR *dirp; struct dirent *ep; @@ -2407,14 +2470,15 @@ arg_is_unicode = 0; PyErr_Clear(); } - if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name)) + if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname)) return NULL; + name = bytes2str(oname, 1); if ((dirp = opendir(name)) == NULL) { - return posix_error_with_allocated_filename(name); + return posix_error_with_allocated_filename(oname); } if ((d = PyList_New(0)) == NULL) { closedir(dirp); - PyMem_Free(name); + release_bytes(oname); return NULL; } for (;;) { @@ -2428,7 +2492,7 @@ } else { closedir(dirp); Py_DECREF(d); - return posix_error_with_allocated_filename(name); + return posix_error_with_allocated_filename(oname); } } if (ep->d_name[0] == '.' && @@ -2446,18 +2510,16 @@ w = PyUnicode_FromEncodedObject(v, Py_FileSystemDefaultEncoding, - "strict"); - if (w != NULL) { - Py_DECREF(v); + "utf8b"); + Py_DECREF(v); + if (w != NULL) v = w; - } else { - /* Ignore undecodable filenames, as discussed - * in issue 3187. To include these, - * use getcwdb(). */ - PyErr_Clear(); - Py_DECREF(v); - continue; + /* Encoding failed to decode ASCII bytes. + Raise exception. */ + Py_DECREF(d); + d = NULL; + break; } } if (PyList_Append(d, v) != 0) { @@ -2469,7 +2531,7 @@ Py_DECREF(v); } closedir(dirp); - PyMem_Free(name); + release_bytes(oname); return d; @@ -2481,10 +2543,8 @@ static PyObject * posix__getfullpathname(PyObject *self, PyObject *args) { - /* assume encoded strings won't more than double no of chars */ - char inbuf[MAX_PATH*2]; - char *inbufp = inbuf; - Py_ssize_t insize = sizeof(inbuf); + PyObject *opath; + char *path; char outbuf[MAX_PATH*2]; char *temp; #ifdef Py_WIN_WIDE_FILENAMES @@ -2518,13 +2578,17 @@ PyErr_Clear(); } #endif - if (!PyArg_ParseTuple (args, "et#:_getfullpathname", - Py_FileSystemDefaultEncoding, &inbufp, - &insize)) + if (!PyArg_ParseTuple (args, "O&:_getfullpathname", + PyUnicode_FSConverter, &opath)) return NULL; - if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]), - outbuf, &temp)) - return win32_error("GetFullPathName", inbuf); + path = bytes2str(opath, 1); + if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]), + outbuf, &temp)) { + win32_error("GetFullPathName", path); + release_bytes(opath); + return NULL; + } + release_bytes(path); if (PyUnicode_Check(PyTuple_GetItem(args, 0))) { return PyUnicode_Decode(outbuf, strlen(outbuf), Py_FileSystemDefaultEncoding, NULL); @@ -2541,7 +2605,8 @@ posix_mkdir(PyObject *self, PyObject *args) { int res; - char *path = NULL; + PyObject *opath; + char *path; int mode = 0777; #ifdef Py_WIN_WIDE_FILENAMES @@ -2562,9 +2627,10 @@ are also valid. */ PyErr_Clear(); } - if (!PyArg_ParseTuple(args, "et|i:mkdir", - Py_FileSystemDefaultEncoding, &path, &mode)) + if (!PyArg_ParseTuple(args, "O&|i:mkdir", + PyUnicode_FSConverter, &opath, &mode)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS /* PyUnicode_AS_UNICODE OK without thread lock as it is a simple dereference. */ @@ -2572,17 +2638,18 @@ Py_END_ALLOW_THREADS if (!res) { win32_error("mkdir", path); - PyMem_Free(path); + release_bytes(opath); return NULL; } - PyMem_Free(path); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; #else - if (!PyArg_ParseTuple(args, "et|i:mkdir", - Py_FileSystemDefaultEncoding, &path, &mode)) + if (!PyArg_ParseTuple(args, "O&|i:mkdir", + PyUnicode_FSConverter, &opath, &mode)) return NULL; + path = bytes2str(opath, 1); Py_BEGIN_ALLOW_THREADS #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__) res = mkdir(path); @@ -2591,8 +2658,8 @@ #endif Py_END_ALLOW_THREADS if (res < 0) - return posix_error_with_allocated_filename(path); - PyMem_Free(path); + return posix_error_with_allocated_filename(opath); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; #endif @@ -2684,7 +2751,7 @@ Py_INCREF(Py_None); return Py_None; #else - return posix_2str(args, "etet:rename", rename); + return posix_2str(args, "O&O&:rename", rename); #endif } @@ -2699,7 +2766,7 @@ #ifdef MS_WINDOWS return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW); #else - return posix_1str(args, "et:rmdir", rmdir); + return posix_1str(args, "O&:rmdir", rmdir); #endif } @@ -2712,9 +2779,9 @@ posix_stat(PyObject *self, PyObject *args) { #ifdef MS_WINDOWS - return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat); + return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_wstat); #else - return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL); + return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL); #endif } @@ -2780,7 +2847,7 @@ #ifdef MS_WINDOWS return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW); #else - return posix_1str(args, "et:remove", unlink); + return posix_1str(args, "O&:remove", unlink); #endif } @@ -2852,7 +2919,8 @@ PyObject *arg; PyUnicodeObject *obwpath; wchar_t *wpath = NULL; - char *apath = NULL; + PyObject *oapath; + char *apath; HANDLE hFile; long atimesec, mtimesec, ausec, musec; FILETIME atime, mtime; @@ -2874,9 +2942,10 @@ PyErr_Clear(); } if (!wpath) { - if (!PyArg_ParseTuple(args, "etO:utime", - Py_FileSystemDefaultEncoding, &apath, &arg)) + if (!PyArg_ParseTuple(args, "O&O:utime", + PyUnicode_FSConverter, &oapath, &arg)) return NULL; + apath = bytes2str(oapath); Py_BEGIN_ALLOW_THREADS hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, @@ -2884,10 +2953,10 @@ Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { win32_error("utime", apath); - PyMem_Free(apath); + release(oapath); return NULL; } - PyMem_Free(apath); + release_bytes(oapath); } if (arg == Py_None) { @@ -2928,7 +2997,8 @@ return result; #else /* Py_WIN_WIDE_FILENAMES */ - char *path = NULL; + PyObject *opath; + char *path; long atime, mtime, ausec, musec; int res; PyObject* arg; @@ -2951,9 +3021,10 @@ #endif /* HAVE_UTIMES */ - if (!PyArg_ParseTuple(args, "etO:utime", - Py_FileSystemDefaultEncoding, &path, &arg)) + if (!PyArg_ParseTuple(args, "O&O:utime", + PyUnicode_FSConverter, &opath, &arg)) return NULL; + path = bytes2str(opath, 1); if (arg == Py_None) { /* optional time values not given */ Py_BEGIN_ALLOW_THREADS @@ -2963,18 +3034,18 @@ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) { PyErr_SetString(PyExc_TypeError, "utime() arg 2 must be a tuple (atime, mtime)"); - PyMem_Free(path); + release_bytes(opath); return NULL; } else { if (extract_time(PyTuple_GET_ITEM(arg, 0), &atime, &ausec) == -1) { - PyMem_Free(path); + release_bytes(opath); return NULL; } if (extract_time(PyTuple_GET_ITEM(arg, 1), &mtime, &musec) == -1) { - PyMem_Free(path); + release_bytes(opath); return NULL; } ATIME = atime; @@ -2992,9 +3063,9 @@ #endif /* HAVE_UTIMES */ } if (res < 0) { - return posix_error_with_allocated_filename(path); + return posix_error_with_allocated_filename(opath); } - PyMem_Free(path); + release_bytes(opath); Py_INCREF(Py_None); return Py_None; #undef UTIME_ARG @@ -3029,6 +3100,22 @@ PyMem_Free(array[i]); PyMem_DEL(array); } + +int fsconvert_strdup(PyObject *o, char**out) +{ + PyObject *bytes; + Py_ssize_t size; + if (!PyUnicode_FSConverter(o, &bytes)) + return 0; + size = PyObject_Size(bytes); + *out = PyMem_Malloc(size+1); + if (!*out) + return 0; + /* Don't lock bytes, as we hold the GIL */ + memcpy(*out, bytes2str(bytes, 0), size+1); + Py_DECREF(bytes); + return 1; +} #endif @@ -3043,6 +3130,7 @@ static PyObject * posix_execv(PyObject *self, PyObject *args) { + PyObject *opath; char *path; PyObject *argv; char **argvlist; @@ -3052,10 +3140,11 @@ /* execv has two arguments: (path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "etO:execv", - Py_FileSystemDefaultEncoding, - &path, &argv)) + if (!PyArg_ParseTuple(args, "O&O:execv", + PyUnicode_FSConverter, + &opath, &argv)) return NULL; + path = bytes2str(opath, 1); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -3066,28 +3155,27 @@ } else { PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list"); - PyMem_Free(path); + release_bytes(opath); return NULL; } if (argc < 1) { PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); - PyMem_Free(path); + release_bytes(opath); return NULL; } argvlist = PyMem_NEW(char *, argc+1); if (argvlist == NULL) { - PyMem_Free(path); + release_bytes(opath); return PyErr_NoMemory(); } for (i = 0; i < argc; i++) { - if (!PyArg_Parse((*getitem)(argv, i), "et", - Py_FileSystemDefaultEncoding, - &argvlist[i])) { + if (!fsconvert_strdup((*getitem)(argv, i), + &argvlist[i])) { free_string_array(argvlist, i); PyErr_SetString(PyExc_TypeError, "execv() arg 2 must contain only strings"); - PyMem_Free(path); + release_bytes(opath); return NULL; } @@ -3099,7 +3187,7 @@ /* If we get here it's definitely an error */ free_string_array(argvlist, argc); - PyMem_Free(path); + release_bytes(opath); return posix_error(); } @@ -3115,6 +3203,7 @@ static PyObject * posix_execve(PyObject *self, PyObject *args) { + PyObject *opath; char *path; PyObject *argv, *env; char **argvlist; @@ -3128,10 +3217,11 @@ argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - if (!PyArg_ParseTuple(args, "etOO:execve", - Py_FileSystemDefaultEncoding, - &path, &argv, &env)) + if (!PyArg_ParseTuple(args, "O&OO:execve", + PyUnicode_FSConverter, + &opath, &argv, &env)) return NULL; + path = bytes2str(opath, 1); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -3157,10 +3247,8 @@ goto fail_0; } for (i = 0; i < argc; i++) { - if (!PyArg_Parse((*getitem)(argv, i), - "et;execve() arg 2 must contain only strings", - Py_FileSystemDefaultEncoding, - &argvlist[i])) + if (!fsconvert_strdup((*getitem)(argv, i), + &argvlist[i])) { lastarg = i; goto fail_1; @@ -3242,7 +3330,7 @@ Py_XDECREF(vals); Py_XDECREF(keys); fail_0: - PyMem_Free(path); + release_bytes(opath); return NULL; } #endif /* HAVE_EXECV */ @@ -3260,8 +3348,10 @@ static PyObject * posix_spawnv(PyObject *self, PyObject *args) { + PyObject *opath; char *path; PyObject *argv; + PyObject **oargvlist; char **argvlist; int mode, i; Py_ssize_t argc; @@ -3271,10 +3361,11 @@ /* spawnv has three arguments: (mode, path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode, - Py_FileSystemDefaultEncoding, - &path, &argv)) + if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode, + PyUnicode_FSConverter, + &opath, &argv)) return NULL; + path = bytes2str(opath); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -3286,24 +3377,23 @@ else { PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list"); - PyMem_Free(path); + release_bytes(opath); return NULL; } argvlist = PyMem_NEW(char *, argc+1); if (argvlist == NULL) { - PyMem_Free(path); + release_bytes(opath); return PyErr_NoMemory(); } for (i = 0; i < argc; i++) { - if (!PyArg_Parse((*getitem)(argv, i), "et", - Py_FileSystemDefaultEncoding, - &argvlist[i])) { + if (!fsconvert_strdup((*getitem)(argv, i), + &oargvlist[i])) { free_string_array(argvlist, i); PyErr_SetString( PyExc_TypeError, "spawnv() arg 2 must contain only strings"); - PyMem_Free(path); + release_bytes(opath); return NULL; } } @@ -3323,7 +3413,7 @@ #endif free_string_array(argvlist, argc); - PyMem_Free(path); + release_bytes(opath); if (spawnval == -1) return posix_error(); @@ -3348,6 +3438,7 @@ static PyObject * posix_spawnve(PyObject *self, PyObject *args) { + PyObject *opath; char *path; PyObject *argv, *env; char **argvlist; @@ -3363,10 +3454,11 @@ argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode, - Py_FileSystemDefaultEncoding, - &path, &argv, &env)) + if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode, + PyUnicode_FSConverter, + &opath, &argv, &env)) return NULL; + path = bytes2str(opath); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -3392,10 +3484,8 @@ goto fail_0; } for (i = 0; i < argc; i++) { - if (!PyArg_Parse((*getitem)(argv, i), - "et;spawnve() arg 2 must contain only strings", - Py_FileSystemDefaultEncoding, - &argvlist[i])) + if (!fsconvert_strdup((*getitem)(argv, i), + &argvlist[i])) { lastarg = i; goto fail_1; @@ -3485,7 +3575,7 @@ Py_XDECREF(vals); Py_XDECREF(keys); fail_0: - PyMem_Free(path); + release_bytes(opath); return res; } @@ -3503,6 +3593,7 @@ static PyObject * posix_spawnvp(PyObject *self, PyObject *args) { + PyObject *opath; char *path; PyObject *argv; char **argvlist; @@ -3513,10 +3604,11 @@ /* spawnvp has three arguments: (mode, path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode, - Py_FileSystemDefaultEncoding, - &path, &argv)) + if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode, + PyUnicode_FSConverter, + &opath, &argv)) return NULL; + path = bytes2str(opath); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -3528,24 +3620,23 @@ else { PyErr_SetString(PyExc_TypeError, "spawnvp() arg 2 must be a tuple or list"); - PyMem_Free(path); + release_bytes(opath); return NULL; } argvlist = PyMem_NEW(char *, argc+1); if (argvlist == NULL) { - PyMem_Free(path); + release_bytes(opath); return PyErr_NoMemory(); } for (i = 0; i < argc; i++) { - if (!PyArg_Parse((*getitem)(argv, i), "et", - Py_FileSystemDefaultEncoding, - &argvlist[i])) { + if (!fsconvert_strdup((*getitem)(argv, i), + &argvlist[i])) { free_string_array(argvlist, i); PyErr_SetString( PyExc_TypeError, "spawnvp() arg 2 must contain only strings"); - PyMem_Free(path); + release_bytes(opath); return NULL; } } @@ -3560,7 +3651,7 @@ Py_END_ALLOW_THREADS free_string_array(argvlist, argc); - PyMem_Free(path); + release_bytes(opath); if (spawnval == -1) return posix_error(); @@ -3582,6 +3673,7 @@ static PyObject * posix_spawnvpe(PyObject *self, PyObject *args) { + PyObject *opath char *path; PyObject *argv, *env; char **argvlist; @@ -3597,9 +3689,10 @@ like posix.environ. */ if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode, - Py_FileSystemDefaultEncoding, - &path, &argv, &env)) + PyUnicode_FSConverter, + &opath, &argv, &env)) return NULL; + path = bytes2str(opath); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -3625,10 +3718,8 @@ goto fail_0; } for (i = 0; i < argc; i++) { - if (!PyArg_Parse((*getitem)(argv, i), - "et;spawnvpe() arg 2 must contain only strings", - Py_FileSystemDefaultEncoding, - &argvlist[i])) + if (!fsconvert_strdup((*getitem)(argv, i), + &argvlist[i])) { lastarg = i; goto fail_1; @@ -3709,7 +3800,7 @@ Py_XDECREF(vals); Py_XDECREF(keys); fail_0: - PyMem_Free(path); + release_bytes(opath); return res; } #endif /* PYOS_OS2 */ @@ -4548,12 +4639,12 @@ posix_lstat(PyObject *self, PyObject *args) { #ifdef HAVE_LSTAT - return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL); + return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL); #else /* !HAVE_LSTAT */ #ifdef MS_WINDOWS - return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat); + return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", win32_wstat); #else - return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL); + return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL); #endif #endif /* !HAVE_LSTAT */ } @@ -4569,16 +4660,18 @@ { PyObject* v; char buf[MAXPATHLEN]; + PyObject *opath; char *path; int n; int arg_is_unicode = 0; - if (!PyArg_ParseTuple(args, "et:readlink", - Py_FileSystemDefaultEncoding, &path)) + if (!PyArg_ParseTuple(args, "O&:readlink", + PyUnicode_FSConverter, &opath)) return NULL; + path = bytes2str(opath, 1); v = PySequence_GetItem(args, 0); if (v == NULL) { - PyMem_Free(path); + release_bytes(opath); return NULL; } @@ -4591,16 +4684,16 @@ n = readlink(path, buf, (int) sizeof buf); Py_END_ALLOW_THREADS if (n < 0) - return posix_error_with_allocated_filename(path); + return posix_error_with_allocated_filename(opath); - PyMem_Free(path); + release_bytes(opath); v = PyBytes_FromStringAndSize(buf, n); if (arg_is_unicode) { PyObject *w; w = PyUnicode_FromEncodedObject(v, Py_FileSystemDefaultEncoding, - "strict"); + "utf8b"); if (w != NULL) { Py_DECREF(v); v = w; @@ -4622,7 +4715,7 @@ static PyObject * posix_symlink(PyObject *self, PyObject *args) { - return posix_2str(args, "etet:symlink", symlink); + return posix_2str(args, "O&O&:symlink", symlink); } #endif /* HAVE_SYMLINK */ @@ -4810,7 +4903,8 @@ static PyObject * posix_open(PyObject *self, PyObject *args) { - char *file = NULL; + PyObject *ofile; + char *file; int flag; int mode = 0777; int fd; @@ -4834,17 +4928,17 @@ } #endif - if (!PyArg_ParseTuple(args, "eti|i", - Py_FileSystemDefaultEncoding, &file, + if (!PyArg_ParseTuple(args, "O&i|i", + PyUnicode_FSConverter, &ofile, &flag, &mode)) return NULL; - + file = bytes2str(ofile, 1); Py_BEGIN_ALLOW_THREADS fd = open(file, flag, mode); Py_END_ALLOW_THREADS if (fd < 0) - return posix_error_with_allocated_filename(file); - PyMem_Free(file); + return posix_error_with_allocated_filename(ofile); + release_bytes(ofile); return PyLong_FromLong((long)fd); } @@ -6728,20 +6822,21 @@ #endif normal: - if (!PyArg_ParseTuple(args, "et|s:startfile", - Py_FileSystemDefaultEncoding, &filepath, + if (!PyArg_ParseTuple(args, "O&|s:startfile", + PyUnicode_FSConverter, &ofilepath, &operation)) return NULL; + filepath = bytes2str(ofilepath); Py_BEGIN_ALLOW_THREADS rc = ShellExecute((HWND)0, operation, filepath, NULL, NULL, SW_SHOWNORMAL); Py_END_ALLOW_THREADS if (rc <= (HINSTANCE)32) { PyObject *errval = win32_error("startfile", filepath); - PyMem_Free(filepath); + release_bytes(ofilepath); return errval; } - PyMem_Free(filepath); + release_bytes(ofilepath); Py_INCREF(Py_None); return Py_None; } Index: pyconfig.h.in =================================================================== --- pyconfig.h.in (.../py3k) (Revision 72215) +++ pyconfig.h.in (.../pep-0383) (Revision 72247) @@ -419,6 +419,9 @@ /* Define this if you have the makedev macro. */ #undef HAVE_MAKEDEV +/* Define to 1 if you have the `mbrtowc' function. */ +#undef HAVE_MBRTOWC + /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE Eigenschaftsänderungen: . ___________________________________________________________________ Gelöscht: svnmerge-blocked - /python/trunk:61438,61442,61454,61475,61478,61486,61489,61491-61492,61529,61564,61570,61577,61585,61587,61590,61779,61810,61867,61871,61875,61878-61882,61904,61936-61937,61940,62005-62006,62015,62019-62020,62023,62025-62026,62028,62030,62067,62075,62095,62097,62099,62103,62123,62126,62138,62143,62195,62223,62309-62310,62398,62431,62511,62517-62518,62536,62599,62666,62684,62720,62722,62793,62797,62861,62865,62879,62884,62888,62900,62912,62917,62920,62923,62943,62960,62962,62968,62971,62974,62977,62983,62985-62986,63004,63007-63008,63013,63018,63021,63025,63030,63046,63055,63080,63086,63098,63100,63105,63108,63114,63129,63134,63145,63149-63150,63153-63154,63166,63177-63180,63187,63191,63195,63207,63210,63213,63218,63225,63228,63233,63236,63240,63242,63249,63255,63260,63262,63265,63268,63271,63274,63277,63279,63282,63285,63288,63291,63294,63297,63300,63303,63306,63308,63315,63323,63326,63336,63343,63347,63354,63358,63374,63376,63381-63382,63384,63392,63403,63408-63410,63413-63415,63421-63422,63425-63426,63428,63430,63434,63440,63458,63469,63481,63485-63491,63493-63495,63498,63513,63528,63537,63545,63547,63549,63568,63586-63589,63597-63601,63603-63607,63611,63617-63618,63630,63649,63660,63665,63672,63675,63677,63679,63685-63686,63691,63704,63714,63718-63719,63721,63725,63736,63738,63742,63745,63767,63776,63799-63800,63814,63846,63848-63849,63861,63863,63873,63899,63910,63914,63932,63942-63943,63945,63961-63963,63965,63967,63982,64016,64018-64019,64028,64031,64040,64044-64045,64048,64057-64058,64062,64068-64069,64080,64086,64090,64093,64097,64105,64128-64129,64133,64142,64169,64206,64248,64250,64254,64371,64386,64392,64398,64400,64413,64424,64429,64431,64436-64439,64453,64456,64462,64471,64489,64498,64508,64511,64516,64520,64527,64535,64546-64547,64554-64555,64572,64578,64580,64595,64633,64635,64649,64673,64702,64762,64791,64854-64855,64858-64859,64861,64865-64866,64910,64913,64922,64930,64953,64958,64962,64986,65005,65016,65020,65032,65042,65044,65046,65069-65070,65075,65082,65085,65102,65109,65111-65112,65172,65193,65198,65205,65217,65266,65284,65289,65310,65312,65318,65323,65346,65349,65351,65353,65355,65382-65383,65386-65387,65391,65393,65395,65402,65422-65423,65425,65438,65440,65442,65444,65446,65449,65451,65453,65455,65457,65462,65464,65467,65477,65488,65506,65508,65510,65512,65514,65516,65519,65522,65524,65563,65578,65584,65586,65588,65606,65613,65615,65617,65619,65642,65655,65663,65665,65679,65710,65716,65719,65721,65733,65741-65742,65748,65762,65768,65798,65802-65803,65806,65814,65822,65839,65865,65872,65874,65880,65891,65893,65912,65914,65917,65922,65926,65995,66004,66013,66039,66043,66058,66088,66100,66114,66119,66123,66127,66135,66137,66142,66181-66182,66192,66196-66197,66229,66232,66275,66281-66282,66284,66301,66310,66316,66319,66332,66386,66390,66415-66416,66422,66447,66450,66498,66502,66504,66506,66554,66566,66568-66569,66620,66657,66676,66682,66689,66714,66721,66744,66756,66763-66765,66768,66809-66810,66822,66878,67002,67013,67041,67060-67061,67163,67166,67266,67287,67303,67307,67326,67332,67336,67349,67353,67370,67376,67396,67407,67411,67498,67521,67581,67583-67584,67587,67601,67614,67619,67694,67746,67748,67762,67797,67822,67902,67934-67935,67955,67967,67976,67980,68014,68089,68092,68150,68156,68158-68161,68163,68179,68208-68209,68220,68231,68238,68240,68243,68395,68424,68426,68429-68430,68432,68439,68487,68521,68532,68544-68545,68559,68562,68565-68567,68569,68579-68580,68584,68589,68592,68597,68603-68605,68705,68760,68764,68766,68772,68785,68789,68792-68793,68803,68805,68807,68813,68826,68829,68831,68843,68845,68850,68853,68892,68925,68927,68941-68942,68953,68964,68985,68998,69001,69010,69012,69014,69018,69023,69039,69070,69074,69085,69087,69134,69146,69149,69161,69227,69237,69240,69242,69252-69253,69257,69262,69268,69271-69273,69276,69295,69302-69305,69315,69322,69373-69374,69389,69394,69414,69433,69443,69509,69516,69522,69525,69528,69530,69546,69561,69570,69573,69578,69604,69610,69639,69672,69685,69689,69709,69715-69717,69739,69743,69748,69751,69757,69761,69765,69770,69772,69777,69795,69837-69838,69870-69871,69878,69896,69908,69937,69946,69952-69953,69955,69959,69981,69983,69994,70000,70011,70016,70071,70078,70081,70119-70123,70126,70131-70132,70136,70149,70153,70166-70167,70169,70176,70178,70197,70261,70267,70271,70273,70286,70290,70292-70293,70295-70296,70298,70300,70305,70315,70319,70368,70443,70454,70463,70466,70470-70473,70475,70477,70479,70485,70531,70533,70538,70544,70552-70553,70564,70601,70651,70672,70702,70711,70713,70716,70719,70734,70747,70757,70772,70775,70807,70821,70825,70830,70838,70844,70856,70858,70874,70876-70877,70901-70902,70918,70940,70958,70969,70981,70986,70993-70994,71026,71029,71031,71070,71073,71075,71078,71082,71127,71175,71206,71221,71253,71300,71302,71361,71365,71367,71370,71377,71380,71385,71389,71392,71408,71419,71430,71435,71448,71462,71507,71710,71715,71725,71776,71780,71787,71796,71808,71824,71827,71893,71904,71938,71961,71969,72010,72056,72117,72119,72126-72127,72137,72155,72199-72200 Geändert: svnmerge-integrated - /python/trunk:1-61437,61439-61441,61443-61453,61455-61474,61476-61477,61479-61485,61487-61488,61490,61493-61528,61530-61563,61565-61569,61571-61576,61578-61584,61586,61588-61589,61591-61778,61780-61809,61811-61866,61868-61870,61872-61874,61876-61877,61883-61903,61905-61935,61938-61939,61941-62004,62007-62014,62016-62018,62021-62022,62024,62027,62029,62031-62066,62068-62074,62076-62094,62096,62098,62100-62102,62104-62122,62124-62125,62127-62137,62139-62142,62144-62194,62196-62222,62224-62308,62311-62397,62399-62430,62432-62510,62512-62516,62519-62535,62537-62598,62600-62665,62667-62683,62685-62719,62721,62723-62792,62794-62796,62798-62860,62862-62864,62866-62878,62880-62883,62885-62887,62889-62899,62901-62911,62913-62916,62918-62919,62921-62922,62924-62942,62944-62959,62961,62963-62967,62969-62970,62972-62973,62975-62976,62978-62982,62984,62987-63003,63005-63006,63009-63012,63014-63017,63019-63020,63022-63024,63026-63029,63031-63045,63047-63054,63056-63079,63081-63085,63087-63097,63099,63101-63104,63106-63107,63109-63113,63115-63128,63130-63133,63135-63144,63146-63148,63151-63152,63155-63165,63167-63176,63181-63186,63188-63190,63192-63194,63196-63206,63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63248,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63342,63344-63346,63348-63353,63355-63357,63359-63373,63375,63377-63380,63383,63385-63391,63393-63402,63404-63407,63411-63412,63416-63420,63423-63424,63427,63429,63431-63433,63435-63439,63441-63457,63459-63468,63470-63480,63482-63484,63492,63496-63497,63499-63512,63514-63527,63529-63536,63538-63544,63546,63548,63550-63567,63569-63585,63590-63596,63602,63608-63610,63612-63616,63619-63629,63631-63648,63650-63659,63661-63664,63666-63671,63673-63674,63676,63678,63680-63684,63687-63690,63692-63703,63705-63713,63715-63717,63720,63722-63724,63726-63735,63737,63739-63741,63743-63744,63746-63766,63768-63775,63777-63798,63801-63813,63815-63845,63847,63850-63860,63862,63864-63872,63874-63898,63900-63909,63911-63913,63915-63931,63933-63941,63944,63946-63960,63964,63966,63968-63981,63983-64015,64017,64020-64027,64029-64030,64032-64039,64041-64043,64046-64047,64049-64056,64059-64061,64063-64067,64070-64079,64081-64085,64087-64089,64091-64092,64094-64096,64098-64104,64106-64127,64130-64132,64134-64141,64143-64168,64170-64205,64207-64247,64249,64251-64253,64255-64370,64372-64385,64387-64391,64393-64397,64399,64401-64412,64414-64423,64425-64428,64430,64432-64435,64440-64452,64454-64455,64457-64461,64463-64470,64472-64488,64490-64497,64499-64507,64509-64510,64512-64515,64517-64519,64521-64526,64528-64534,64536-64545,64548-64553,64556-64571,64573-64577,64579,64581-64594,64596-64632,64634,64636-64648,64650-64672,64674-64701,64703-64761,64763-64790,64792-64853,64856-64857,64860,64862-64864,64867-64909,64911-64912,64914-64921,64923-64929,64931-64952,64954-64957,64959-64961,64963-64985,64987-65004,65006-65015,65017-65019,65021-65031,65033-65041,65043,65045,65047-65068,65071-65074,65076-65081,65083-65084,65086-65101,65103-65108,65110,65113-65171,65173-65192,65194-65197,65199-65204,65206-65216,65218-65265,65267-65283,65285-65288,65290-65309,65311,65313-65317,65319-65322,65324-65345,65347-65348,65350,65352,65354,65356-65381,65384-65385,65388-65390,65392,65394,65396-65401,65403-65421,65424,65426-65437,65439,65441,65443,65445,65447-65448,65450,65452,65454,65456,65458-65461,65463,65465-65466,65468-65476,65478-65487,65489-65505,65507,65509,65511,65513,65515,65517-65518,65520-65521,65523,65525-65562,65564-65577,65579-65583,65585,65587,65589-65605,65607-65612,65614,65616,65618,65620-65641,65643-65654,65656-65662,65664,65666-65678,65680-65709,65711-65715,65717-65718,65720,65722-65732,65734-65740,65743-65747,65749-65761,65763-65767,65769-65797,65799-65801,65804-65805,65807-65813,65815-65821,65823-65838,65840-65864,65866-65871,65873,65875-65879,65881-65890,65892,65894-65911,65913,65915-65916,65918-65921,65923-65925,65927-65994,65996-66003,66005-66012,66014-66038,66040-66042,66044-66057,66059-66087,66089-66099,66101-66113,66115-66118,66120-66122,66124-66126,66128-66134,66136,66138-66141,66143-66180,66183-66191,66193-66195,66198-66228,66230-66231,66233-66274,66276-66280,66283,66285-66300,66302-66309,66311-66315,66317-66318,66320-66331,66333-66385,66387-66389,66391-66414,66417-66421,66423-66446,66448-66449,66451-66497,66499-66501,66503,66505,66507-66553,66555-66565,66567,66570-66619,66621-66656,66658-66675,66677-66681,66683-66688,66690-66713,66715-66720,66722-66743,66745-66755,66757-66762,66766-66767,66769-66808,66811-66821,66823-66877,66879-67001,67003-67012,67014-67040,67042-67059,67062-67162,67164-67165,67167-67265,67267-67286,67288-67302,67304-67306,67308-67325,67327-67331,67333-67335,67337-67348,67350-67352,67354-67369,67371-67375,67377-67395,67397-67406,67408-67410,67412-67497,67499-67520,67522-67580,67582,67585-67586,67588-67600,67602-67613,67615-67618,67620-67693,67695-67745,67747,67749-67761,67763-67796,67798-67821,67823-67901,67903-67933,67936-67954,67956-67966,67968-67975,67977-67979,67981-68013,68015-68088,68090-68091,68093-68149,68151-68155,68157,68162,68164-68178,68180-68207,68210-68219,68221-68230,68232-68237,68239,68241-68242,68244-68394,68396-68423,68425,68427-68428,68431,68433-68438,68440-68486,68488-68520,68522-68531,68533-68543,68546-68558,68560-68561,68563-68564,68568,68570-68578,68581-68583,68585-68588,68590-68591,68593-68596,68598-68602,68606-68704,68706-68759,68761-68763,68765,68767-68771,68773-68784,68786-68788,68790-68791,68794-68802,68804,68806,68808-68812,68814-68825,68827-68828,68830,68832-68842,68844,68846-68849,68851-68852,68854-68891,68893-68924,68926,68928-68940,68943-68952,68954-68963,68965-68984,68986-68997,68999-69000,69002-69009,69011,69013,69015-69017,69019-69022,69024-69038,69040-69069,69071-69073,69075-69084,69086,69088-69133,69135-69145,69147-69148,69150-69160,69162-69226,69228-69236,69238-69239,69241,69243-69251,69254-69256,69258-69261,69263-69267,69269-69270,69274-69275,69277-69294,69296-69301,69306-69314,69316-69321,69323-69372,69375-69388,69390-69393,69395-69413,69415-69432,69434-69442,69444-69508,69510-69515,69517-69521,69523-69524,69526-69527,69529,69531-69545,69547-69560,69562-69569,69571-69572,69574-69577,69579-69603,69605-69609,69611-69638,69640-69671,69673-69684,69686-69688,69690-69708,69710-69714,69718-69738,69740-69742,69744-69747,69749-69750,69752-69756,69758-69760,69762-69764,69766-69769,69771,69773-69776,69778-69794,69796-69836,69839-69869,69872-69877,69879-69895,69897-69907,69909-69936,69938-69945,69947-69951,69954,69956-69958,69960-69980,69982,69984-69993,69995-69999,70001-70010,70012-70015,70017-70070,70072-70077,70079-70080,70082-70118,70124-70125,70127-70130,70133-70135,70137-70148,70150-70152,70154-70165,70168,70170-70175,70177,70179-70196,70198-70260,70262-70266,70268-70270,70272,70274-70281,70308,70342-70367,70369-70442,70444-70453,70455-70462,70464-70465,70467-70468,70489,70499,70518-70530,70532,70534-70537,70539-70543,70545-70551,70554-70563,70565-70600,70602-70650,70652-70671,70673-70701,70703-70706,70712,70714-70715,70717-70718,70720-70733,70735-70746,70748-70756,70758-70767,70769-70771,70773-70774,70776-70806,70808-70820,70822-70824,70826-70829,70831-70837,70839-70843,70845-70855,70857,70859-70873,70875,70878-70900,70903-70917,70919-70939,70941-70957,70959-70968,70970-70980,70982-70985,70987-70992,70995-71025,71027-71028,71030,71032-71069,71071-71072,71074,71076-71077,71079-71081,71083-71126,71128-71174,71176-71205,71207-71252,71254-71299,71301,71303-71360,71362-71364,71366,71368-71369,71371-71376,71378-71379,71381-71384,71386-71388,71390-71391,71393-71407,71409-71418,71420-71429,71431-71434,71436-71447,71449-71461,71463-71494,71498,71509,71513,71523,71528,71533,71539,71548,71553,71560,71569,71579,71585,71589,71627,71631,71640-71641,71651,71674,71705,71719,71722,71734-71739,71743,71750,71758-71759,71766,71772,71785,71788,71799,71802,71812,71832,71837-71838,71842,71847,71853,71860,71869,71875,71878,71884,71894,71906,71920-71937,71947,71963,71972,71984,72167,72173,72178,72180,72183-72184,72189,72202,72210 + /python/branches/py3k:1-72215