📄 import.c
字号:
/* Portions Copyright (c) 2005 Nokia Corporation */
/* Module definition and import implementation */
#include "Python.h"
#include "node.h"
#include "token.h"
#include "errcode.h"
#include "marshal.h"
#include "compile.h"
#include "eval.h"
#include "osdefs.h"
#include "importdl.h"
#ifdef macintosh
#include "macglue.h"
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
/* check if the int_value can't be written in 15 bits (signed) */
#define CANT_WRITE(int_value) (int_value > 32767)
extern time_t PyOS_GetLastModificationTime(char *, FILE *);
/* In getmtime.c */
/* Magic word to reject .pyc files generated by other Python versions */
/* Change for each incompatible change */
/* The value of CR and LF is incorporated so if you ever read or write
a .pyc file in text mode the magic number will be wrong; also, the
Apple MPW compiler swaps their values, botching string constants.
XXX That probably isn't important anymore.
*/
/* XXX Perhaps the magic number should be frozen and a version field
added to the .pyc file header? */
/* New way to come up with the low 16 bits of the magic number:
(YEAR-1995) * 10000 + MONTH * 100 + DAY
where MONTH and DAY are 1-based.
XXX Whatever the "old way" may have been isn't documented.
XXX This scheme breaks in 2002, as (2002-1995)*10000 = 70000 doesn't
fit in 16 bits.
XXX Later, sometimes 1 gets added to MAGIC in order to record that
the Unicode -U option is in use. IMO (Tim's), that's a Bad Idea
(quite apart from that the -U option doesn't work so isn't used
anyway).
*/
#define MAGIC (60717 | ((long)'\r'<<16) | ((long)'\n'<<24))
/* Magic word as global; note that _PyImport_Init() can change the
value of this global to accommodate for alterations of how the
compiler works which are enabled by command line switches. */
#ifndef SYMBIAN
static long pyc_magic = MAGIC;
#else
#define pyc_magic (PYTHON_GLOBALS->imp_pyc_magic)
#endif
/* See _PyImport_FixupExtension() below */
#ifndef SYMBIAN
static PyObject *extensions = NULL;
#else
#define extensions (PYTHON_GLOBALS->imp_extensions)
#endif
/* This table is defined in config.c: */
extern const struct _inittab _PyImport_Inittab[];
#ifndef SYMBIAN
struct _inittab *PyImport_Inittab = _PyImport_Inittab;
#endif
/* these tables define the module suffixes that Python recognizes */
#ifndef SYMBIAN
struct filedescr * _PyImport_Filetab = NULL;
#else
#define _PyImport_Filetab (PYTHON_GLOBALS->imp__PyImport_Filetab)
#endif
#ifdef RISCOS
static const struct filedescr _PyImport_StandardFiletab[] = {
{"/py", "r", PY_SOURCE},
{"/pyc", "rb", PY_COMPILED},
{0, 0}
};
#else
static const struct filedescr _PyImport_StandardFiletab[] = {
{".py", "r", PY_SOURCE},
#ifdef MS_WIN32
{".pyw", "r", PY_SOURCE},
#endif
{".pyc", "rb", PY_COMPILED},
{0, 0}
};
#endif
#ifdef SYMBIAN
// moved here from frozen.c
static const unsigned char M___hello__[] = {
99,0,0,0,0,1,0,0,0,115,15,0,0,0,127,0,
0,127,1,0,100,0,0,71,72,100,1,0,83,40,2,0,
0,0,115,14,0,0,0,72,101,108,108,111,32,119,111,114,
108,100,46,46,46,78,40,0,0,0,0,40,0,0,0,0,
40,0,0,0,0,40,0,0,0,0,115,8,0,0,0,104,
101,108,108,111,46,112,121,115,1,0,0,0,63,1,0,115,
0,0,0,0,
};
#define SIZE (int)sizeof(M___hello__)
// XXX:CW32
static const struct _frozen _PyImport_FrozenModules[] = {
/* Test module */
{"__hello__", (unsigned char *)M___hello__, SIZE},
/* Test package (negative size indicates package-ness) */
{"__phello__", (unsigned char *)M___hello__, -SIZE},
{"__phello__.spam", (unsigned char *)M___hello__, SIZE},
{0, 0, 0} /* sentinel */
};
#endif /* SYMBIAN */
/* Initialize things */
DL_EXPORT(void)
_PyImport_Init(void)
{
const struct filedescr *scan;
struct filedescr *filetab;
int countD = 0;
int countS = 0;
#ifdef SYMBIAN
pyc_magic = MAGIC;
#ifdef WITH_THREAD
PYTHON_GLOBALS->imp_import_lock_thread = -1;
#endif
#endif
/* prepare _PyImport_Filetab: copy entries from
_PyImport_DynLoadFiletab and _PyImport_StandardFiletab.
*/
for (scan = _PyImport_DynLoadFiletab; scan->suffix != NULL; ++scan)
++countD;
for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan)
++countS;
filetab = PyMem_NEW(struct filedescr, countD + countS + 1);
memcpy(filetab, _PyImport_DynLoadFiletab,
countD * sizeof(struct filedescr));
memcpy(filetab + countD, _PyImport_StandardFiletab,
countS * sizeof(struct filedescr));
filetab[countD + countS].suffix = NULL;
_PyImport_Filetab = filetab;
if (Py_OptimizeFlag) {
/* Replace ".pyc" with ".pyo" in _PyImport_Filetab */
for (; filetab->suffix != NULL; filetab++) {
#ifndef RISCOS
if (strcmp(filetab->suffix, ".pyc") == 0)
filetab->suffix = ".pyo";
#else
if (strcmp(filetab->suffix, "/pyc") == 0)
filetab->suffix = "/pyo";
#endif
}
}
if (Py_UnicodeFlag) {
/* Fix the pyc_magic so that byte compiled code created
using the all-Unicode method doesn't interfere with
code created in normal operation mode. */
pyc_magic = MAGIC + 1;
}
}
DL_EXPORT(void)
_PyImport_Fini(void)
{
Py_XDECREF(extensions);
extensions = NULL;
PyMem_DEL(_PyImport_Filetab);
_PyImport_Filetab = NULL;
}
/* Locking primitives to prevent parallel imports of the same module
in different threads to return with a partially loaded module.
These calls are serialized by the global interpreter lock. */
#ifdef WITH_THREAD
#include "pythread.h"
#ifndef SYMBIAN
static PyThread_type_lock import_lock = 0;
static long import_lock_thread = -1;
static int import_lock_level = 0;
#else
#define import_lock (PYTHON_GLOBALS->imp_import_lock)
#define import_lock_thread (PYTHON_GLOBALS->imp_import_lock_thread)
#define import_lock_level (PYTHON_GLOBALS->imp_import_lock_level)
#endif
static void
lock_import(void)
{
long me = PyThread_get_thread_ident();
if (me == -1)
return; /* Too bad */
if (import_lock == NULL)
import_lock = PyThread_allocate_lock();
if (import_lock_thread == me) {
import_lock_level++;
return;
}
if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0)) {
PyThreadState *tstate = PyEval_SaveThread();
PyThread_acquire_lock(import_lock, 1);
PyEval_RestoreThread(tstate);
}
import_lock_thread = me;
import_lock_level = 1;
}
static void
unlock_import(void)
{
long me = PyThread_get_thread_ident();
if (me == -1)
return; /* Too bad */
if (import_lock_thread != me)
Py_FatalError("unlock_import: not holding the import lock");
import_lock_level--;
if (import_lock_level == 0) {
import_lock_thread = -1;
PyThread_release_lock(import_lock);
}
}
#else
#define lock_import()
#define unlock_import()
#endif
static PyObject *
imp_lock_held(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":lock_held"))
return NULL;
#ifdef WITH_THREAD
return PyInt_FromLong(import_lock_thread != -1);
#else
return PyInt_FromLong(0);
#endif
}
/* Helper for sys */
DL_EXPORT(PyObject *)
PyImport_GetModuleDict(void)
{
PyInterpreterState *interp = PyThreadState_Get()->interp;
if (interp->modules == NULL)
Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
return interp->modules;
}
/* List of names to clear in sys */
static const char *const sys_deletes[] = {
"path", "argv", "ps1", "ps2", "exitfunc",
"exc_type", "exc_value", "exc_traceback",
"last_type", "last_value", "last_traceback",
NULL
};
static const char *const sys_files[] = {
"stdin", "__stdin__",
"stdout", "__stdout__",
"stderr", "__stderr__",
NULL
};
/* Un-initialize things, as good as we can */
DL_EXPORT(void)
PyImport_Cleanup(void)
{
int pos, ndone;
char *name;
PyObject *key, *value, *dict;
PyInterpreterState *interp = PyThreadState_Get()->interp;
PyObject *modules = interp->modules;
if (modules == NULL)
return; /* Already done */
/* Delete some special variables first. These are common
places where user values hide and people complain when their
destructors fail. Since the modules containing them are
deleted *last* of all, they would come too late in the normal
destruction order. Sigh. */
value = PyDict_GetItemString(modules, "__builtin__");
if (value != NULL && PyModule_Check(value)) {
dict = PyModule_GetDict(value);
if (Py_VerboseFlag)
PySys_WriteStderr("# clear __builtin__._\n");
PyDict_SetItemString(dict, "_", Py_None);
}
value = PyDict_GetItemString(modules, "sys");
if (value != NULL && PyModule_Check(value)) {
char **p;
PyObject *v;
dict = PyModule_GetDict(value);
// XXX:CW32
for (p = (char **)sys_deletes; *p != NULL; p++) {
if (Py_VerboseFlag)
PySys_WriteStderr("# clear sys.%s\n", *p);
PyDict_SetItemString(dict, *p, Py_None);
}
// XXX:CW32
for (p = (char **)sys_files; *p != NULL; p+=2) {
if (Py_VerboseFlag)
PySys_WriteStderr("# restore sys.%s\n", *p);
v = PyDict_GetItemString(dict, *(p+1));
if (v == NULL)
v = Py_None;
PyDict_SetItemString(dict, *p, v);
}
}
/* First, delete __main__ */
value = PyDict_GetItemString(modules, "__main__");
if (value != NULL && PyModule_Check(value)) {
if (Py_VerboseFlag)
PySys_WriteStderr("# cleanup __main__\n");
_PyModule_Clear(value);
PyDict_SetItemString(modules, "__main__", Py_None);
}
/* The special treatment of __builtin__ here is because even
when it's not referenced as a module, its dictionary is
referenced by almost every module's __builtins__. Since
deleting a module clears its dictionary (even if there are
references left to it), we need to delete the __builtin__
module last. Likewise, we don't delete sys until the very
end because it is implicitly referenced (e.g. by print).
Also note that we 'delete' modules by replacing their entry
in the modules dict with None, rather than really deleting
them; this avoids a rehash of the modules dictionary and
also marks them as "non existent" so they won't be
re-imported. */
/* Next, repeatedly delete modules with a reference count of
one (skipping __builtin__ and sys) and delete them */
do {
ndone = 0;
pos = 0;
while (PyDict_Next(modules, &pos, &key, &value)) {
if (value->ob_refcnt != 1)
continue;
if (PyString_Check(key) && PyModule_Check(value)) {
name = PyString_AS_STRING(key);
if (strcmp(name, "__builtin__") == 0)
continue;
if (strcmp(name, "sys") == 0)
continue;
if (Py_VerboseFlag)
PySys_WriteStderr(
"# cleanup[1] %s\n", name);
_PyModule_Clear(value);
PyDict_SetItem(modules, key, Py_None);
ndone++;
}
}
} while (ndone > 0);
/* Next, delete all modules (still skipping __builtin__ and sys) */
pos = 0;
while (PyDict_Next(modules, &pos, &key, &value)) {
if (PyString_Check(key) && PyModule_Check(value)) {
name = PyString_AS_STRING(key);
if (strcmp(name, "__builtin__") == 0)
continue;
if (strcmp(name, "sys") == 0)
continue;
if (Py_VerboseFlag)
PySys_WriteStderr("# cleanup[2] %s\n", name);
_PyModule_Clear(value);
PyDict_SetItem(modules, key, Py_None);
}
}
/* Next, delete sys and __builtin__ (in that order) */
value = PyDict_GetItemString(modules, "sys");
if (value != NULL && PyModule_Check(value)) {
if (Py_VerboseFlag)
PySys_WriteStderr("# cleanup sys\n");
_PyModule_Clear(value);
PyDict_SetItemString(modules, "sys", Py_None);
}
value = PyDict_GetItemString(modules, "__builtin__");
if (value != NULL && PyModule_Check(value)) {
if (Py_VerboseFlag)
PySys_WriteStderr("# cleanup __builtin__\n");
_PyModule_Clear(value);
PyDict_SetItemString(modules, "__builtin__", Py_None);
}
/* Finally, clear and delete the modules directory */
PyDict_Clear(modules);
interp->modules = NULL;
Py_DECREF(modules);
}
/* Helper for pythonrun.c -- return magic number */
DL_EXPORT(long)
PyImport_GetMagicNumber(void)
{
return pyc_magic;
}
/* Magic for extension modules (built-in as well as dynamically
loaded). To prevent initializing an extension module more than
once, we keep a static dictionary 'extensions' keyed by module name
(for built-in modules) or by filename (for dynamically loaded
modules), containing these modules. A copy of the module's
dictionary is stored by calling _PyImport_FixupExtension()
immediately after the module initialization function succeeds. A
copy can be retrieved from there by calling
_PyImport_FindExtension(). */
DL_EXPORT(PyObject *)
_PyImport_FixupExtension(char *name, char *filename)
{
PyObject *modules, *mod, *dict, *copy;
if (extensions == NULL) {
extensions = PyDict_New();
if (extensions == NULL)
return NULL;
}
modules = PyImport_GetModuleDict();
mod = PyDict_GetItemString(modules, name);
if (mod == NULL || !PyModule_Check(mod)) {
PyErr_Format(PyExc_SystemError,
"_PyImport_FixupExtension: module %.200s not loaded", name);
return NULL;
}
dict = PyModule_GetDict(mod);
if (dict == NULL)
return NULL;
copy = PyDict_Copy(dict);
if (copy == NULL)
return NULL;
PyDict_SetItemString(extensions, filename, copy);
Py_DECREF(copy);
return copy;
}
DL_EXPORT(PyObject *)
_PyImport_FindExtension(char *name, char *filename)
{
PyObject *dict, *mod, *mdict;
if (extensions == NULL)
return NULL;
dict = PyDict_GetItemString(extensions, filename);
if (dict == NULL)
return NULL;
mod = PyImport_AddModule(name);
if (mod == NULL)
return NULL;
mdict = PyModule_GetDict(mod);
if (mdict == NULL)
return NULL;
if (PyDict_Update(mdict, dict))
return NULL;
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # previously loaded (%s)\n",
name, filename);
return mod;
}
/* Get the module object corresponding to a module name.
First check the modules dictionary if there's one there,
if not, create a new one and insert in in the modules dictionary.
Because the former action is most common, THIS DOES NOT RETURN A
'NEW' REFERENCE! */
DL_EXPORT(PyObject *)
PyImport_AddModule(char *name)
{
PyObject *modules = PyImport_GetModuleDict();
PyObject *m;
if ((m = PyDict_GetItemString(modules, name)) != NULL &&
PyModule_Check(m))
return m;
m = PyModule_New(name);
if (m == NULL)
return NULL;
if (PyDict_SetItemString(modules, name, m) != 0) {
Py_DECREF(m);
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -