Index: Modules/posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.253 diff -c -r2.253 posixmodule.c *** Modules/posixmodule.c 1 Sep 2002 15:06:28 -0000 2.253 --- Modules/posixmodule.c 4 Sep 2002 12:02:06 -0000 *************** *** 481,491 **** return Py_None; } static PyObject * ! posix_1str(PyObject *args, char *format, int (*func)(const char*)) { char *path1 = NULL; int res; if (!PyArg_ParseTuple(args, format, Py_FileSystemDefaultEncoding, &path1)) return NULL; --- 481,524 ---- return Py_None; } + #ifdef Py_WIN_WIDE_FILENAMES + static int + unicode_file_names(void) + { + static int canusewide = -1; + if (canusewide == -1) { + canusewide = (GetVersion() < 0x80000000) ? 1 : 0; + } + return canusewide; + } + #endif + static PyObject * ! posix_1str(PyObject *args, char *format, int (*func)(const char*), ! char *wformat, int (*wfunc)(const Py_UNICODE*)) { char *path1 = NULL; int res; + #ifdef Py_WIN_WIDE_FILENAMES + if (unicode_file_names()) { + PyUnicodeObject *po; + if (PyArg_ParseTuple(args, wformat, &po)) { + Py_BEGIN_ALLOW_THREADS + /* PyUnicode_AS_UNICODE OK without thread + lock as it is a simple dereference. */ + res = (*wfunc)(PyUnicode_AS_UNICODE(po)); + Py_END_ALLOW_THREADS + if (res < 0) + return posix_error(); + Py_INCREF(Py_None); + return Py_None; + } + /* Drop the argument parsing error as narrow + strings are also valid. */ + PyErr_Clear(); + } + #endif + if (!PyArg_ParseTuple(args, format, Py_FileSystemDefaultEncoding, &path1)) return NULL; *************** *** 500,510 **** } static PyObject * ! posix_2str(PyObject *args, char *format, ! int (*func)(const char *, const char *)) { char *path1 = NULL, *path2 = NULL; ! int res; if (!PyArg_ParseTuple(args, format, Py_FileSystemDefaultEncoding, &path1, Py_FileSystemDefaultEncoding, &path2)) --- 533,574 ---- } static PyObject * ! posix_2str(PyObject *args, ! char *format, ! int (*func)(const char *, const char *), ! char *wformat, ! int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *)) { char *path1 = NULL, *path2 = NULL; ! int res; ! #ifdef Py_WIN_WIDE_FILENAMES ! if (unicode_file_names()) { ! PyObject *po1; ! PyObject *po2; ! if (PyArg_ParseTuple(args, wformat, &po1, &po2)) { ! if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) { ! PyObject *wpath1; ! PyObject *wpath2; ! wpath1 = PyUnicode_FromObject(po1); ! wpath2 = PyUnicode_FromObject(po2); ! Py_BEGIN_ALLOW_THREADS ! /* PyUnicode_AS_UNICODE OK without thread ! lock as it is a simple dereference. */ ! res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1), ! PyUnicode_AS_UNICODE(wpath2)); ! Py_END_ALLOW_THREADS ! Py_XDECREF(wpath1); ! Py_XDECREF(wpath2); ! if (res != 0) ! return posix_error(); ! Py_INCREF(Py_None); ! return Py_None; ! } ! /* Else flow through as neither is Unicode. */ ! } ! } ! #endif ! if (!PyArg_ParseTuple(args, format, Py_FileSystemDefaultEncoding, &path1, Py_FileSystemDefaultEncoding, &path2)) *************** *** 678,685 **** } static PyObject * ! posix_do_stat(PyObject *self, PyObject *args, char *format, ! int (*statfunc)(const char *, STRUCT_STAT *)) { STRUCT_STAT st; char *path = NULL; /* pass this to stat; do not free() it */ --- 742,752 ---- } static PyObject * ! posix_do_stat(PyObject *self, PyObject *args, ! char *format, ! int (*statfunc)(const char *, STRUCT_STAT *), ! char *wformat, ! int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *)) { STRUCT_STAT st; char *path = NULL; /* pass this to stat; do not free() it */ *************** *** 691,696 **** --- 758,807 ---- char pathcopy[MAX_PATH]; #endif /* MS_WINDOWS */ + + #ifdef Py_WIN_WIDE_FILENAMES + /* If on wide-character-capable OS see if argument + is Unicode and if so use wide API. */ + if (unicode_file_names()) { + PyUnicodeObject *po; + if (PyArg_ParseTuple(args, wformat, &po)) { + Py_UNICODE wpath[MAX_PATH+1]; + pathlen = wcslen(PyUnicode_AS_UNICODE(po)); + /* the library call can blow up if the file name is too long! */ + if (pathlen > MAX_PATH) { + errno = ENAMETOOLONG; + return posix_error(); + } + wcscpy(wpath, PyUnicode_AS_UNICODE(po)); + /* Remove trailing slash or backslash, unless it's the current + drive root (/ or \) or a specific drive's root (like c:\ or c:/). + */ + if (pathlen > 0 && + (wpath[pathlen-1]== L'\\' || wpath[pathlen-1] == L'/')) { + /* It does end with a slash -- exempt the root drive cases. */ + /* XXX UNC root drives should also be exempted? */ + if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':')) + /* leave it alone */; + else { + /* nuke the trailing backslash */ + wpath[pathlen-1] = L'\0'; + } + } + Py_BEGIN_ALLOW_THREADS + /* PyUnicode_AS_UNICODE result OK without + thread lock as it is a simple dereference. */ + res = wstatfunc(wpath, &st); + Py_END_ALLOW_THREADS + if (res != 0) + return posix_error(); + return _pystat_fromstructstat(st); + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + } + #endif + if (!PyArg_ParseTuple(args, format, Py_FileSystemDefaultEncoding, &path)) return NULL; *************** *** 825,834 **** static PyObject * posix_chdir(PyObject *self, PyObject *args) { ! #if defined(PYOS_OS2) && defined(PYCC_GCC) ! return posix_1str(args, "et:chdir", _chdir2); #else ! return posix_1str(args, "et:chdir", chdir); #endif } --- 936,947 ---- static PyObject * posix_chdir(PyObject *self, PyObject *args) { ! #ifdef MS_WINDOWS ! return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir); ! #elif defined(PYOS_OS2) && defined(PYCC_GCC) ! return posix_1str(args, "et:chdir", _chdir2, NULL, NULL); #else ! return posix_1str(args, "et:chdir", chdir, NULL, NULL); #endif } *************** *** 878,884 **** static PyObject * posix_chroot(PyObject *self, PyObject *args) { ! return posix_1str(args, "et:chroot", chroot); } #endif --- 991,997 ---- static PyObject * posix_chroot(PyObject *self, PyObject *args) { ! return posix_1str(args, "et:chroot", chroot, NULL, NULL); } #endif *************** *** 990,998 **** return posix_error(); return PyString_FromString(buf); } #endif ! #ifdef HAVE_LINK PyDoc_STRVAR(posix_link__doc__, "link(src, dst)\n\n\ --- 1103,1148 ---- return posix_error(); return PyString_FromString(buf); } + + PyDoc_STRVAR(posix_getcwdu__doc__, + "getcwdu() -> path\n\n\ + Return a unicode string representing the current working directory."); + + static PyObject * + posix_getcwdu(PyObject *self, PyObject *args) + { + char buf[1026]; + char *res; + if (!PyArg_ParseTuple(args, ":getcwd")) + return NULL; + + #ifdef Py_WIN_WIDE_FILENAMES + if (unicode_file_names()) { + wchar_t *wres; + wchar_t wbuf[1026]; + Py_BEGIN_ALLOW_THREADS + wres = _wgetcwd(wbuf, sizeof wbuf); + Py_END_ALLOW_THREADS + if (wres == NULL) + return posix_error(); + return PyUnicode_FromWideChar(wbuf, wcslen(wbuf)); + } + #endif + + Py_BEGIN_ALLOW_THREADS + #if defined(PYOS_OS2) && defined(PYCC_GCC) + res = _getcwd2(buf, sizeof buf); + #else + res = getcwd(buf, sizeof buf); + #endif + Py_END_ALLOW_THREADS + if (res == NULL) + return posix_error(); + return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict"); + } #endif ! #ifdef HAVE_LINK PyDoc_STRVAR(posix_link__doc__, "link(src, dst)\n\n\ *************** *** 1001,1007 **** static PyObject * posix_link(PyObject *self, PyObject *args) { ! return posix_2str(args, "etet:link", link); } #endif /* HAVE_LINK */ --- 1151,1157 ---- static PyObject * posix_link(PyObject *self, PyObject *args) { ! return posix_2str(args, "etet:link", link, NULL, NULL); } #endif /* HAVE_LINK */ *************** *** 1029,1034 **** --- 1179,1252 ---- char namebuf[MAX_PATH*2+5]; char *bufptr = namebuf; int len = sizeof(namebuf)/sizeof(namebuf[0]); + + #ifdef Py_WIN_WIDE_FILENAMES + /* If on wide-character-capable OS see if argument + is Unicode and if so use wide API. */ + if (unicode_file_names()) { + PyUnicodeObject *po; + if (PyArg_ParseTuple(args, "U:listdir", &po)) { + WIN32_FIND_DATAW wFileData; + Py_UNICODE wnamebuf[MAX_PATH*2+5]; + Py_UNICODE wch; + int i; + wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH); + wnamebuf[MAX_PATH] = L'\0'; + /* Ensure something indicative if not always + accurate available for error reporting. */ + for (i=0; wnamebuf[i]; i++) { + if (wnamebuf[i] == L'\0') + namebuf[i] = '\0'; + else if (isascii(wnamebuf[i])) + namebuf[i] = (char)(wnamebuf[i]); + else + namebuf[i] = '?'; + } + len = wcslen(wnamebuf); + wch = (len > 0) ? wnamebuf[len-1] : L'\0'; + if (wch != L'/' && wch != L'\\' && wch != L':') + wnamebuf[len++] = L'/'; + wcscpy(wnamebuf + len, L"*.*"); + if ((d = PyList_New(0)) == NULL) + return NULL; + hFindFile = FindFirstFileW(wnamebuf, &wFileData); + if (hFindFile == INVALID_HANDLE_VALUE) { + errno = GetLastError(); + if (errno == ERROR_FILE_NOT_FOUND) { + return PyList_New(0); + } + return win32_error("FindFirstFileW", namebuf); + } + do { + if (wFileData.cFileName[0] == L'.' && + (wFileData.cFileName[1] == L'\0' || + wFileData.cFileName[1] == L'.' && + wFileData.cFileName[2] == L'\0')) + continue; + v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName)); + if (v == NULL) { + Py_DECREF(d); + d = NULL; + break; + } + if (PyList_Append(d, v) != 0) { + Py_DECREF(v); + Py_DECREF(d); + d = NULL; + break; + } + Py_DECREF(v); + } while (FindNextFileW(hFindFile, &wFileData) == TRUE); + + if (FindClose(hFindFile) == FALSE) + return win32_error("FindClose", namebuf); + return d; + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + } + #endif if (!PyArg_ParseTuple(args, "et#:listdir", Py_FileSystemDefaultEncoding, &bufptr, &len)) *************** *** 1198,1204 **** char *inbufp = inbuf; int insize = sizeof(inbuf)/sizeof(inbuf[0]); char outbuf[MAX_PATH*2]; ! char *temp; if (!PyArg_ParseTuple (args, "et#:_getfullpathname", Py_FileSystemDefaultEncoding, &inbufp, &insize)) --- 1416,1439 ---- char *inbufp = inbuf; int insize = sizeof(inbuf)/sizeof(inbuf[0]); char outbuf[MAX_PATH*2]; ! char *temp; ! #ifdef Py_WIN_WIDE_FILENAMES ! if (unicode_file_names()) { ! PyUnicodeObject *po; ! if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) { ! Py_UNICODE woutbuf[MAX_PATH*2]; ! Py_UNICODE *wtemp; ! if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po), ! sizeof(woutbuf)/sizeof(woutbuf[0]), ! woutbuf, &wtemp)) ! return win32_error("GetFullPathName", ""); ! return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf)); ! } ! /* Drop the argument parsing error as narrow strings ! are also valid. */ ! PyErr_Clear(); ! } ! #endif if (!PyArg_ParseTuple (args, "et#:_getfullpathname", Py_FileSystemDefaultEncoding, &inbufp, &insize)) *************** *** 1220,1225 **** --- 1455,1481 ---- int res; char *path = NULL; int mode = 0777; + + #ifdef Py_WIN_WIDE_FILENAMES + if (unicode_file_names()) { + PyUnicodeObject *po; + if (PyArg_ParseTuple(args, "U|i:mkdir", &po)) { + Py_BEGIN_ALLOW_THREADS + /* PyUnicode_AS_UNICODE OK without thread lock as + it is a simple dereference. */ + res = _wmkdir(PyUnicode_AS_UNICODE(po)); + Py_END_ALLOW_THREADS + if (res < 0) + return posix_error(); + Py_INCREF(Py_None); + return Py_None; + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + } + #endif + if (!PyArg_ParseTuple(args, "et|i:mkdir", Py_FileSystemDefaultEncoding, &path, &mode)) return NULL; *************** *** 1288,1294 **** static PyObject * posix_rename(PyObject *self, PyObject *args) { ! return posix_2str(args, "etet:rename", rename); } --- 1544,1554 ---- static PyObject * posix_rename(PyObject *self, PyObject *args) { ! #ifdef MS_WINDOWS ! return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename); ! #else ! return posix_2str(args, "etet:rename", rename, NULL, NULL); ! #endif } *************** *** 1299,1305 **** static PyObject * posix_rmdir(PyObject *self, PyObject *args) { ! return posix_1str(args, "et:rmdir", rmdir); } --- 1559,1569 ---- static PyObject * posix_rmdir(PyObject *self, PyObject *args) { ! #ifdef MS_WINDOWS ! return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir); ! #else ! return posix_1str(args, "et:rmdir", rmdir, NULL, NULL); ! #endif } *************** *** 1310,1316 **** static PyObject * posix_stat(PyObject *self, PyObject *args) { ! return posix_do_stat(self, args, "et:stat", STAT); } --- 1574,1584 ---- static PyObject * posix_stat(PyObject *self, PyObject *args) { ! #ifdef MS_WINDOWS ! return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64); ! #else ! return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL); ! #endif } *************** *** 1362,1368 **** static PyObject * posix_unlink(PyObject *self, PyObject *args) { ! return posix_1str(args, "et:remove", unlink); } --- 1630,1640 ---- static PyObject * posix_unlink(PyObject *self, PyObject *args) { ! #ifdef MS_WINDOWS ! return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink); ! #else ! return posix_1str(args, "et:remove", unlink, NULL, NULL); ! #endif } *************** *** 4092,4100 **** posix_lstat(PyObject *self, PyObject *args) { #ifdef HAVE_LSTAT ! return posix_do_stat(self, args, "et:lstat", lstat); #else /* !HAVE_LSTAT */ ! return posix_do_stat(self, args, "et:lstat", STAT); #endif /* !HAVE_LSTAT */ } --- 4364,4376 ---- posix_lstat(PyObject *self, PyObject *args) { #ifdef HAVE_LSTAT ! return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL); #else /* !HAVE_LSTAT */ ! #ifdef MS_WINDOWS ! return posix_do_stat(self, args, "et:lstat", STAT, "u:lstat", _wstati64); ! #else ! return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL); ! #endif #endif /* !HAVE_LSTAT */ } *************** *** 4130,4136 **** static PyObject * posix_symlink(PyObject *self, PyObject *args) { ! return posix_2str(args, "etet:symlink", symlink); } #endif /* HAVE_SYMLINK */ --- 4406,4412 ---- static PyObject * posix_symlink(PyObject *self, PyObject *args) { ! return posix_2str(args, "etet:symlink", symlink, NULL, NULL); } #endif /* HAVE_SYMLINK */ *************** *** 4311,4316 **** --- 4587,4612 ---- int flag; int mode = 0777; int fd; + + #ifdef MS_WINDOWS + if (unicode_file_names()) { + PyUnicodeObject *po; + if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) { + Py_BEGIN_ALLOW_THREADS + /* PyUnicode_AS_UNICODE OK without thread + lock as it is a simple dereference. */ + fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode); + Py_END_ALLOW_THREADS + if (fd < 0) + return posix_error(); + return PyInt_FromLong((long)fd); + } + /* Drop the argument parsing error as narrow strings + are also valid. */ + PyErr_Clear(); + } + #endif + if (!PyArg_ParseTuple(args, "eti|i", Py_FileSystemDefaultEncoding, &file, &flag, &mode)) *************** *** 6283,6288 **** --- 6579,6585 ---- #endif #ifdef HAVE_GETCWD {"getcwd", posix_getcwd, METH_VARARGS, posix_getcwd__doc__}, + {"getcwdu", posix_getcwdu, METH_VARARGS, posix_getcwdu__doc__}, #endif #ifdef HAVE_LINK {"link", posix_link, METH_VARARGS, posix_link__doc__}, Index: Objects/fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.168 diff -c -r2.168 fileobject.c *** Objects/fileobject.c 14 Aug 2002 21:01:41 -0000 2.168 --- Objects/fileobject.c 4 Sep 2002 12:02:08 -0000 *************** *** 15,20 **** --- 15,26 ---- #include #endif + #ifdef _MSC_VER + /* Need GetVersion to see if on NT so safe to use _wfopen */ + #define WINDOWS_LEAN_AND_MEAN + #include + #endif /* _MSC_VER */ + #ifdef macintosh #ifdef USE_GUSI #define HAVE_FTRUNCATE *************** *** 102,108 **** static PyObject * fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode, ! int (*close)(FILE *)) { assert(f != NULL); assert(PyFile_Check(f)); --- 108,114 ---- static PyObject * fill_file_fields(PyFileObject *f, FILE *fp, char *name, char *mode, ! int (*close)(FILE *), PyObject *wname) { assert(f != NULL); assert(PyFile_Check(f)); *************** *** 110,116 **** Py_DECREF(f->f_name); Py_DECREF(f->f_mode); ! f->f_name = PyString_FromString(name); f->f_mode = PyString_FromString(mode); f->f_close = close; --- 116,125 ---- Py_DECREF(f->f_name); Py_DECREF(f->f_mode); ! if (wname) ! f->f_name = PyUnicode_FromObject(wname); ! else ! f->f_name = PyString_FromString(name); f->f_mode = PyString_FromString(mode); f->f_close = close; *************** *** 156,162 **** else #endif { - Py_BEGIN_ALLOW_THREADS #ifdef WITH_UNIVERSAL_NEWLINES if (strcmp(mode, "U") == 0 || strcmp(mode, "rU") == 0) mode = "rb"; --- 165,170 ---- *************** *** 168,175 **** if (strcmp(mode, "U") == 0 || strcmp(mode, "rU") == 0) mode = "r"; #endif ! f->f_fp = fopen(name, mode); ! Py_END_ALLOW_THREADS } if (f->f_fp == NULL) { #ifdef NO_FOPEN_ERRNO --- 176,201 ---- if (strcmp(mode, "U") == 0 || strcmp(mode, "rU") == 0) mode = "r"; #endif ! #ifdef MS_WINDOWS ! if (PyUnicode_Check(f->f_name)) { ! PyObject *wmode; ! wmode = PyUnicode_DecodeASCII(mode, strlen(mode), NULL); ! if (f->f_name && wmode) { ! Py_BEGIN_ALLOW_THREADS ! /* PyUnicode_AS_UNICODE OK without thread ! lock as it is a simple dereference. */ ! f->f_fp = _wfopen(PyUnicode_AS_UNICODE(f->f_name), ! PyUnicode_AS_UNICODE(wmode)); ! Py_END_ALLOW_THREADS ! } ! Py_XDECREF(wmode); ! } ! #endif ! if (NULL == f->f_fp) { ! Py_BEGIN_ALLOW_THREADS ! f->f_fp = fopen(name, mode); ! Py_END_ALLOW_THREADS ! } } if (f->f_fp == NULL) { #ifdef NO_FOPEN_ERRNO *************** *** 215,221 **** PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type, NULL, NULL); if (f != NULL) { ! if (fill_file_fields(f, fp, name, mode, close) == NULL) { Py_DECREF(f); f = NULL; } --- 241,247 ---- PyFileObject *f = (PyFileObject *)PyFile_Type.tp_new(&PyFile_Type, NULL, NULL); if (f != NULL) { ! if (fill_file_fields(f, fp, name, mode, close, NULL) == NULL) { Py_DECREF(f); f = NULL; } *************** *** 293,303 **** static PyObject * file_repr(PyFileObject *f) { ! return PyString_FromFormat("<%s file '%s', mode '%s' at %p>", f->f_fp == NULL ? "closed" : "open", PyString_AsString(f->f_name), PyString_AsString(f->f_mode), f); } static PyObject * --- 319,342 ---- static PyObject * file_repr(PyFileObject *f) { ! if (PyUnicode_Check(f->f_name)) { ! PyObject *ret = NULL; ! PyObject *name; ! name = PyUnicode_AsUnicodeEscapeString(f->f_name); ! ret = PyString_FromFormat("<%s file u'%s', mode '%s' at %p>", ! f->f_fp == NULL ? "closed" : "open", ! PyString_AsString(name), ! PyString_AsString(f->f_mode), ! f); ! Py_XDECREF(name); ! return ret; ! } else { ! return PyString_FromFormat("<%s file '%s', mode '%s' at %p>", f->f_fp == NULL ? "closed" : "open", PyString_AsString(f->f_name), PyString_AsString(f->f_mode), f); + } } static PyObject * *************** *** 1766,1771 **** --- 1805,1811 ---- char *name = NULL; char *mode = "r"; int bufsize = -1; + int wideargument = 0; assert(PyFile_Check(self)); if (foself->f_fp != NULL) { *************** *** 1776,1787 **** Py_DECREF(closeresult); } ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist, ! Py_FileSystemDefaultEncoding, &name, ! &mode, &bufsize)) ! return -1; ! if (fill_file_fields(foself, NULL, name, mode, fclose) == NULL) ! goto Error; if (open_the_file(foself, name, mode) == NULL) goto Error; PyFile_SetBufSize(self, bufsize); --- 1816,1848 ---- Py_DECREF(closeresult); } ! #ifdef Py_WIN_WIDE_FILENAMES ! if (GetVersion() < 0x80000000) { /* On NT, so wide API available */ ! PyObject *po; ! if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:file", ! kwlist, &po, &mode, &bufsize)) { ! wideargument = 1; ! if (fill_file_fields(foself, NULL, name, mode, ! fclose, po) == NULL) ! goto Error; ! } else { ! /* Drop the argument parsing error as narrow ! strings are also valid. */ ! PyErr_Clear(); ! } ! } ! #endif ! ! if (!wideargument) { ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:file", kwlist, ! Py_FileSystemDefaultEncoding, ! &name, ! &mode, &bufsize)) ! return -1; ! if (fill_file_fields(foself, NULL, name, mode, ! fclose, NULL) == NULL) ! goto Error; ! } if (open_the_file(foself, name, mode) == NULL) goto Error; PyFile_SetBufSize(self, bufsize); Index: PC/pyconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/pyconfig.h,v retrieving revision 1.14 diff -c -r1.14 pyconfig.h *** PC/pyconfig.h 19 Jul 2002 06:55:41 -0000 1.14 --- PC/pyconfig.h 4 Sep 2002 12:02:08 -0000 *************** *** 399,405 **** means wchar_t must be 16-bit unsigned type. (see Include/unicodeobject.h). */ #if Py_UNICODE_SIZE == 2 ! #define HAVE_USABLE_WCHAR_T #endif /* Use Python's own small-block memory-allocator. */ --- 399,409 ---- means wchar_t must be 16-bit unsigned type. (see Include/unicodeobject.h). */ #if Py_UNICODE_SIZE == 2 ! #define HAVE_USABLE_WCHAR_T ! ! /* Define to indicate that the Python Unicode representation can be passed ! as-is to Win32 Wide API. */ ! #define Py_WIN_WIDE_FILENAMES #endif /* Use Python's own small-block memory-allocator. */ --- /dev/null Wed Sep 4 12:02:39 2002 +++ Lib/test/test_pep277.py Wed Sep 4 11:11:30 2002 @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# Test the Unicode versions of normal file functions +# open, os.open, os.stat. os.listdir, os.rename, os.remove, os.mkdir, os.chdir, os.rmdir +import os, unittest +from test.test_support import TESTFN, TestSkipped, run_suite +try: + from nt import _getfullpathname +except ImportError: + raise TestSkipped, "test works only on NT" + +filenames = [ + "abc", + unicode("ascii","utf-8"), + unicode("Grüß-Gott","utf-8"), + unicode("Γειά-σας","utf-8"), + unicode("Здравствуйте","utf-8"), + unicode("にぽん","utf-8"), + unicode("השקצץס","utf-8"), + unicode("曨曩曫","utf-8"), + unicode("曨שんдΓß","utf-8"), + ] + +class UnicodeFileTests(unittest.TestCase): + def setUp(self): + self.files = [os.path.join(TESTFN, f) for f in filenames] + try: + os.mkdir(TESTFN) + except OSError: + pass + for name in self.files: + f = open(name, 'w') + f.write((name+'\n').encode("utf-8")) + f.close() + os.stat(name) + + def tearDown(self): + for name in self.files: + os.unlink(name) + os.rmdir(TESTFN) + + def test_open(self): + for name in self.files: + f = open(name, 'w') + f.write((name+'\n').encode("utf-8")) + f.close() + os.stat(name) + + def test_listdir(self): + f1 = os.listdir(TESTFN) + f1.sort() + f2 = os.listdir(unicode(TESTFN,"mbcs")) + f2.sort + print f1 + print f2 + + def test_rename(self): + for name in self.files: + os.rename(name,"tmp") + os.rename("tmp",name) + + def test_directory(self): + dirname = unicode(os.path.join(TESTFN,"Grüß-曨曩曫"),"utf-8") + filename = unicode("ß-曨曩曫","utf-8") + oldwd = os.getcwd() + os.mkdir(dirname) + os.chdir(dirname) + f = open(filename, 'w') + f.write((filename + '\n').encode("utf-8")) + f.close() + print repr(_getfullpathname(filename)) + os.remove(filename) + os.chdir(oldwd) + os.rmdir(dirname) + +def test_main(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(UnicodeFileTests)) + run_suite(suite) + +if __name__ == "__main__": + test_main()