Issue #13959: Re-implement imp.find_module() in Lib/imp.py.

Thanks to Eric Snow for taking an initial stab at the implementation.
This commit is contained in:
Brett Cannon 2012-04-21 21:09:46 -04:00
parent b8c0206bd4
commit e69f0df45b
2 changed files with 68 additions and 755 deletions

View File

@ -15,16 +15,29 @@ from _imp import get_magic, get_tag
# Can (probably) move to importlib
from _imp import get_suffixes
# Should be re-implemented here (and mostly deprecated)
from _imp import (find_module, NullImporter,
SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION,
PY_RESOURCE, PKG_DIRECTORY, C_BUILTIN, PY_FROZEN,
PY_CODERESOURCE, IMP_HOOK)
from _imp import NullImporter
from importlib._bootstrap import _new_module as new_module
from importlib._bootstrap import _cache_from_source as cache_from_source
from importlib import _bootstrap
import os
import sys
import tokenize
# XXX "deprecate" once find_module(), load_module(), and get_suffixes() are
# deprecated.
SEARCH_ERROR = 0
PY_SOURCE = 1
PY_COMPILED = 2
C_EXTENSION = 3
PY_RESOURCE = 4
PKG_DIRECTORY = 5
C_BUILTIN = 6
PY_FROZEN = 7
PY_CODERESOURCE = 8
IMP_HOOK = 9
def source_from_cache(path):
@ -131,3 +144,54 @@ def load_module(name, file, filename, details):
else:
msg = "Don't know how to import {} (type code {}".format(name, type_)
raise ImportError(msg, name=name)
def find_module(name, path=None):
"""Search for a module.
If path is omitted or None, search for a built-in, frozen or special
module and continue search in sys.path. The module name cannot
contain '.'; to search for a submodule of a package, pass the
submodule name and the package's __path__.
"""
if not isinstance(name, str):
raise TypeError("'name' must be a str, not {}".format(type(name)))
elif not isinstance(path, (type(None), list)):
# Backwards-compatibility
raise RuntimeError("'list' must be None or a list, "
"not {}".format(type(name)))
if path is None:
if is_builtin(name):
return None, None, ('', '', C_BUILTIN)
elif is_frozen(name):
return None, None, ('', '', PY_FROZEN)
else:
path = sys.path
for entry in path:
package_directory = os.path.join(entry, name)
for suffix in ['.py', _bootstrap.BYTECODE_SUFFIX]:
package_file_name = '__init__' + suffix
file_path = os.path.join(package_directory, package_file_name)
if os.path.isfile(file_path):
return None, package_directory, ('', '', PKG_DIRECTORY)
for suffix, mode, type_ in get_suffixes():
file_name = name + suffix
file_path = os.path.join(entry, file_name)
if os.path.isfile(file_path):
break
else:
continue
break # Break out of outer loop when breaking out of inner loop.
else:
raise ImportError('No module name {!r}'.format(name), name=name)
encoding = None
if mode == 'U':
with open(file_path, 'rb') as file:
encoding = tokenize.detect_encoding(file.readline)[0]
file = open(file_path, mode, encoding=encoding)
return file, file_path, (suffix, mode, type_)

View File

