summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-09-05 07:33:22 (GMT)
committerGuido van Rossum <guido@python.org>1997-09-05 07:33:22 (GMT)
commitaee0bad0a50f9f533267d241bea97a0b2118f238 (patch)
tree636ee14fc00351167bfea4c341ada498730f1cc2 /Python
parent026de19906695cc0f63977da4e7740214048ba6f (diff)
downloadcpython-aee0bad0a50f9f533267d241bea97a0b2118f238.zip
cpython-aee0bad0a50f9f533267d241bea97a0b2118f238.tar.gz
cpython-aee0bad0a50f9f533267d241bea97a0b2118f238.tar.bz2
First part of package support.
This doesn't yet support "import a.b.c" or "from a.b.c import x", but it does recognize directories. When importing a directory, it initializes __path__ to a list containing the directory name, and loads the __init__ module if found. The (internal) find_module() and load_module() functions are restructured so that they both also handle built-in and frozen modules and Mac resources (and directories of course). The imp module's find_module() and (new) load_module() also have this functionality. Moreover, imp unconditionally defines constants for all module types, and has two more new functions: find_module_in_package() and find_module_in_directory(). There's also a new API function, PyImport_ImportModuleEx(), which takes all four __import__ arguments (name, globals, locals, fromlist). The last three may be NULL. This is currently the same as PyImport_ImportModule() but in the future it will be able to do relative dotted-path imports. Other changes: - bltinmodule.c: in __import__, call PyImport_ImportModuleEx(). - ceval.c: always pass the fromlist to __import__, even if it is a C function, so PyImport_ImportModuleEx() is useful. - getmtime.c: the function has a second argument, the FILE*, on which it applies fstat(). According to Sjoerd this is much faster. The first (pathname) argument is ignored, but remains for backward compatibility (so the Mac version still works without changes). By cleverly combining the new imp functionality, the full support for dotted names in Python (mini.py, not checked in) is now about 7K, lavishly commented (vs. 14K for ni plus 11K for ihooks, also lavishly commented). Good night!
Diffstat (limited to 'Python')
-rw-r--r--Python/bltinmodule.c2
-rw-r--r--Python/ceval.c14
-rw-r--r--Python/getmtime.c6
-rw-r--r--Python/import.c571
-rw-r--r--Python/importdl.h15
5 files changed, 460 insertions, 148 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 358b6f1..251108f 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -65,7 +65,7 @@ builtin___import__(self, args)
if (!PyArg_ParseTuple(args, "s|OOO:__import__",
&name, &globals, &locals, &fromlist))
return NULL;
- return PyImport_ImportModule(name);
+ return PyImport_ImportModuleEx(name, globals, locals, fromlist);
}
diff --git a/Python/ceval.c b/Python/ceval.c
index 4bf53e8..d8c9a05 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1408,16 +1408,10 @@ eval_code2(co, globals, locals,
"__import__ not found");
break;
}
- if (PyCFunction_Check(x)) {
- u = Py_None;
- Py_INCREF(u);
- }
- else {
- u = find_from_args(f, INSTR_OFFSET());
- if (u == NULL) {
- x = u;
- break;
- }
+ u = find_from_args(f, INSTR_OFFSET());
+ if (u == NULL) {
+ x = u;
+ break;
}
w = Py_BuildValue("(OOOO)",
w,
diff --git a/Python/getmtime.c b/Python/getmtime.c
index 793c663..4bf2adf 100644
--- a/Python/getmtime.c
+++ b/Python/getmtime.c
@@ -35,15 +35,17 @@ PERFORMANCE OF THIS SOFTWARE.
#include "config.h"
+#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
long
-PyOS_GetLastModificationTime(path)
+PyOS_GetLastModificationTime(path, fp)
char *path;
+ FILE *fp;
{
struct stat st;
- if (stat(path, &st) != 0)
+ if (fstat(fileno(fp), &st) != 0)
return -1;
else
return st.st_mtime;
diff --git a/Python/import.c b/Python/import.c
index fe24b28..971e658 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -49,6 +49,22 @@ PERFORMANCE OF THIS SOFTWARE.
#include <unistd.h>
#endif
+/* We expect that stat exists on most systems.
+ It's confirmed on Unix, Mac and Windows.
+ If you don't have it, add #define DONT_HAVE_STAT to your config.h. */
+#ifndef DONT_HAVE_STAT
+#define HAVE_STAT
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef S_ISDIR
+#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+
+#endif
+
+
extern long PyOS_GetLastModificationTime(); /* In getmtime.c */
/* Magic word to reject .pyc files generated by other Python versions */
@@ -185,8 +201,8 @@ _PyImport_FixupExtension(name, filename)
modules = PyImport_GetModuleDict();
mod = PyDict_GetItemString(modules, name);
if (mod == NULL || !PyModule_Check(mod)) {
- PyErr_SetString(PyExc_SystemError,
- "_PyImport_FixupExtension: module not loaded");
+ PyErr_Format(PyExc_SystemError,
+ "_PyImport_FixupExtension: module %.200s not loaded", name);
return NULL;
}
dict = PyModule_GetDict(mod);
@@ -281,14 +297,15 @@ PyImport_ExecCodeModule(name, co)
if (PyDict_SetItemString(d, "__file__",
((PyCodeObject *)co)->co_filename) != 0)
PyErr_Clear(); /* Not important enough to report */
- v = PyEval_EvalCode((PyCodeObject *)co, d, d); /* XXX owner? */
+ v = PyEval_EvalCode((PyCodeObject *)co, d, d);
if (v == NULL)
return NULL;
Py_DECREF(v);
if ((m = PyDict_GetItemString(modules, name)) == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "loaded module not found in sys.modules");
+ PyErr_Format(PyExc_ImportError,
+ "Loaded module %.200s not found in sys.modules",
+ name);
return NULL;
}
@@ -364,7 +381,8 @@ check_compiled_module(pathname, mtime, cpathname)
/* Read a code object from a file and check it for validity */
static PyCodeObject *
-read_compiled_module(fp)
+read_compiled_module(cpathname, fp)
+ char *cpathname;
FILE *fp;
{
PyObject *co;
@@ -373,8 +391,8 @@ read_compiled_module(fp)
/* Ugly: rd_object() may return NULL with or without error */
if (co == NULL || !PyCode_Check(co)) {
if (!PyErr_Occurred())
- PyErr_SetString(PyExc_ImportError,
- "Non-code object in .pyc file");
+ PyErr_Format(PyExc_ImportError,
+ "Non-code object in %.200s", cpathname);
Py_XDECREF(co);
return NULL;
}
@@ -397,12 +415,12 @@ load_compiled_module(name, cpathname, fp)
magic = PyMarshal_ReadLongFromFile(fp);
if (magic != MAGIC) {
- PyErr_SetString(PyExc_ImportError,
- "Bad magic number in .pyc file");
+ PyErr_Format(PyExc_ImportError,
+ "Bad magic number in %.200s", cpathname);
return NULL;
}
(void) PyMarshal_ReadLongFromFile(fp);
- co = read_compiled_module(fp);
+ co = read_compiled_module(cpathname, fp);
if (co == NULL)
return NULL;
if (Py_VerboseFlag)
@@ -496,11 +514,11 @@ load_source_module(name, pathname, fp)
PyCodeObject *co;
PyObject *m;
- mtime = PyOS_GetLastModificationTime(pathname);
+ mtime = PyOS_GetLastModificationTime(pathname, fp);
cpathname = make_compiled_pathname(pathname, buf, MAXPATHLEN+1);
if (cpathname != NULL &&
(fpc = check_compiled_module(pathname, mtime, cpathname))) {
- co = read_compiled_module(fpc);
+ co = read_compiled_module(cpathname, fpc);
fclose(fpc);
if (co == NULL)
return NULL;
@@ -524,10 +542,108 @@ load_source_module(name, pathname, fp)
}
+/* Forward */
+static PyObject *load_module Py_PROTO((char *, FILE *, char *, int));
+static struct filedescr *find_module Py_PROTO((char *, PyObject *,
+ char *, int, FILE **));
+
+/* Load a package and return its module object WITH INCREMENTED
+ REFERENCE COUNT */
+
+static PyObject *
+load_package(name, pathname)
+ char *name;
+ char *pathname;
+{
+ PyObject *m, *d, *file, *path;
+ int err;
+ char buf[MAXPATHLEN+1];
+ FILE *fp = NULL;
+ struct filedescr *fdp;
+
+ m = PyImport_AddModule(name);
+ if (m == NULL)
+ return NULL;
+ d = PyModule_GetDict(m);
+ file = PyString_FromString(pathname);
+ if (file == NULL)
+ return NULL;
+ path = Py_BuildValue("[O]", file);
+ if (path == NULL) {
+ Py_DECREF(file);
+ return NULL;
+ }
+ err = PyDict_SetItemString(d, "__file__", file);
+ if (err == 0)
+ err = PyDict_SetItemString(d, "__path__", path);
+ if (err != 0) {
+ m = NULL;
+ goto cleanup;
+ }
+ buf[0] = '\0';
+ fdp = find_module("__init__", path, buf, sizeof(buf), &fp);
+ if (fdp == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_ImportError)) {
+ PyErr_Clear();
+ }
+ else
+ m = NULL;
+ goto cleanup;
+ }
+ m = load_module(name, fp, buf, fdp->type);
+ if (fp != NULL)
+ fclose(fp);
+ cleanup:
+ Py_XINCREF(m);
+ Py_XDECREF(path);
+ Py_XDECREF(file);
+ return m;
+}
+
+
+/* Helper to test for built-in module */
+
+static int
+is_builtin(name)
+ char *name;
+{
+ int i;
+ for (i = 0; _PyImport_Inittab[i].name != NULL; i++) {
+ if (strcmp(name, _PyImport_Inittab[i].name) == 0) {
+ if (_PyImport_Inittab[i].initfunc == NULL)
+ return -1;
+ else
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Helper to test for frozen module */
+
+static int
+is_frozen(name)
+ char *name;
+{
+ struct _frozen *p;
+ for (p = PyImport_FrozenModules; ; p++) {
+ if (p->name == NULL)
+ break;
+ if (strcmp(p->name, name) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+
/* Search the path (default sys.path) for a module. Return the
corresponding filedescr struct, and (via return arguments) the
pathname and an open file. Return NULL if the module is not found. */
+#ifdef MS_COREDLL
+extern FILE *PyWin_FindRegisteredModule();
+#endif
+
static struct filedescr *
find_module(name, path, buf, buflen, p_fp)
char *name;
@@ -540,14 +656,26 @@ find_module(name, path, buf, buflen, p_fp)
int i, npath, len, namelen;
struct filedescr *fdp = NULL;
FILE *fp = NULL;
+ struct stat statbuf;
+
+ if (path == NULL) {
+ if (is_builtin(name)) {
+ static struct filedescr fd = {"", "", C_BUILTIN};
+ return &fd;
+ }
+ if (is_frozen(name)) {
+ static struct filedescr fd = {"", "", PY_FROZEN};
+ return &fd;
+ }
#ifdef MS_COREDLL
- extern FILE *PyWin_FindRegisteredModule();
- if ((fp=PyWin_FindRegisteredModule(name, &fdp, buf, buflen))!=NULL) {
- *p_fp = fp;
- return fdp;
- }
+ fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen);
+ if (fp != NULL) {
+ *p_fp = fp;
+ return fdp;
+ }
#endif
+ }
if (path == NULL)
@@ -580,14 +708,18 @@ find_module(name, path, buf, buflen, p_fp)
PyString_InternInPlace(&PyList_GET_ITEM(path, i));
v = PyList_GET_ITEM(path, i);
#endif
- if ( PyMac_FindResourceModule((PyStringObject *)v, name, buf) ) {
+ if (PyMac_FindResourceModule((PyStringObject *)v, name, buf)) {
static struct filedescr resfiledescr =
{"", "", PY_RESOURCE};
return &resfiledescr;
}
#endif
- if (len > 0 && buf[len-1] != SEP)
+ if (len > 0 && buf[len-1] != SEP
+#ifdef ALTSEP
+ && buf[len-1] != ALTSEP
+#endif
+ )
buf[len++] = SEP;
#ifdef macintosh
fdp = PyMac_FindModuleExtension(buf, &len, name);
@@ -611,6 +743,15 @@ find_module(name, path, buf, buflen, p_fp)
strcpy(buf+len, name);
len += namelen;
}
+#ifdef HAVE_STAT
+ if (stat(buf, &statbuf) == 0) {
+ static struct filedescr fd = {"", "", PKG_DIRECTORY};
+ if (S_ISDIR(statbuf.st_mode))
+ return &fd;
+ }
+#else
+ /* XXX How are you going to test for directories? */
+#endif
for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
strcpy(buf+len, fdp->suffix);
if (Py_VerboseFlag > 1)
@@ -624,9 +765,8 @@ find_module(name, path, buf, buflen, p_fp)
break;
}
if (fp == NULL) {
- char buf[256];
- sprintf(buf, "No module named %.200s", name);
- PyErr_SetString(PyExc_ImportError, buf);
+ PyErr_Format(PyExc_ImportError,
+ "No module named %.200s", name);
return NULL;
}
@@ -635,23 +775,35 @@ find_module(name, path, buf, buflen, p_fp)
}
+static int init_builtin Py_PROTO((char *)); /* Forward */
+
/* Load an external module using the default search path and return
its module object WITH INCREMENTED REFERENCE COUNT */
static PyObject *
-load_module(name)
+load_module(name, fp, buf, type)
char *name;
+ FILE *fp;
+ char *buf;
+ int type;
{
- char buf[MAXPATHLEN+1];
- struct filedescr *fdp;
- FILE *fp = NULL;
+ PyObject *modules;
PyObject *m;
+ int err;
- fdp = find_module(name, (PyObject *)NULL, buf, MAXPATHLEN+1, &fp);
- if (fdp == NULL)
- return NULL;
+ /* 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 (fdp->type) {
+ switch (type) {
case PY_SOURCE:
m = load_source_module(name, buf, fp);
@@ -671,14 +823,48 @@ load_module(name)
break;
#endif
+ case PKG_DIRECTORY:
+ m = load_package(name, buf);
+ break;
+
+ case C_BUILTIN:
+ case PY_FROZEN:
+ if (type == C_BUILTIN)
+ err = init_builtin(name);
+ else
+ err = PyImport_ImportFrozenModule(name);
+ if (err < 0)
+ goto failure;
+ if (err == 0) {
+ PyErr_Format(PyExc_ImportError,
+ "Purported %s module %.200s not found",
+ type == C_BUILTIN ?
+ "builtin" : "frozen",
+ name);
+ goto failure;
+ }
+ 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);
+ goto failure;
+ }
+ Py_INCREF(m);
+ break;
+
default:
- PyErr_SetString(PyExc_SystemError,
- "find_module returned unexpected result");
+ failure:
+ PyErr_Format(PyExc_ImportError,
+ "Don't know how to import %.200s (type code %d)",
+ name, type);
m = NULL;
}
- if ( fp )
- fclose(fp);
return m;
}
@@ -701,8 +887,9 @@ init_builtin(name)
for (p = _PyImport_Inittab; p->name != NULL; p++) {
if (strcmp(name, p->name) == 0) {
if (p->initfunc == NULL) {
- PyErr_SetString(PyExc_ImportError,
- "Cannot re-init internal module");
+ PyErr_Format(PyExc_ImportError,
+ "Cannot re-init internal module %.200s",
+ name);
return -1;
}
if (Py_VerboseFlag)
@@ -743,7 +930,9 @@ get_frozen_object(name)
struct _frozen *p = find_frozen(name);
if (p == NULL) {
- PyErr_SetString(PyExc_ImportError, "No such frozen object");
+ PyErr_Format(PyExc_ImportError,
+ "No such frozen object named %.200s",
+ name);
return NULL;
}
return PyMarshal_ReadObjectFromString((char *)p->code, p->size);
@@ -771,8 +960,9 @@ PyImport_ImportFrozenModule(name)
return -1;
if (!PyCode_Check(co)) {
Py_DECREF(co);
- PyErr_SetString(PyExc_TypeError,
- "frozen object is not a code object");
+ PyErr_Format(PyExc_TypeError,
+ "frozen object %.200s is not a code object",
+ name);
return -1;
}
m = PyImport_ExecCodeModule(name, co);
@@ -791,6 +981,16 @@ PyObject *
PyImport_ImportModule(name)
char *name;
{
+ return PyImport_ImportModuleEx(name, NULL, NULL, NULL);
+}
+
+PyObject *
+PyImport_ImportModuleEx(name, globals, locals, fromlist)
+ char *name;
+ PyObject *globals;
+ PyObject *locals;
+ PyObject *fromlist;
+{
PyObject *modules = PyImport_GetModuleDict();
PyObject *m;
@@ -798,22 +998,18 @@ PyImport_ImportModule(name)
Py_INCREF(m);
}
else {
- int i;
- if ((i = init_builtin(name)) ||
- (i = PyImport_ImportFrozenModule(name))) {
- if (i < 0)
- return NULL;
- if ((m = PyDict_GetItemString(modules,
- name)) == NULL) {
- if (PyErr_Occurred() == NULL)
- PyErr_SetString(PyExc_SystemError,
- "built-in module not initialized properly");
- }
- else
- Py_INCREF(m);
- }
- else
- m = load_module(name);
+ char buf[MAXPATHLEN+1];
+ struct filedescr *fdp;
+ FILE *fp = NULL;
+
+ buf[0] = '\0';
+ fdp = find_module(name, (PyObject *)NULL,
+ buf, MAXPATHLEN+1, &fp);
+ if (fdp == NULL)
+ return NULL;
+ m = load_module(name, fp, buf, fdp->type);
+ if (fp)
+ fclose(fp);
}
return m;
@@ -829,7 +1025,9 @@ PyImport_ReloadModule(m)
{
PyObject *modules = PyImport_GetModuleDict();
char *name;
- int i;
+ char buf[MAXPATHLEN+1];
+ struct filedescr *fdp;
+ FILE *fp = NULL;
if (m == NULL || !PyModule_Check(m)) {
PyErr_SetString(PyExc_TypeError,
@@ -840,19 +1038,18 @@ PyImport_ReloadModule(m)
if (name == NULL)
return NULL;
if (m != PyDict_GetItemString(modules, name)) {
- PyErr_SetString(PyExc_ImportError,
- "reload() module not in sys.modules");
+ PyErr_Format(PyExc_ImportError,
+ "reload(): module %.200s not in sys.modules",
+ name);
return NULL;
}
- /* Check for built-in and frozen modules */
- if ((i = init_builtin(name)) ||
- (i = PyImport_ImportFrozenModule(name))) {
- if (i < 0)
- return NULL;
- Py_INCREF(m);
- }
- else
- m = load_module(name);
+ buf[0] = '\0';
+ fdp = find_module(name, (PyObject *)NULL, buf, MAXPATHLEN+1, &fp);
+ if (fdp == NULL)
+ return NULL;
+ m = load_module(name, fp, buf, fdp->type);
+ if (fp)
+ fclose(fp);
return m;
}
@@ -987,27 +1184,31 @@ imp_get_suffixes(self, args)
}
static PyObject *
-imp_find_module(self, args)
- PyObject *self;
- PyObject *args;
+call_find_module(name, path)
+ char *name;
+ PyObject *path; /* list or NULL */
{
extern int fclose Py_PROTO((FILE *));
- char *name;
- PyObject *path = NULL;
PyObject *fob, *ret;
struct filedescr *fdp;
char pathname[MAXPATHLEN+1];
- FILE *fp;
- if (!PyArg_ParseTuple(args, "s|O!", &name, &PyList_Type, &path))
- return NULL;
+ FILE *fp = NULL;
+
+ pathname[0] = '\0';
fdp = find_module(name, path, pathname, MAXPATHLEN+1, &fp);
if (fdp == NULL)
return NULL;
- fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose);
- if (fob == NULL) {
- fclose(fp);
- return NULL;
+ if (fp != NULL) {
+ fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose);
+ if (fob == NULL) {
+ fclose(fp);
+ return NULL;
+ }
}
+ else {
+ fob = Py_None;
+ Py_INCREF(fob);
+ }
ret = Py_BuildValue("Os(ssi)",
fob, pathname, fdp->suffix, fdp->mode, fdp->type);
Py_DECREF(fob);
@@ -1015,6 +1216,18 @@ imp_find_module(self, args)
}
static PyObject *
+imp_find_module(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *name;
+ PyObject *path = NULL;
+ if (!PyArg_ParseTuple(args, "s|O!", &name, &PyList_Type, &path))
+ return NULL;
+ return call_find_module(name, path);
+}
+
+static PyObject *
imp_init_builtin(self, args)
PyObject *self;
PyObject *args;
@@ -1075,19 +1288,10 @@ imp_is_builtin(self, args)
PyObject *self;
PyObject *args;
{
- int i;
char *name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
- for (i = 0; _PyImport_Inittab[i].name != NULL; i++) {
- if (strcmp(name, _PyImport_Inittab[i].name) == 0) {
- if (_PyImport_Inittab[i].initfunc == NULL)
- return PyInt_FromLong(-1);
- else
- return PyInt_FromLong(1);
- }
- }
- return PyInt_FromLong(0);
+ return PyInt_FromLong(is_builtin(name));
}
static PyObject *
@@ -1095,17 +1299,10 @@ imp_is_frozen(self, args)
PyObject *self;
PyObject *args;
{
- struct _frozen *p;
char *name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
- for (p = PyImport_FrozenModules; ; p++) {
- if (p->name == NULL)
- break;
- if (strcmp(p->name, name) == 0)
- return PyInt_FromLong(1);
- }
- return PyInt_FromLong(0);
+ return PyInt_FromLong(is_frozen(name));
}
static FILE *
@@ -1139,13 +1336,15 @@ imp_load_compiled(self, args)
PyObject *fob = NULL;
PyObject *m;
FILE *fp;
- if (!PyArg_ParseTuple(args, "ssO!", &name, &pathname,
+ if (!PyArg_ParseTuple(args, "ss|O!", &name, &pathname,
&PyFile_Type, &fob))
return NULL;
fp = get_file(pathname, fob, "rb");
if (fp == NULL)
return NULL;
m = load_compiled_module(name, pathname, fp);
+ if (fob == NULL)
+ fclose(fp);
return m;
}
@@ -1162,8 +1361,11 @@ imp_load_dynamic(self, args)
if (!PyArg_ParseTuple(args, "ss|O!", &name, &pathname,
&PyFile_Type, &fob))
return NULL;
- if (fob)
+ if (fob) {
fp = get_file(pathname, fob, "r");
+ if (fp == NULL)
+ return NULL;
+ }
m = _PyImport_LoadDynamicModule(name, pathname, fp);
return m;
}
@@ -1178,13 +1380,15 @@ imp_load_source(self, args)
PyObject *fob = NULL;
PyObject *m;
FILE *fp;
- if (!PyArg_ParseTuple(args, "ssO!", &name, &pathname,
+ if (!PyArg_ParseTuple(args, "ss|O!", &name, &pathname,
&PyFile_Type, &fob))
return NULL;
fp = get_file(pathname, fob, "r");
if (fp == NULL)
return NULL;
m = load_source_module(name, pathname, fp);
+ if (fob == NULL)
+ fclose(fp);
return m;
}
@@ -1206,6 +1410,55 @@ imp_load_resource(self, args)
#endif /* macintosh */
static PyObject *
+imp_load_module(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *name;
+ PyObject *fob;
+ char *pathname;
+ char *suffix; /* Unused */
+ char *mode;
+ int type;
+ FILE *fp;
+
+ if (!PyArg_ParseTuple(args, "sOs(ssi)",
+ &name, &fob, &pathname,
+ &suffix, &mode, &type))
+ return NULL;
+ if (*mode && (*mode != 'r' || strchr(mode, '+') != NULL)) {
+ PyErr_Format(PyExc_ValueError,
+ "invalid file open mode %.200s", mode);
+ return NULL;
+ }
+ if (fob == Py_None)
+ fp = NULL;
+ else {
+ if (!PyFile_Check(fob)) {
+ PyErr_SetString(PyExc_ValueError,
+ "load_module arg#2 should be a file or None");
+ return NULL;
+ }
+ fp = get_file(pathname, fob, mode);
+ if (fp == NULL)
+ return NULL;
+ }
+ return load_module(name, fp, pathname, type);
+}
+
+static PyObject *
+imp_load_package(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *name;
+ char *pathname;
+ if (!PyArg_ParseTuple(args, "ss", &name, &pathname))
+ return NULL;
+ return load_package(name, pathname);
+}
+
+static PyObject *
imp_new_module(self, args)
PyObject *self;
PyObject *args;
@@ -1216,56 +1469,114 @@ imp_new_module(self, args)
return PyModule_New(name);
}
+static PyObject *
+imp_find_module_in_package(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ PyObject *name;
+ PyObject *packagename = NULL;
+ PyObject *package;
+ PyObject *modules;
+ PyObject *path;
+
+ if (!PyArg_ParseTuple(args, "S|S", &name, &packagename))
+ return NULL;
+ if (packagename == NULL || PyString_GET_SIZE(packagename) == 0) {
+ return call_find_module(
+ PyString_AS_STRING(name),
+ (PyObject *)NULL);
+ }
+ modules = PyImport_GetModuleDict();
+ package = PyDict_GetItem(modules, packagename);
+ if (package == NULL) {
+ PyErr_Format(PyExc_ImportError,
+ "No package named %.200s",
+ PyString_AS_STRING(packagename));
+ return NULL;
+ }
+ path = PyObject_GetAttrString(package, "__path__");
+ if (path == NULL) {
+ PyErr_Format(PyExc_ImportError,
+ "Package %.200s has no __path__ attribute",
+ PyString_AS_STRING(packagename));
+ return NULL;
+ }
+ return call_find_module(PyString_AS_STRING(name), path);
+}
+
+static PyObject *
+imp_find_module_in_directory(self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ PyObject *name;
+ PyObject *directory;
+ PyObject *path;
+
+ if (!PyArg_ParseTuple(args, "SS", &name, &directory))
+ return NULL;
+ path = Py_BuildValue("[O]", directory);
+ if (path == NULL)
+ return NULL;
+ return call_find_module(PyString_AS_STRING(name), path);
+}
+
static PyMethodDef imp_methods[] = {
+ {"find_module", imp_find_module, 1},
+ {"find_module_in_directory", imp_find_module_in_directory, 1},
+ {"find_module_in_package", imp_find_module_in_package, 1},
{"get_frozen_object", imp_get_frozen_object, 1},
{"get_magic", imp_get_magic, 1},
{"get_suffixes", imp_get_suffixes, 1},
- {"find_module", imp_find_module, 1},
{"init_builtin", imp_init_builtin, 1},
{"init_frozen", imp_init_frozen, 1},
{"is_builtin", imp_is_builtin, 1},
{"is_frozen", imp_is_frozen, 1},
{"load_compiled", imp_load_compiled, 1},
{"load_dynamic", imp_load_dynamic, 1},
- {"load_source", imp_load_source, 1},
- {"new_module", imp_new_module, 1},
+ {"load_module", imp_load_module, 1},
+ {"load_package", imp_load_package, 1},
#ifdef macintosh
{"load_resource", imp_load_resource, 1},
#endif
+ {"load_source", imp_load_source, 1},
+ {"new_module", imp_new_module, 1},
{NULL, NULL} /* sentinel */
};
+int
+setint(d, name, value)
+ PyObject *d;
+ char *name;
+ int value;
+{
+ PyObject *v;
+ int err;
+
+ v = PyInt_FromLong((long)value);
+ err = PyDict_SetItemString(d, name, v);
+ Py_XDECREF(v);
+ return err;
+}
+
void
initimp()
{
- PyObject *m, *d, *v;
+ PyObject *m, *d;
m = Py_InitModule("imp", imp_methods);
d = PyModule_GetDict(m);
- v = PyInt_FromLong(SEARCH_ERROR);
- PyDict_SetItemString(d, "SEARCH_ERROR", v);
- Py_XDECREF(v);
-
- v = PyInt_FromLong(PY_SOURCE);
- PyDict_SetItemString(d, "PY_SOURCE", v);
- Py_XDECREF(v);
-
- v = PyInt_FromLong(PY_COMPILED);
- PyDict_SetItemString(d, "PY_COMPILED", v);
- Py_XDECREF(v);
-
- v = PyInt_FromLong(C_EXTENSION);
- PyDict_SetItemString(d, "C_EXTENSION", v);
- Py_XDECREF(v);
-
-#ifdef macintosh
- v = PyInt_FromLong(PY_RESOURCE);
- PyDict_SetItemString(d, "PY_RESOURCE", v);
- Py_XDECREF(v);
-#endif
-
-
- if (PyErr_Occurred())
- Py_FatalError("imp module initialization failed");
+ if (setint(d, "SEARCH_ERROR", SEARCH_ERROR) < 0) goto failure;
+ if (setint(d, "PY_SOURCE", PY_SOURCE) < 0) goto failure;
+ if (setint(d, "PY_COMPILED", PY_COMPILED) < 0) goto failure;
+ if (setint(d, "C_EXTENSION", C_EXTENSION) < 0) goto failure;
+ if (setint(d, "PY_RESOURCE", PY_RESOURCE) < 0) goto failure;
+ if (setint(d, "PKG_DIRECTORY", PKG_DIRECTORY) < 0) goto failure;
+ if (setint(d, "C_BUILTIN", C_BUILTIN) < 0) goto failure;
+ if (setint(d, "PY_FROZEN", PY_FROZEN) < 0) goto failure;
+
+ failure:
+ ;
}
diff --git a/Python/importdl.h b/Python/importdl.h
index 4587841..fb50ded 100644
--- a/Python/importdl.h
+++ b/Python/importdl.h
@@ -30,11 +30,16 @@ PERFORMANCE OF THIS SOFTWARE.
******************************************************************/
/* Definitions for dynamic loading of extension modules */
-#ifdef macintosh
-enum filetype {SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE};
-#else
-enum filetype {SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION};
-#endif
+enum filetype {
+ SEARCH_ERROR,
+ PY_SOURCE,
+ PY_COMPILED,
+ C_EXTENSION,
+ PY_RESOURCE, /* Mac only */
+ PKG_DIRECTORY,
+ C_BUILTIN,
+ PY_FROZEN
+};
extern struct filedescr {
char *suffix;