Issue #3080: Use Unicode to import source and compiled modules

* Use Unicode for module name and path in the following functions:

   * get_file()
   * load_source_module(), parse_source_module()
   * make_compiled_pathname(), check_compiled_module(),
     read_compiled_module(), load_compiled_module(), write_compiled_module(),
     update_compiled_module()

 * On Windows, use CreateDirectoryW() instead of mkdir()
 * update_compiled_module() cannot fail anymore
This commit is contained in:
Victor Stinner 2011-03-20 00:41:24 +01:00
parent c9abda0c04
commit 2f42ae53aa
1 changed files with 203 additions and 153 deletions

View File

@ -107,8 +107,8 @@ typedef unsigned short mode_t;
/* MAGIC must change whenever the bytecode emitted by the compiler may no
longer be understood by older implementations of the eval loop (usually
due to the addition of new opcodes)
TAG must change for each major Python release. The magic number will take
care of any bytecode changes that occur during development.
TAG and PYC_TAG_UNICODE must change for each major Python release. The magic
number will take care of any bytecode changes that occur during development.
*/
#define MAGIC (3180 | ((long)'\r'<<16) | ((long)'\n'<<24))
#define TAG "cpython-32"
@ -118,6 +118,8 @@ static const Py_UNICODE CACHEDIR_UNICODE[] = {
/* Current magic word and string tag as globals. */
static long pyc_magic = MAGIC;
static const char *pyc_tag = TAG;
static const Py_UNICODE PYC_TAG_UNICODE[] = {
'c', 'p', 'y', 't', 'h', 'o', 'n', '-', '3', '2', '\0'};
/* See _PyImport_FixupExtensionObject() below */
static PyObject *extensions = NULL;
@ -745,8 +747,7 @@ remove_module(PyObject *name)
static PyObject * get_sourcefile(PyObject *filename);
static PyObject *make_source_pathname(PyObject *pathname);
static char *make_compiled_pathname(char *pathname, char *buf, size_t buflen,
int debug);
static PyObject* make_compiled_pathname(Py_UNICODE *pathname, int debug);
/* Execute a code object in a module and return the module object
* WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is
@ -867,32 +868,11 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
}
/* Like strrchr(string, '/') but searches for the rightmost of either SEP
or ALTSEP, if the latter is defined.
*/
static char *
rightmost_sep(char *s)
{
char *found, c;
for (found = NULL; (c = *s); s++) {
if (c == SEP
#ifdef ALTSEP
|| c == ALTSEP
#endif
)
{
found = s;
}
}
return found;
}
/* Like strrchr(string, '/') but searches for the rightmost of either SEP
or ALTSEP, if the latter is defined.
*/
static Py_UNICODE*
rightmost_sep_unicode(Py_UNICODE *s)
rightmost_sep(Py_UNICODE *s)
{
Py_UNICODE *found, c;
for (found = NULL; (c = *s); s++) {
@ -912,15 +892,18 @@ rightmost_sep_unicode(Py_UNICODE *s)
/* Given a pathname for a Python source file, fill a buffer with the
pathname for the corresponding compiled file. Return the pathname
for the compiled file, or NULL if there's no space in the buffer.
Doesn't set an exception. */
Doesn't set an exception.
static char *
make_compiled_pathname(char *pathname, char *buf, size_t buflen, int debug)
foo.py -> __pycache__/foo.<tag>.pyc */
static PyObject*
make_compiled_pathname(Py_UNICODE *pathname, int debug)
{
/* foo.py -> __pycache__/foo.<tag>.pyc */
size_t len = strlen(pathname);
Py_UNICODE buf[MAXPATHLEN];
size_t buflen = (size_t)MAXPATHLEN;
size_t len = Py_UNICODE_strlen(pathname);
size_t i, save;
char *pos;
Py_UNICODE *pos;
int sep = SEP;
/* Sanity check that the buffer has roughly enough space to hold what
@ -932,35 +915,37 @@ make_compiled_pathname(char *pathname, char *buf, size_t buflen, int debug)
sanity check before writing the extension to ensure we do not
overflow the buffer.
*/
if (len + strlen(CACHEDIR) + strlen(pyc_tag) + 5 > buflen)
if (len + Py_UNICODE_strlen(CACHEDIR_UNICODE) + Py_UNICODE_strlen(PYC_TAG_UNICODE) + 5 > buflen)
return NULL;
/* Find the last path separator and copy everything from the start of
the source string up to and including the separator.
*/
if ((pos = rightmost_sep(pathname)) == NULL) {
pos = rightmost_sep(pathname);
if (pos == NULL) {
i = 0;
}
else {
sep = *pos;
i = pos - pathname + 1;
strncpy(buf, pathname, i);
Py_UNICODE_strncpy(buf, pathname, i);
}
save = i;
buf[i++] = '\0';
/* Add __pycache__/ */
strcat(buf, CACHEDIR);
i += strlen(CACHEDIR) - 1;
Py_UNICODE_strcat(buf, CACHEDIR_UNICODE);
i += Py_UNICODE_strlen(CACHEDIR_UNICODE) - 1;
buf[i++] = sep;
buf[i++] = '\0';
/* Add the base filename, but remove the .py or .pyw extension, since
the tag name must go before the extension.
*/
strcat(buf, pathname + save);
if ((pos = strrchr(buf, '.')) != NULL)
Py_UNICODE_strcat(buf, pathname + save);
pos = Py_UNICODE_strrchr(buf, '.');
if (pos != NULL)
*++pos = '\0';
strcat(buf, pyc_tag);
Py_UNICODE_strcat(buf, PYC_TAG_UNICODE);
/* The length test above assumes that we're only adding one character
to the end of what would normally be the extension. What if there
is no extension, or the string ends in '.' or '.p', and otherwise
@ -1010,11 +995,15 @@ make_compiled_pathname(char *pathname, char *buf, size_t buflen, int debug)
#if 0
printf("strlen(buf): %d; buflen: %d\n", (int)strlen(buf), (int)buflen);
#endif
if (strlen(buf) + 5 > buflen)
len = Py_UNICODE_strlen(buf);
if (len + 5 > buflen)
return NULL;
strcat(buf, debug ? ".pyc" : ".pyo");
assert(strlen(buf) < buflen);
return buf;
buf[len] = '.'; len++;
buf[len] = 'p'; len++;
buf[len] = 'y'; len++;
buf[len] = debug ? 'c' : 'o'; len++;
assert(len <= buflen);
return PyUnicode_FromUnicode(buf, len);
}
@ -1042,12 +1031,12 @@ make_source_pathname(PyObject *pathobj)
must be the string __pycache__ or this is not a PEP 3147 style
path. It's possible for there to be only one slash.
*/
right = rightmost_sep_unicode(pathname);
right = rightmost_sep(pathname);
if (right == NULL)
return NULL;
sep = *right;
*right = '\0';
left = rightmost_sep_unicode(pathname);
left = rightmost_sep(pathname);
*right = sep;
if (left == NULL)
left = pathname;
@ -1088,31 +1077,31 @@ make_source_pathname(PyObject *pathobj)
Doesn't set an exception. */
static FILE *
check_compiled_module(char *pathname, time_t mtime, char *cpathname)
check_compiled_module(PyObject *pathname, time_t mtime, PyObject *cpathname)
{
FILE *fp;
long magic;
long pyc_mtime;
fp = fopen(cpathname, "rb");
fp = _Py_fopen(cpathname, "rb");
if (fp == NULL)
return NULL;
magic = PyMarshal_ReadLongFromFile(fp);
if (magic != pyc_magic) {
if (Py_VerboseFlag)
PySys_WriteStderr("# %s has bad magic\n", cpathname);
PySys_FormatStderr("# %R has bad magic\n", cpathname);
fclose(fp);
return NULL;
}
pyc_mtime = PyMarshal_ReadLongFromFile(fp);
if (pyc_mtime != mtime) {
if (Py_VerboseFlag)
PySys_WriteStderr("# %s has bad mtime\n", cpathname);
PySys_FormatStderr("# %R has bad mtime\n", cpathname);
fclose(fp);
return NULL;
}
if (Py_VerboseFlag)
PySys_WriteStderr("# %s matches %s\n", cpathname, pathname);
PySys_FormatStderr("# %R matches %R\n", cpathname, pathname);
return fp;
}
@ -1120,7 +1109,7 @@ check_compiled_module(char *pathname, time_t mtime, char *cpathname)
/* Read a code object from a file and check it for validity */
static PyCodeObject *
read_compiled_module(char *cpathname, FILE *fp)
read_compiled_module(PyObject *cpathname, FILE *fp)
{
PyObject *co;
@ -1129,7 +1118,7 @@ read_compiled_module(char *cpathname, FILE *fp)
return NULL;
if (!PyCode_Check(co)) {
PyErr_Format(PyExc_ImportError,
"Non-code object in %.200s", cpathname);
"Non-code object in %R", cpathname);
Py_DECREF(co);
return NULL;
}
@ -1141,7 +1130,7 @@ read_compiled_module(char *cpathname, FILE *fp)
module object WITH INCREMENTED REFERENCE COUNT */
static PyObject *
load_compiled_module(char *name, char *cpathname, FILE *fp)
load_compiled_module(PyObject *name, PyObject *cpathname, FILE *fp)
{
long magic;
PyCodeObject *co;
@ -1150,7 +1139,7 @@ load_compiled_module(char *name, char *cpathname, FILE *fp)
magic = PyMarshal_ReadLongFromFile(fp);
if (magic != pyc_magic) {
PyErr_Format(PyExc_ImportError,
"Bad magic number in %.200s", cpathname);
"Bad magic number in %R", cpathname);
return NULL;
}
(void) PyMarshal_ReadLongFromFile(fp);
@ -1158,10 +1147,10 @@ load_compiled_module(char *name, char *cpathname, FILE *fp)
if (co == NULL)
return NULL;
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # precompiled from %s\n",
name, cpathname);
m = PyImport_ExecCodeModuleWithPathnames(
name, (PyObject *)co, cpathname, cpathname);
PySys_FormatStderr("import %U # precompiled from %R\n",
name, cpathname);
m = PyImport_ExecCodeModuleObject(name, (PyObject *)co,
cpathname, cpathname);
Py_DECREF(co);
return m;
@ -1170,27 +1159,37 @@ load_compiled_module(char *name, char *cpathname, FILE *fp)
/* Parse a source file and return the corresponding code object */
static PyCodeObject *
parse_source_module(const char *pathname, FILE *fp)
parse_source_module(PyObject *pathname, FILE *fp)
{
PyCodeObject *co = NULL;
PyCodeObject *co;
PyObject *pathbytes;
mod_ty mod;
PyCompilerFlags flags;
PyArena *arena = PyArena_New();
if (arena == NULL)
PyArena *arena;
pathbytes = PyUnicode_EncodeFSDefault(pathname);
if (pathbytes == NULL)
return NULL;
arena = PyArena_New();
if (arena == NULL) {
Py_DECREF(pathbytes);
return NULL;
}
flags.cf_flags = 0;
mod = PyParser_ASTFromFile(fp, pathname, NULL,
mod = PyParser_ASTFromFile(fp, PyBytes_AS_STRING(pathbytes), NULL,
Py_file_input, 0, 0, &flags,
NULL, arena);
if (mod) {
co = PyAST_Compile(mod, pathname, NULL, arena);
}
if (mod != NULL)
co = PyAST_Compile(mod, PyBytes_AS_STRING(pathbytes), NULL, arena);
else
co = NULL;
Py_DECREF(pathbytes);
PyArena_Free(arena);
return co;
}
/* Helper to open a bytecode file for writing in exclusive mode */
static FILE *
@ -1231,10 +1230,10 @@ open_exclusive(char *filename, mode_t mode)
remove the file. */
static void
write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
write_compiled_module(PyCodeObject *co, PyObject *cpathname,
struct stat *srcstat)
{
FILE *fp;
char *dirpath;
time_t mtime = srcstat->st_mtime;
#ifdef MS_WINDOWS /* since Windows uses different permissions */
mode_t mode = srcstat->st_mode & ~S_IEXEC;
@ -1243,39 +1242,64 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
mode_t dirmode = (srcstat->st_mode |
S_IXUSR | S_IXGRP | S_IXOTH |
S_IWUSR | S_IWGRP | S_IWOTH);
PyObject *dirbytes;
#endif
int saved;
PyObject *cpathbytes, *dirname;
Py_UNICODE *dirsep;
int res, ok;
/* Ensure that the __pycache__ directory exists. */
dirpath = rightmost_sep(cpathname);
if (dirpath == NULL) {
dirsep = rightmost_sep(PyUnicode_AS_UNICODE(cpathname));
if (dirsep == NULL) {
if (Py_VerboseFlag)
PySys_WriteStderr(
"# no %s path found %s\n",
CACHEDIR, cpathname);
PySys_FormatStderr("# no %s path found %R\n", CACHEDIR, cpathname);
return;
}
dirname = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(cpathname),
dirsep - PyUnicode_AS_UNICODE(cpathname));
if (dirname == NULL) {
PyErr_Clear();
return;
}
saved = *dirpath;
*dirpath = '\0';
#ifdef MS_WINDOWS
if (_mkdir(cpathname) < 0 && errno != EEXIST) {
res = CreateDirectoryW(PyUnicode_AS_UNICODE(dirname), NULL);
ok = (res != 0);
if (!ok && GetLastError() == ERROR_ALREADY_EXISTS)
ok = 1;
#else
if (mkdir(cpathname, dirmode) < 0 && errno != EEXIST) {
#endif
*dirpath = saved;
if (Py_VerboseFlag)
PySys_WriteStderr(
"# cannot create cache dir %s\n", cpathname);
dirbytes = PyUnicode_EncodeFSDefault(dirname);
if (dirbytes == NULL) {
PyErr_Clear();
return;
}
*dirpath = saved;
res = mkdir(PyBytes_AS_STRING(dirbytes), dirmode);
Py_DECREF(dirbytes);
if (0 <= res)
ok = 1;
else
ok = (errno == EEXIST);
#endif
if (!ok) {
if (Py_VerboseFlag)
PySys_FormatStderr("# cannot create cache dir %R\n", dirname);
Py_DECREF(dirname);
return;
}
Py_DECREF(dirname);
fp = open_exclusive(cpathname, mode);
cpathbytes = PyUnicode_EncodeFSDefault(cpathname);
if (cpathbytes == NULL) {
PyErr_Clear();
return;
}
fp = open_exclusive(PyBytes_AS_STRING(cpathbytes), mode);
if (fp == NULL) {
if (Py_VerboseFlag)
PySys_WriteStderr(
"# can't create %s\n", cpathname);
PySys_FormatStderr(
"# can't create %R\n", cpathname);
Py_DECREF(cpathbytes);
return;
}
PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION);
@ -1284,12 +1308,18 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION);
if (fflush(fp) != 0 || ferror(fp)) {
if (Py_VerboseFlag)
PySys_WriteStderr("# can't write %s\n", cpathname);
PySys_FormatStderr("# can't write %R\n", cpathname);
/* Don't keep partial file */
fclose(fp);
(void) unlink(cpathname);
#ifdef MS_WINDOWS
(void)DeleteFileW(PyUnicode_AS_UNICODE(cpathname));
#else
(void) unlink(PyBytes_AS_STRING(cpathbytes));
#endif
Py_DECREF(cpathbytes);
return;
}
Py_DECREF(cpathbytes);
/* Now write the true mtime */
fseek(fp, 4L, 0);
assert(mtime < LONG_MAX);
@ -1297,7 +1327,7 @@ write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
fflush(fp);
fclose(fp);
if (Py_VerboseFlag)
PySys_WriteStderr("# wrote %s\n", cpathname);
PySys_FormatStderr("# wrote %R\n", cpathname);
}
static void
@ -1324,26 +1354,18 @@ update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
}
}
static int
update_compiled_module(PyCodeObject *co, char *pathname)
static void
update_compiled_module(PyCodeObject *co, PyObject *newname)
{
PyObject *oldname, *newname;
PyObject *oldname;
newname = PyUnicode_DecodeFSDefault(pathname);
if (newname == NULL)
return -1;
if (!PyUnicode_Compare(co->co_filename, newname)) {
Py_DECREF(newname);
return 0;
}
if (PyUnicode_Compare(co->co_filename, newname) == 0)
return;
oldname = co->co_filename;
Py_INCREF(oldname);
update_code_filenames(co, oldname, newname);
Py_DECREF(oldname);
Py_DECREF(newname);
return 1;
}
/* Load a source module from a given file and return its module
@ -1351,20 +1373,19 @@ update_compiled_module(PyCodeObject *co, char *pathname)
byte-compiled file, use that instead. */
static PyObject *
load_source_module(char *name, char *pathname, FILE *fp)
load_source_module(PyObject *name, PyObject *pathname, FILE *fp)
{
struct stat st;
FILE *fpc;
char buf[MAXPATHLEN+1];
char *cpathname;
PyObject *cpathname = NULL, *cpathbytes = NULL;
PyCodeObject *co;
PyObject *m;
PyObject *m = NULL;
if (fstat(fileno(fp), &st) != 0) {
PyErr_Format(PyExc_RuntimeError,
"unable to get file status from '%s'",
"unable to get file status from %R",
pathname);
return NULL;
goto error;
}
#if SIZEOF_TIME_T > 4
/* Python's .pyc timestamp handling presumes that the timestamp fits
@ -1374,41 +1395,50 @@ load_source_module(char *name, char *pathname, FILE *fp)
if (st.st_mtime >> 32) {
PyErr_SetString(PyExc_OverflowError,
"modification time overflows a 4 byte field");
return NULL;
goto error;
}
#endif
cpathname = make_compiled_pathname(
pathname, buf, (size_t)MAXPATHLEN + 1, !Py_OptimizeFlag);
if (cpathname != NULL &&
(fpc = check_compiled_module(pathname, st.st_mtime, cpathname))) {
PyUnicode_AS_UNICODE(pathname),
!Py_OptimizeFlag);
if (cpathname != NULL)
fpc = check_compiled_module(pathname, st.st_mtime, cpathname);
else
fpc = NULL;
if (fpc) {
co = read_compiled_module(cpathname, fpc);
fclose(fpc);
if (co == NULL)
return NULL;
if (update_compiled_module(co, pathname) < 0)
return NULL;
goto error;
update_compiled_module(co, pathname);
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # precompiled from %s\n",
name, cpathname);
pathname = cpathname;
PySys_FormatStderr("import %U # precompiled from %R\n",
name, cpathname);
m = PyImport_ExecCodeModuleObject(name, (PyObject *)co,
cpathname, cpathname);
}
else {
co = parse_source_module(pathname, fp);
if (co == NULL)
return NULL;
goto error;
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # from %s\n",
PySys_FormatStderr("import %U # from %R\n",
name, pathname);
if (cpathname) {
if (cpathname != NULL) {
PyObject *ro = PySys_GetObject("dont_write_bytecode");
if (ro == NULL || !PyObject_IsTrue(ro))
write_compiled_module(co, cpathname, &st);
}
m = PyImport_ExecCodeModuleObject(name, (PyObject *)co,
pathname, cpathname);
}
m = PyImport_ExecCodeModuleWithPathnames(
name, (PyObject *)co, pathname, cpathname);
Py_DECREF(co);
error:
Py_XDECREF(cpathbytes);
Py_XDECREF(cpathname);
return m;
}
@ -2291,13 +2321,37 @@ load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
switch (type) {
case PY_SOURCE:
m = load_source_module(name, pathname, fp);
case PY_SOURCE: {
PyObject *nameobj, *pathobj;
nameobj = PyUnicode_FromString(name);
if (nameobj == NULL)
return NULL;
pathobj = PyUnicode_DecodeFSDefault(pathname);
if (pathobj == NULL) {
Py_DECREF(nameobj);
return NULL;
}
m = load_source_module(nameobj, pathobj, fp);
Py_DECREF(nameobj);
Py_DECREF(pathobj);
break;
}
case PY_COMPILED:
m = load_compiled_module(name, pathname, fp);
case PY_COMPILED: {
PyObject *nameobj, *pathobj;
nameobj = PyUnicode_FromString(name);
if (nameobj == NULL)
return NULL;
pathobj = PyUnicode_DecodeFSDefault(pathname);
if (pathobj == NULL) {
Py_DECREF(nameobj);
return NULL;
}
m = load_compiled_module(nameobj, pathobj, fp);
Py_DECREF(nameobj);
Py_DECREF(pathobj);
break;
}
#ifdef HAVE_DYNAMIC_LOADING
case C_EXTENSION: {
@ -3533,13 +3587,13 @@ imp_is_frozen(PyObject *self, PyObject *args)
}
static FILE *
get_file(char *pathname, PyObject *fob, char *mode)
get_file(PyObject *pathname, PyObject *fob, char *mode)
{
FILE *fp;
if (mode[0] == 'U')
mode = "r" PY_STDIOTEXTMODE;
if (fob == NULL) {
fp = fopen(pathname, mode);
fp = _Py_fopen(pathname, mode);
}
else {
int fd = PyObject_AsFileDescriptor(fob);
@ -3565,22 +3619,21 @@ error:
static PyObject *
imp_load_compiled(PyObject *self, PyObject *args)
{
char *name;
PyObject *pathname;
PyObject *name, *pathname;
PyObject *fob = NULL;
PyObject *m;
FILE *fp;
if (!PyArg_ParseTuple(args, "sO&|O:load_compiled",
if (!PyArg_ParseTuple(args, "UO&|O:load_compiled",
&name,
PyUnicode_FSConverter, &pathname,
PyUnicode_FSDecoder, &pathname,
&fob))
return NULL;
fp = get_file(PyBytes_AS_STRING(pathname), fob, "rb");
fp = get_file(pathname, fob, "rb");
if (fp == NULL) {
Py_DECREF(pathname);
return NULL;
}
m = load_compiled_module(name, PyBytes_AS_STRING(pathname), fp);
m = load_compiled_module(name, pathname, fp);
fclose(fp);
Py_DECREF(pathname);
return m;
@ -3615,22 +3668,21 @@ imp_load_dynamic(PyObject *self, PyObject *args)
static PyObject *
imp_load_source(PyObject *self, PyObject *args)
{
char *name;
PyObject *pathname;
PyObject *name, *pathname;
PyObject *fob = NULL;
PyObject *m;
FILE *fp;
if (!PyArg_ParseTuple(args, "sO&|O:load_source",
if (!PyArg_ParseTuple(args, "UO&|O:load_source",
&name,
PyUnicode_FSConverter, &pathname,
PyUnicode_FSDecoder, &pathname,
&fob))
return NULL;
fp = get_file(PyBytes_AS_STRING(pathname), fob, "r");
fp = get_file(pathname, fob, "r");
if (fp == NULL) {
Py_DECREF(pathname);
return NULL;
}
m = load_source_module(name, PyBytes_AS_STRING(pathname), fp);
m = load_source_module(name, pathname, fp);
Py_DECREF(pathname);
fclose(fp);
return m;
@ -3719,33 +3771,31 @@ imp_cache_from_source(PyObject *self, PyObject *args, PyObject *kws)
{
static char *kwlist[] = {"path", "debug_override", NULL};
char buf[MAXPATHLEN+1];
PyObject *pathbytes;
char *cpathname;
PyObject *pathname, *cpathname;
PyObject *debug_override = NULL;
int debug = !Py_OptimizeFlag;
if (!PyArg_ParseTupleAndKeywords(
args, kws, "O&|O", kwlist,
PyUnicode_FSConverter, &pathbytes, &debug_override))
PyUnicode_FSDecoder, &pathname, &debug_override))
return NULL;
if (debug_override != NULL &&
(debug = PyObject_IsTrue(debug_override)) < 0) {
Py_DECREF(pathbytes);
Py_DECREF(pathname);
return NULL;
}
cpathname = make_compiled_pathname(
PyBytes_AS_STRING(pathbytes),
buf, MAXPATHLEN+1, debug);
Py_DECREF(pathbytes);
PyUnicode_AS_UNICODE(pathname),
debug);
Py_DECREF(pathname);
if (cpathname == NULL) {
PyErr_Format(PyExc_SystemError, "path buffer too short");
return NULL;
}
return PyUnicode_DecodeFSDefault(buf);
return cpathname;
}
PyDoc_STRVAR(doc_cache_from_source,