@ -1118,8 +1118,6 @@ unchanged:
}
/* Forward */
static struct filedescr *find_module(PyObject *, PyObject *, PyObject *,
PyObject **, FILE **, PyObject **);
static struct _frozen * find_frozen(PyObject *);
@ -1220,678 +1218,12 @@ PyImport_GetImporter(PyObject *path) {
return importer;
}
/* 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(PyObject *, struct filedescr **,
PyObject **p_path);
#endif
/* Forward */
static int case_ok(PyObject *, Py_ssize_t, PyObject *);
static int find_init_module(PyObject *);
static struct filedescr importhookdescr = {"", "", IMP_HOOK};
/* Get the path of a module: get its importer and call importer.find_module()
hook, or check if the module if a package (if path/__init__.py exists).
-1: error: a Python error occurred
0: ignore: an error occurred because of invalid data, but the error is not
important enough to be reported.
1: get path: module not found, but *buf contains its path
2: found: *p_fd is the file descriptor (IMP_HOOK or PKG_DIRECTORY)
and *buf is the path */
static int
find_module_path(PyObject *fullname, PyObject *name, PyObject *path,
PyObject *path_hooks, PyObject *path_importer_cache,
PyObject **p_path, PyObject **p_loader, struct filedescr **p_fd)
{
PyObject *path_unicode, *filename = NULL;
Py_ssize_t len, pos;
struct stat statbuf;
static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
int err, result, addsep;
if (PyUnicode_Check(path)) {
Py_INCREF(path);
path_unicode = path;
}
else if (PyBytes_Check(path)) {
path_unicode = PyUnicode_DecodeFSDefaultAndSize(
PyBytes_AS_STRING(path), PyBytes_GET_SIZE(path));
if (path_unicode == NULL)
return -1;
}
else
return 0;
if (PyUnicode_READY(path_unicode))
return -1;
len = PyUnicode_GET_LENGTH(path_unicode);
if (PyUnicode_FindChar(path_unicode, 0, 0, len, 1) != -1) {
result = 0;
goto out; /* path contains '\0' */
}
/* sys.path_hooks import hook */
if (p_loader != NULL) {
_Py_IDENTIFIER(find_module);
PyObject *importer;
importer = get_path_importer(path_importer_cache,
path_hooks, path);
if (importer == NULL) {
result = -1;
goto out;
}
/* Note: importer is a borrowed reference */
if (importer != Py_None) {
PyObject *loader;
loader = _PyObject_CallMethodId(importer,
&PyId_find_module, "O", fullname);
if (loader == NULL) {
result = -1; /* error */
goto out;
}
if (loader != Py_None) {
/* a loader was found */
*p_loader = loader;
*p_fd = &importhookdescr;
result = 2;
goto out;
}
Py_DECREF(loader);
result = 0;
goto out;
}
}
/* no hook was found, use builtin import */
addsep = 0;
if (len > 0 && PyUnicode_READ_CHAR(path_unicode, len-1) != SEP
#ifdef ALTSEP
&& PyUnicode_READ_CHAR(path_unicode, len-1) != ALTSEP
#endif
)
addsep = 1;
filename = PyUnicode_New(len + PyUnicode_GET_LENGTH(name) + addsep,
Py_MAX(PyUnicode_MAX_CHAR_VALUE(path_unicode),
PyUnicode_MAX_CHAR_VALUE(name)));
if (filename == NULL) {
result = -1;
goto out;
}
PyUnicode_CopyCharacters(filename, 0, path_unicode, 0, len);
pos = len;
if (addsep)
PyUnicode_WRITE(PyUnicode_KIND(filename),
PyUnicode_DATA(filename),
pos++, SEP);
PyUnicode_CopyCharacters(filename, pos, name, 0,
PyUnicode_GET_LENGTH(name));
/* Check for package import (buf holds a directory name,
and there's an __init__ module in that directory */
#ifdef HAVE_STAT
err = _Py_stat(filename, &statbuf);
if (err == -2) {
result = -1;
goto out;
}
if (err == 0 && /* it exists */
S_ISDIR(statbuf.st_mode)) /* it's a directory */
{
int match;
match = case_ok(filename, 0, name);
if (match < 0) {
result = -1;
goto out;
}
if (match) { /* case matches */
if (find_init_module(filename)) { /* and has __init__.py */
*p_path = filename;
filename = NULL;
*p_fd = &fd_package;
result = 2;
goto out;
}
else {
int err;
err = PyErr_WarnFormat(PyExc_ImportWarning, 1,
"Not importing directory %R: missing __init__.py",
filename);
if (err) {
result = -1;
goto out;
}
}
}
}
#endif
*p_path = filename;
filename = NULL;
result = 1;
out:
Py_DECREF(path_unicode);
Py_XDECREF(filename);
return result;
}
/* Find a module in search_path_list. For each path, try
find_module_path() or try each _PyImport_Filetab suffix.
If the module is found, return a file descriptor, write the path in
*p_filename, write the pointer to the file object into *p_fp, and (if
p_loader is not NULL) the loader into *p_loader.
Otherwise, raise an exception and return NULL. */
static struct filedescr*
find_module_path_list(PyObject *fullname, PyObject *name,
PyObject *search_path_list, PyObject *path_hooks,
PyObject *path_importer_cache,
PyObject **p_path, FILE **p_fp, PyObject **p_loader)
{
Py_ssize_t i, npath;
struct filedescr *fdp = NULL;
char *filemode;
FILE *fp = NULL;
PyObject *prefix, *filename;
int match;
int err;
npath = PyList_Size(search_path_list);
for (i = 0; i < npath; i++) {
PyObject *path;
int ok;
path = PyList_GetItem(search_path_list, i);
if (path == NULL)
return NULL;
prefix = NULL;
ok = find_module_path(fullname, name, path,
path_hooks, path_importer_cache,
&prefix, p_loader, &fdp);
if (ok < 0)
return NULL;
if (ok == 0)
continue;
if (ok == 2) {
*p_path = prefix;
return fdp;
}
for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
struct stat statbuf;
filemode = fdp->mode;
if (filemode[0] == 'U')
filemode = "r" PY_STDIOTEXTMODE;
filename = PyUnicode_FromFormat("%U%s", prefix, fdp->suffix);
if (filename == NULL) {
Py_DECREF(prefix);
return NULL;
}
if (Py_VerboseFlag > 1)
PySys_FormatStderr("# trying %R\n", filename);
err = _Py_stat(filename, &statbuf);
if (err == -2) {
Py_DECREF(prefix);
Py_DECREF(filename);
return NULL;
}
if (err != 0 || S_ISDIR(statbuf.st_mode)) {
/* it doesn't exist, or it's a directory */
Py_DECREF(filename);
continue;
}
fp = _Py_fopen(filename, filemode);
if (fp == NULL) {
Py_DECREF(filename);
if (PyErr_Occurred()) {
Py_DECREF(prefix);
return NULL;
}
continue;
}
match = case_ok(filename, -(Py_ssize_t)strlen(fdp->suffix), name);
if (match < 0) {
Py_DECREF(prefix);
Py_DECREF(filename);
return NULL;
}
if (match) {
Py_DECREF(prefix);
*p_path = filename;
*p_fp = fp;
return fdp;
}
Py_DECREF(filename);
fclose(fp);
fp = NULL;
}
Py_DECREF(prefix);
}
PyErr_Format(PyExc_ImportError,
"No module named %R", name);
return NULL;
}
/* Find a module:
- try find_module() of each sys.meta_path hook
- try find_frozen()
- try is_builtin()
- try _PyWin_FindRegisteredModule() (Windows only)
- otherwise, call find_module_path_list() with search_path_list (if not
NULL) or sys.path
fullname can be NULL, but only if p_loader is NULL.
Return:
- &fd_builtin (C_BUILTIN) if it is a builtin
- &fd_frozen (PY_FROZEN) if it is frozen
- &fd_package (PKG_DIRECTORY) and write the filename into *p_path
if it is a package
- &importhookdescr (IMP_HOOK) and write the loader into *p_loader if a
importer loader was found
- a file descriptor (PY_SOURCE, PY_COMPILED, C_EXTENSION, PY_RESOURCE or
PY_CODERESOURCE: see _PyImport_Filetab), write the filename into
*p_path and the pointer to the open file into *p_fp
- NULL on error
By default, *p_path, *p_fp and *p_loader (if set) are set to NULL.
Eg. *p_path is set to NULL for a builtin package.
*/
static struct filedescr *
find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list,
PyObject **p_path, FILE **p_fp, PyObject **p_loader)
{
Py_ssize_t i, npath;
static struct filedescr fd_frozen = {"", "", PY_FROZEN};
static struct filedescr fd_builtin = {"", "", C_BUILTIN};
PyObject *path_hooks, *path_importer_cache;
*p_path = NULL;
*p_fp = NULL;
if (p_loader != NULL)
*p_loader = NULL;
/* sys.meta_path import hook */
if (p_loader != NULL) {
_Py_IDENTIFIER(find_module);
PyObject *meta_path;
meta_path = PySys_GetObject("meta_path");
if (meta_path == NULL || !PyList_Check(meta_path)) {
PyErr_SetString(PyExc_RuntimeError,
"sys.meta_path must be a list of "
"import hooks");
return NULL;
}
Py_INCREF(meta_path); /* zap guard */
npath = PyList_Size(meta_path);
for (i = 0; i < npath; i++) {
PyObject *loader;
PyObject *hook = PyList_GetItem(meta_path, i);
loader = _PyObject_CallMethodId(hook, &PyId_find_module,
"OO", fullname,
search_path_list != NULL ?
search_path_list : Py_None);
if (loader == NULL) {
Py_DECREF(meta_path);
return NULL; /* true error */
}
if (loader != Py_None) {
/* a loader was found */
*p_loader = loader;
Py_DECREF(meta_path);
return &importhookdescr;
}
Py_DECREF(loader);
}
Py_DECREF(meta_path);
}
if (find_frozen(fullname) != NULL)
return &fd_frozen;
if (search_path_list == NULL) {
#ifdef MS_COREDLL
FILE *fp;
struct filedescr *fdp;
#endif
if (is_builtin(name))
return &fd_builtin;
#ifdef MS_COREDLL
fp = _PyWin_FindRegisteredModule(name, &fdp, p_path);
if (fp != NULL) {
*p_fp = fp;
return fdp;
}
else if (PyErr_Occurred())
return NULL;
#endif
search_path_list = PySys_GetObject("path");
}
if (search_path_list == NULL || !PyList_Check(search_path_list)) {
PyErr_SetString(PyExc_RuntimeError,
"sys.path must be a list of directory names");
return NULL;
}
path_hooks = PySys_GetObject("path_hooks");
if (path_hooks == NULL || !PyList_Check(path_hooks)) {
PyErr_SetString(PyExc_RuntimeError,
"sys.path_hooks must be a list of "
"import hooks");
return NULL;
}
path_importer_cache = PySys_GetObject("path_importer_cache");
if (path_importer_cache == NULL ||
!PyDict_Check(path_importer_cache)) {
PyErr_SetString(PyExc_RuntimeError,
"sys.path_importer_cache must be a dict");
return NULL;
}
return find_module_path_list(fullname, name,
search_path_list, path_hooks,
path_importer_cache,
p_path, p_fp, p_loader);
}
/* case_bytes(char* buf, Py_ssize_t len, Py_ssize_t 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_bytes() is to return 1 if there's a case-sensitive match for
* name, else 0. case_bytes() is also to return 1 if envar PYTHONCASEOK
* exists.
*
* case_bytes() 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_bytes().
*/
#if defined(MS_WINDOWS)
#include <windows.h>
#elif defined(DJGPP)
#include <dir.h>
#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
#include <sys/types.h>
#include <dirent.h>
#elif defined(PYOS_OS2)
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_NOPMAPI
#include <os2.h>
#endif
#if defined(DJGPP) \
|| ((defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) \
&& defined(HAVE_DIRENT_H)) \
|| defined(PYOS_OS2)
# define USE_CASE_OK_BYTES
#endif
#ifdef USE_CASE_OK_BYTES
static int
case_bytes(char *buf, Py_ssize_t len, Py_ssize_t namelen, const char *name)
{
/* Pick a platform-specific implementation; the sequence of #if's here should
* match the sequence just above.
*/
/* DJGPP */
#if 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 -1;
}
return strncmp(ffblk.ff_name, name, namelen) == 0;
/* new-fangled macintosh (macosx) or Cygwin */
#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && 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 */
/* OS/2 */
#elif defined(PYOS_OS2)
HDIR hdir = 1;
ULONG srchcnt = 1;
FILEFINDBUF3 ffbuf;
APIRET rc;
if (Py_GETENV("PYTHONCASEOK") != NULL)
return 1;
rc = DosFindFirst(buf,
&hdir,
FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
&ffbuf, sizeof(ffbuf),
&srchcnt,
FIL_STANDARD);
if (rc != NO_ERROR)
return 0;
return strncmp(ffbuf.achName, name, namelen) == 0;
/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
#else
# error "USE_CASE_OK_BYTES is not correctly defined"
#endif
}
#endif
/*
* Check if a filename case matchs the name case. 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, 0 if it
* the filename doesn't match, or -1 on error. 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.
*/
static int
case_ok(PyObject *filename, Py_ssize_t prefix_delta, PyObject *name)
{
#ifdef MS_WINDOWS
WIN32_FIND_DATAW data;
HANDLE h;
int cmp;
wchar_t *wfilename, *wname;
Py_ssize_t wname_len;
if (Py_GETENV("PYTHONCASEOK") != NULL)
return 1;
wfilename = PyUnicode_AsUnicode(filename);
if (wfilename == NULL)
return -1;
h = FindFirstFileW(wfilename, &data);
if (h == INVALID_HANDLE_VALUE) {
PyErr_Format(PyExc_NameError,
"Can't find file for module %R\n(filename %R)",
name, filename);
return -1;
}
FindClose(h);
wname = PyUnicode_AsUnicodeAndSize(name, &wname_len);
if (wname == NULL)
return -1;
cmp = wcsncmp(data.cFileName, wname, wname_len);
return cmp == 0;
#elif defined(USE_CASE_OK_BYTES)
int match;
PyObject *filebytes, *namebytes;
filebytes = PyUnicode_EncodeFSDefault(filename);
if (filebytes == NULL)
return -1;
namebytes = PyUnicode_EncodeFSDefault(name);
if (namebytes == NULL) {
Py_DECREF(filebytes);
return -1;
}
match = case_bytes(
PyBytes_AS_STRING(filebytes),
PyBytes_GET_SIZE(filebytes) + prefix_delta,
PyBytes_GET_SIZE(namebytes),
PyBytes_AS_STRING(namebytes));
Py_DECREF(filebytes);
Py_DECREF(namebytes);
return match;
#else
/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
return 1;
#endif
}
#ifdef HAVE_STAT
/* Helper to look for __init__.py or __init__.py[co] in potential package.
Return 1 if __init__ was found, 0 if not, or -1 on error. */
static int
find_init_module(PyObject *directory)
{
struct stat statbuf;
PyObject *filename;
int match;
int err;
filename = PyUnicode_FromFormat("%U%c__init__.py", directory, SEP);
if (filename == NULL)
return -1;
err = _Py_stat(filename, &statbuf);
if (err == -2)
return -1;
if (err == 0) {
/* 3=len(".py") */
match = case_ok(filename, -3, initstr);
if (match < 0) {
Py_DECREF(filename);
return -1;
}
if (match) {
Py_DECREF(filename);
return 1;
}
}
Py_DECREF(filename);
filename = PyUnicode_FromFormat("%U%c__init__.py%c",
directory, SEP, Py_OptimizeFlag ? 'o' : 'c');
if (filename == NULL)
return -1;
err = _Py_stat(filename, &statbuf);
if (err == -2) {
Py_DECREF(filename);
return -1;
}
if (err == 0) {
/* 4=len(".pyc") */
match = case_ok(filename, -4, initstr);
if (match < 0) {
Py_DECREF(filename);
return -1;
}
if (match) {
Py_DECREF(filename);
return 1;
}
}
Py_DECREF(filename);
return 0;
}
#endif /* HAVE_STAT */
static int init_builtin(PyObject *); /* Forward */
@ -2688,81 +2020,6 @@ imp_get_suffixes(PyObject *self, PyObject *noargs)
return list;
}
static PyObject *
call_find_module(PyObject *name, PyObject *path_list)
{
extern int fclose(FILE *);
PyObject *fob, *ret;
PyObject *pathobj;
struct filedescr *fdp;
FILE *fp;
int fd = -1;
char *found_encoding = NULL;
char *encoding = NULL;
if (path_list == Py_None)
path_list = NULL;
fdp = find_module(NULL, name, path_list,
&pathobj, &fp, NULL);
if (fdp == NULL)
return NULL;
if (fp != NULL) {
fd = fileno(fp);
if (fd != -1)
fd = dup(fd);
fclose(fp);
fp = NULL;
if (fd == -1)
return PyErr_SetFromErrno(PyExc_OSError);
}
if (fd != -1) {
if (strchr(fdp->mode, 'b') == NULL) {
/* PyTokenizer_FindEncodingFilename() returns PyMem_MALLOC'ed
memory. */
found_encoding = PyTokenizer_FindEncodingFilename(fd, pathobj);
lseek(fd, 0, 0); /* Reset position */
if (found_encoding == NULL && PyErr_Occurred()) {
Py_XDECREF(pathobj);
close(fd);
return NULL;
}
encoding = (found_encoding != NULL) ? found_encoding :
(char*)PyUnicode_GetDefaultEncoding();
}
fob = PyFile_FromFd(fd, NULL, fdp->mode, -1,
(char*)encoding, NULL, NULL, 1);
if (fob == NULL) {
Py_XDECREF(pathobj);
close(fd);
PyMem_FREE(found_encoding);
return NULL;
}
}
else {
fob = Py_None;
Py_INCREF(fob);
}
if (pathobj == NULL) {
Py_INCREF(Py_None);
pathobj = Py_None;
}
ret = Py_BuildValue("NN(ssi)",
fob, pathobj, fdp->suffix, fdp->mode, fdp->type);
PyMem_FREE(found_encoding);
return ret;
}
static PyObject *
imp_find_module(PyObject *self, PyObject *args)
{
PyObject *name, *path_list = NULL;
if (!PyArg_ParseTuple(args, "U|O:find_module",
&name, &path_list))
return NULL;
return call_find_module(name, path_list);
}
static PyObject *
imp_init_builtin(PyObject *self, PyObject *args)
{
@ -2931,13 +2188,6 @@ Reload the module. The module must have been successfully imported before.");
PyDoc_STRVAR(doc_imp,
"(Extremely) low-level import machinery bits as used by importlib and imp.");
PyDoc_STRVAR(doc_find_module,
"find_module(name, [path]) -> (file, filename, (suffix, mode, type))\n\
Search for a module. If path is omitted or None, search for a\n\
built-in, frozen or special module and continue search in sys.path.\n\
The module name cannot contain '.'; to search for a submodule of a\n\
package, pass the submodule name and the package's __path__.");
PyDoc_STRVAR(doc_get_magic,
"get_magic() -> string\n\
Return the magic number for .pyc or .pyo files.");
@ -2969,7 +2219,6 @@ Release the interpreter's import lock.\n\
On platforms without threads, this function does nothing.");
static PyMethodDef imp_methods[] = {
{"find_module", imp_find_module, METH_VARARGS, doc_find_module},
{"get_magic", imp_get_magic, METH_NOARGS, doc_get_magic},
{"get_tag", imp_get_tag, METH_NOARGS, doc_get_tag},
{"get_suffixes", imp_get_suffixes, METH_NOARGS, doc_get_suffixes},