📄 import.c
字号:
return NULL;
#endif
}
if (path == NULL) {
if (is_builtin(name)) {
strcpy(buf, name);
return &fd_builtin;
}
if ((find_frozen(name)) != NULL) {
strcpy(buf, name);
return &fd_frozen;
}
#ifdef MS_COREDLL
fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen);
if (fp != NULL) {
*p_fp = fp;
return fdp;
}
#endif
path = PySys_GetObject("path");
}
if (path == NULL || !PyList_Check(path)) {
PyErr_SetString(PyExc_ImportError,
"sys.path must be a list of directory names");
return NULL;
}
npath = PyList_Size(path);
namelen = strlen(name);
for (i = 0; i < npath; i++) {
PyObject *v = PyList_GetItem(path, i);
if (!PyString_Check(v))
continue;
len = PyString_Size(v);
if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen)
continue; /* Too long */
strcpy(buf, PyString_AsString(v));
if (strlen(buf) != len)
continue; /* v contains '\0' */
#ifdef macintosh
#ifdef INTERN_STRINGS
/*
** Speedup: each sys.path item is interned, and
** FindResourceModule remembers which items refer to
** folders (so we don't have to bother trying to look
** into them for resources).
*/
PyString_InternInPlace(&PyList_GET_ITEM(path, i));
v = PyList_GET_ITEM(path, i);
#endif
if (PyMac_FindResourceModule((PyStringObject *)v, name, buf)) {
#ifndef SYMBIAN
static struct filedescr resfiledescr =
{"", "", PY_RESOURCE};
#else
#define resfiledescr (pyglobals->imp_resfiledescr)
if (resfiledescr.type == UNINITIALIZED) {
resfiledescr.suffix = "";
resfiledescr.mode = "";
resfiledescr.type = PY_RESOURCE;
}
#endif
return &resfiledescr;
}
if (PyMac_FindCodeResourceModule((PyStringObject *)v, name, buf)) {
#ifndef SYMBIAN
static struct filedescr resfiledescr =
{"", "", PY_CODERESOURCE};
#else
#undef resfiledescr
#define resfiledescr (pyglobals->imp_coderesfiledescr)
if (resfiledescr.type == UNINITIALIZED) {
resfiledescr.suffix = "";
resfiledescr.mode = "";
resfiledescr.type = PY_CODERESOURCE;
}
#endif
return &resfiledescr;
}
#endif
if (len > 0 && buf[len-1] != SEP
#ifdef ALTSEP
&& buf[len-1] != ALTSEP
#endif
)
buf[len++] = SEP;
strcpy(buf+len, name);
len += namelen;
/* Check for package import (buf holds a directory name,
and there's an __init__ module in that directory */
#ifdef HAVE_STAT
if (stat(buf, &statbuf) == 0 && /* it exists */
S_ISDIR(statbuf.st_mode) && /* it's a directory */
find_init_module(buf) && /* it has __init__.py */
case_ok(buf, len, namelen, name)) /* and case matches */
return &fd_package;
#else
/* XXX How are you going to test for directories? */
#ifdef RISCOS
if (isdir(buf) &&
find_init_module(buf) &&
case_ok(buf, len, namelen, name))
return &fd_package;
#endif
#endif
#ifdef macintosh
fdp = PyMac_FindModuleExtension(buf, &len, name);
if (fdp) {
#else
for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
strcpy(buf+len, fdp->suffix);
if (Py_VerboseFlag > 1)
PySys_WriteStderr("# trying %s\n", buf);
#endif /* !macintosh */
fp = fopen(buf, fdp->mode);
if (fp != NULL) {
if (case_ok(buf, len, namelen, name))
break;
else { /* continue search */
fclose(fp);
fp = NULL;
}
}
}
if (fp != NULL)
break;
}
if (fp == NULL) {
PyErr_Format(PyExc_ImportError,
"No module named %.200s", name);
return NULL;
}
*p_fp = fp;
return fdp;
}
/* case_ok(char* buf, int len, int namelen, char* name)
* The arguments here are tricky, best shown by example:
* /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
* ^ ^ ^ ^
* |--------------------- buf ---------------------|
* |------------------- len ------------------|
* |------ name -------|
* |----- namelen -----|
* buf is the full path, but len only counts up to (& exclusive of) the
* extension. name is the module name, also exclusive of extension.
*
* We've already done a successful stat() or fopen() on buf, so know that
* there's some match, possibly case-insensitive.
*
* case_ok() is to return 1 if there's a case-sensitive match for
* name, else 0. case_ok() is also to return 1 if envar PYTHONCASEOK
* exists.
*
* case_ok() is used to implement case-sensitive import semantics even
* on platforms with case-insensitive filesystems. It's trivial to implement
* for case-sensitive filesystems. It's pretty much a cross-platform
* nightmare for systems with case-insensitive filesystems.
*/
/* First we may need a pile of platform-specific header files; the sequence
* of #if's here should match the sequence in the body of case_ok().
*/
#if defined(MS_WIN32) || defined(__CYGWIN__)
#include <windows.h>
#ifdef __CYGWIN__
#include <sys/cygwin.h>
#endif
#elif defined(DJGPP)
#include <dir.h>
#elif defined(macintosh)
#include <TextUtils.h>
#ifdef USE_GUSI1
#include "TFileSpec.h" /* for Path2FSSpec() */
#endif
#elif defined(__MACH__) && defined(__APPLE__) && defined(HAVE_DIRENT_H)
#include <sys/types.h>
#include <dirent.h>
#elif defined(RISCOS)
#include "oslib/osfscontrol.h"
#endif
static int
case_ok(char *buf, int len, int namelen, char *name)
{
/* Pick a platform-specific implementation; the sequence of #if's here should
* match the sequence just above.
*/
/* MS_WIN32 || __CYGWIN__ */
#if defined(MS_WIN32) || defined(__CYGWIN__)
WIN32_FIND_DATA data;
HANDLE h;
#ifdef __CYGWIN__
char tempbuf[MAX_PATH];
#endif
if (Py_GETENV("PYTHONCASEOK") != NULL)
return 1;
#ifdef __CYGWIN__
cygwin32_conv_to_win32_path(buf, tempbuf);
h = FindFirstFile(tempbuf, &data);
#else
h = FindFirstFile(buf, &data);
#endif
if (h == INVALID_HANDLE_VALUE) {
PyErr_Format(PyExc_NameError,
"Can't find file for module %.100s\n(filename %.300s)",
name, buf);
return 0;
}
FindClose(h);
return strncmp(data.cFileName, name, namelen) == 0;
/* DJGPP */
#elif defined(DJGPP)
struct ffblk ffblk;
int done;
if (Py_GETENV("PYTHONCASEOK") != NULL)
return 1;
done = findfirst(buf, &ffblk, FA_ARCH|FA_RDONLY|FA_HIDDEN|FA_DIREC);
if (done) {
PyErr_Format(PyExc_NameError,
"Can't find file for module %.100s\n(filename %.300s)",
name, buf);
return 0;
}
return strncmp(ffblk.ff_name, name, namelen) == 0;
/* macintosh */
#elif defined(macintosh)
FSSpec fss;
OSErr err;
if (Py_GETENV("PYTHONCASEOK") != NULL)
return 1;
#ifndef USE_GUSI1
err = FSMakeFSSpec(0, 0, Pstring(buf), &fss);
#else
/* GUSI's Path2FSSpec() resolves all possible aliases nicely on
the way, which is fine for all directories, but here we need
the original name of the alias file (say, Dlg.ppc.slb, not
toolboxmodules.ppc.slb). */
char *colon;
err = Path2FSSpec(buf, &fss);
if (err == noErr) {
colon = strrchr(buf, ':'); /* find filename */
if (colon != NULL)
err = FSMakeFSSpec(fss.vRefNum, fss.parID,
Pstring(colon+1), &fss);
else
err = FSMakeFSSpec(fss.vRefNum, fss.parID,
fss.name, &fss);
}
#endif
if (err) {
PyErr_Format(PyExc_NameError,
"Can't find file for module %.100s\n(filename %.300s)",
name, buf);
return 0;
}
return fss.name[0] >= namelen &&
strncmp(name, (char *)fss.name+1, namelen) == 0;
/* new-fangled macintosh (macosx) */
#elif defined(__MACH__) && defined(__APPLE__) && defined(HAVE_DIRENT_H)
DIR *dirp;
struct dirent *dp;
char dirname[MAXPATHLEN + 1];
const int dirlen = len - namelen - 1; /* don't want trailing SEP */
if (Py_GETENV("PYTHONCASEOK") != NULL)
return 1;
/* Copy the dir component into dirname; substitute "." if empty */
if (dirlen <= 0) {
dirname[0] = '.';
dirname[1] = '\0';
}
else {
assert(dirlen <= MAXPATHLEN);
memcpy(dirname, buf, dirlen);
dirname[dirlen] = '\0';
}
/* Open the directory and search the entries for an exact match. */
dirp = opendir(dirname);
if (dirp) {
char *nameWithExt = buf + len - namelen;
while ((dp = readdir(dirp)) != NULL) {
const int thislen =
#ifdef _DIRENT_HAVE_D_NAMELEN
dp->d_namlen;
#else
strlen(dp->d_name);
#endif
if (thislen >= namelen &&
strcmp(dp->d_name, nameWithExt) == 0) {
(void)closedir(dirp);
return 1; /* Found */
}
}
(void)closedir(dirp);
}
return 0 ; /* Not found */
/* RISC OS */
#elif defined(RISCOS)
char canon[MAXPATHLEN+1]; /* buffer for the canonical form of the path */
char buf2[MAXPATHLEN+2];
char *nameWithExt = buf+len-namelen;
int canonlen;
os_error *e;
if (Py_GETENV("PYTHONCASEOK") != NULL)
return 1;
/* workaround:
append wildcard, otherwise case of filename wouldn't be touched */
strcpy(buf2, buf);
strcat(buf2, "*");
e = xosfscontrol_canonicalise_path(buf2,canon,0,0,MAXPATHLEN+1,&canonlen);
canonlen = MAXPATHLEN+1-canonlen;
if (e || canonlen<=0 || canonlen>(MAXPATHLEN+1) )
return 0;
if (strcmp(nameWithExt, canon+canonlen-strlen(nameWithExt))==0)
return 1; /* match */
return 0;
/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
#else
return 1;
#endif
}
#ifdef HAVE_STAT
/* Helper to look for __init__.py or __init__.py[co] in potential package */
static int
find_init_module(char *buf)
{
const size_t save_len = strlen(buf);
size_t i = save_len;
char *pname; /* pointer to start of __init__ */
struct stat statbuf;
/* For calling case_ok(buf, len, namelen, name):
* /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
* ^ ^ ^ ^
* |--------------------- buf ---------------------|
* |------------------- len ------------------|
* |------ name -------|
* |----- namelen -----|
*/
if (save_len + 13 >= MAXPATHLEN)
return 0;
buf[i++] = SEP;
pname = buf + i;
strcpy(pname, "__init__.py");
if (stat(buf, &statbuf) == 0) {
if (case_ok(buf,
save_len + 9, /* len("/__init__") */
8, /* len("__init__") */
pname)) {
buf[save_len] = '\0';
return 1;
}
}
i += strlen(pname);
strcpy(buf+i, Py_OptimizeFlag ? "o" : "c");
if (stat(buf, &statbuf) == 0) {
if (case_ok(buf,
save_len + 9, /* len("/__init__") */
8, /* len("__init__") */
pname)) {
buf[save_len] = '\0';
return 1;
}
}
buf[save_len] = '\0';
return 0;
}
#else
#ifdef RISCOS
static int
find_init_module(buf)
char *buf;
{
int save_len = strlen(buf);
int i = save_len;
if (save_len + 13 >= MAXPATHLEN)
return 0;
buf[i++] = SEP;
strcpy(buf+i, "__init__/py");
if (isfile(buf)) {
buf[save_len] = '\0';
return 1;
}
if (Py_OptimizeFlag)
strcpy(buf+i, "o");
else
strcpy(buf+i, "c");
if (isfile(buf)) {
buf[save_len] = '\0';
return 1;
}
buf[save_len] = '\0';
return 0;
}
#endif /*RISCOS*/
#endif /* HAVE_STAT */
static int init_builtin(char *); /* Forward */
/* Load an external module using the default search path and return
its module object WITH INCREMENTED REFERENCE COUNT */
static PyObject *
load_module(char *name, FILE *fp, char *buf, int type)
{
PyObject *modules;
PyObject *m;
int err;
/* First check that there's an open file (if we need one) */
switch (type) {
case PY_SOURCE:
case PY_COMPILED:
if (fp == NULL) {
PyErr_Format(PyExc_ValueError,
"file object required for import (type code %d)",
type);
return NULL;
}
}
switch (type) {
case PY_SOURCE:
m = load_source_module(name, buf, fp);
break;
case PY_COMPILED:
m = load_compiled_module(name, buf, fp);
break;
#ifdef HAVE_DYNAMIC_LOADING
case C_EXTENSION:
m = _PyImport_LoadDynamicModule(name, buf, fp);
break;
#endif
#ifdef macintosh
case PY_RESOURCE:
m = PyMac_LoadResourceModule(name, buf);
break;
case PY_CODERESOURCE:
m = PyMac_LoadCodeResourceModule(name, buf);
break;
#endif
case PKG_DIRECTORY:
m = load_package(name, buf);
break;
case C_BUILTIN:
case PY_FROZEN:
if (buf != NULL && buf[0] != '\0')
name = buf;
if (type == C_BUILTIN)
err = init_builtin(name);
else
err = PyImport_ImportFrozenModule(name);
if (err < 0)
return NULL;
if (err == 0) {
PyErr_Format(PyExc_ImportError,
"Purported %s module %.200s not found",
type == C_BUILTIN ?
"builtin" : "frozen",
name);
return NULL;
}
modules = PyImport_GetModuleDict();
m = PyDict_GetItemString(modules, name);
if (m == NULL) {
PyErr_Format(
PyExc_ImportError,
"%s module %.200s not properly initialized",
type == C_BUILTIN ?
"builtin" : "frozen",
name);
return NULL;
}
Py_INCREF(m);
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -