[Python-Dev] New universal import mechanism ( Re: [Python-checkins] python/dist/src/Python import.c,2.210,2.211)
Wiktor Sadowski
Wiktor Sadowski" <art@wiktorsadowski.com
Sun, 1 Dec 2002 02:16:52 +0100
This is a multi-part message in MIME format.
------=_NextPart_000_002D_01C298DF.B68FC6C0
Content-Type: text/plain;
charset="windows-1250"
Content-Transfer-Encoding: quoted-printable
I think Python should have a more universal import mechanism , which =
could be done
by adding a new C_CUSTOM type to the definitions for dynamic loading =
(importdl.h) ,
a new struct _customtab to import.h and a new function to Python API =
(import.c).
Then any archive,database,internet import architecture could be =
implemented=20
in C extensions without messing with Python core.
Wiktor Sadowski
www.wiktorsadowski.com
IMPLEMENTATION
(tested on win_98)
import.h
extern DL_IMPORT(int) PyImport_AppendCustomtab(int =
(*get_name)(char*),void (*initfunc)(char*));
struct _customtab {
int (*get_name)(char*);
void (*initfunc)(char*);
struct _customtab *next;
};
importdl.h
enum filetype {
SEARCH_ERROR,
PY_SOURCE,
PY_COMPILED,
C_EXTENSION,
PY_RESOURCE, /* Mac only */
PKG_DIRECTORY,
C_BUILTIN,
PY_FROZEN,
C_CUSTOM,
PY_CODERESOURCE /* Mac only */
};
import.c
struct _customtab *PyImport_Customtab;
int=20
PyImport_AppendCustomtab(int (*get_name)(char*),void =
(*initfunc)(char*))
{
struct _customtab *pycustomtab;
struct _customtab *newtab=3DPyMem_NEW(struct _customtab,1);
newtab->get_name=3Dget_name;
newtab->initfunc=3Dinitfunc;
newtab->next=3DNULL;
pycustomtab=3DPyImport_Customtab;
if (pycustomtab)
{
while(pycustomtab->next)
pycustomtab=3Dpycustomtab->next;=20
pycustomtab->next=3Dnewtab;
}
else
PyImport_Customtab=3Dnewtab;
return 1;=20
}
static struct filedescr *
find_module(char *realname, PyObject *path, char *buf, size_t buflen,
FILE **p_fp)
.........................................................................=
..........................
static struct filedescr fd_custom =3D {"", "", C_CUSTOM};
.........................................................................=
..........................
before find_frozen !:
if (is_custom(name)) {
strcpy(buf, name);
return &fd_custom;
}
if (find_frozen(name) !=3D NULL) {
strcpy(buf, name);
return &fd_frozen;
.........................................................................=
..........................
and again:
if (path =3D=3D NULL) {
if (is_custom(name)) {
strcpy(buf, name);
return &fd_custom;
}
LOAD_MODULE
static PyObject *
load_module(char *name, FILE *fp, char *buf, int type)
.........................................................................=
..........................
switch (type) {
.............................................
case C_CUSTOM:
if (buf !=3D NULL && buf[0] !=3D '\0')
name =3D buf;
=20
err =3D init_custom(name);
=20
if (err < 0)
return NULL;
if (err =3D=3D 0) {
PyErr_Format(PyExc_ImportError,
"Purported %s module %.200s not found",
type =3D=3D C_BUILTIN ?
"builtin" : type =3D=3D C_CUSTOM ? "custom":"frozen",
name);
return NULL;
}
modules =3D PyImport_GetModuleDict();
m =3D PyDict_GetItemString(modules, name);
if (m =3D=3D NULL) {
PyErr_Format(
PyExc_ImportError,
"%s module %.200s not properly initialized",
type =3D=3D C_BUILTIN ?
"builtin" : type =3D=3D C_CUSTOM ? "custom":"frozen",
name);
return NULL;
}
Py_INCREF(m);
break;
IS_CUSTOM
static int
is_custom(char *name)
{
struct _customtab *p;
if (!PyImport_Customtab)
return 0;
p=3DPyImport_Customtab;
while(p){
if (p->get_name)
if ((*p->get_name)(name))
return 1;
p=3Dp->next;=20
}
return 0;
}
INIT_CUSTOM
static int
init_custom(char *name)
{
struct _customtab *p =3D PyImport_Customtab;
if (_PyImport_FindExtension(name, name) !=3D NULL)
return 1;
while(p) {
if (p->get_name){
if ((*p->get_name)(name)) {
if (p->initfunc =3D=3D NULL) {
PyErr_Format(PyExc_ImportError,
"Cannot re-init internal module %.200s",
name);
return -1;
}
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # builtin\n", name);
(*p->initfunc)(name);
if (PyErr_Occurred())
return -1;
if (_PyImport_FixupExtension(name, name) =3D=3D NULL)
return -1;
return 1;
}
}
p=3Dp->next;
}
return 0;
}
------=_NextPart_000_002D_01C298DF.B68FC6C0
Content-Type: text/html;
charset="windows-1250"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Dwindows-1250">
<META content=3D"MSHTML 6.00.2600.0" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV>I think Python should have a more universal import mechanism , =
which could=20
be done</DIV>
<DIV>by adding a new C_CUSTOM type to the definitions for dynamic =
loading=20
(importdl.h) ,</DIV>
<DIV>a new struct _customtab to import.h and a new function =
to Python API=20
(import.c).</DIV>
<DIV>Then any archive,database,internet import architecture =
could be=20
implemented </DIV>
<DIV>in C extensions without messing with Python core.</DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV>Wiktor Sadowski</DIV>
<DIV><A =
href=3D"http://www.wiktorsadowski.com">www.wiktorsadowski.com</A></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV>IMPLEMENTATION</DIV>
<DIV>(tested on win_98)</DIV>
<DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV>import.h</DIV>
<DIV>extern DL_IMPORT(int) PyImport_AppendCustomtab(int =20
(*get_name)(char*),void (*initfunc)(char*));</DIV>
<DIV> </DIV>
<DIV>struct _customtab {<BR> int =20
(*get_name)(char*);<BR> void=20
(*initfunc)(char*);<BR> struct _customtab *next;<BR>};</DIV></DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>importdl.h</DIV>
<DIV>enum filetype=20
{<BR> SEARCH_ERROR,<BR> PY_SOURCE,<BR> PY_COMPILED,<BR>&nb=
sp;C_EXTENSION,<BR> PY_RESOURCE,=20
/* Mac only=20
*/<BR> PKG_DIRECTORY,<BR> C_BUILTIN,<BR> PY_FROZEN,<BR>&nb=
sp;C_CUSTOM,<BR> PY_CODERESOURCE=20
/* Mac only */<BR>};</DIV>
<DIV> </DIV>
<DIV>import.c</DIV>
<DIV>struct _customtab *PyImport_Customtab;</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>int <BR>PyImport_AppendCustomtab(int (*get_name)(char*),void=20
(*initfunc)(char*))<BR>{<BR> struct _customtab =
*pycustomtab;<BR> =20
struct _customtab *newtab=3DPyMem_NEW(struct _customtab,1);<BR> =20
newtab->get_name=3Dget_name;<BR> =
newtab->initfunc=3Dinitfunc;<BR> =20
newtab->next=3DNULL;</DIV>
<DIV> </DIV>
<DIV> pycustomtab=3DPyImport_Customtab;</DIV>
<DIV> if (pycustomtab)<BR> {<BR> =20
while(pycustomtab->next)<BR> =20
pycustomtab=3Dpycustomtab->next; <BR> =20
pycustomtab->next=3Dnewtab;<BR> }<BR> =20
else<BR> PyImport_Customtab=3Dnewtab;</DIV>
<DIV> return 1; <BR> }</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>static struct filedescr *<BR>find_module(char *realname, PyObject =
*path,=20
char *buf, size_t buflen,<BR> FILE **p_fp)</DIV>
<DIV>....................................................................=
...............................</DIV>
<DIV>static struct filedescr fd_custom =3D {"", "", C_CUSTOM};</DIV>
<DIV>....................................................................=
...............................</DIV>
<DIV>before find_frozen !:</DIV>
<DIV> </DIV>
<DIV>if (is_custom(name)) {<BR> strcpy(buf,=20
name);<BR> return =
&fd_custom;<BR> }</DIV>
<DIV> </DIV>
<DIV> if (find_frozen(name) !=3D NULL)=20
{<BR> strcpy(buf, name);<BR> return=20
&fd_frozen;</DIV>
<DIV>....................................................................=
...............................</DIV>
<DIV>and again:</DIV>
<DIV>if (path =3D=3D NULL) {</DIV>
<DIV> if (is_custom(name)) {<BR> strcpy(buf,=20
name);<BR> return =
&fd_custom;<BR> }</DIV>
<DIV> </DIV>
<DIV>LOAD_MODULE</DIV>
<DIV>static PyObject *<BR>load_module(char *name, FILE *fp, char *buf, =
int=20
type)</DIV>
<DIV>....................................................................=
...............................</DIV>
<DIV>switch (type) {</DIV>
<DIV>.............................................</DIV>
<DIV>case C_CUSTOM:</DIV>
<DIV> </DIV>
<DIV> if (buf !=3D NULL && buf[0] !=3D=20
'\0')<BR> name =3D =
buf;<BR> <BR> err=20
=3D init_custom(name);<BR> <BR> if (err <=20
0)<BR> return NULL;<BR> if (err =3D=3D 0)=20
{<BR> PyErr_Format(PyExc_ImportError,<BR> &nb=
sp; =20
"Purported %s module %.200s not=20
found",<BR> type =3D=3D =
C_BUILTIN=20
?<BR> "builtin" : type =3D=3D =
C_CUSTOM ?=20
"custom":"frozen",<BR> =20
name);<BR> return =
NULL;<BR> }<BR> modules=20
=3D PyImport_GetModuleDict();<BR> m =3D =
PyDict_GetItemString(modules,=20
name);<BR> if (m =3D=3D NULL)=20
{<BR> PyErr_Format(<BR> PyExc_Imp=
ortError,<BR> "%s=20
module %.200s not properly initialized",<BR> type =
=3D=3D=20
C_BUILTIN ?<BR> "builtin" : type =
=3D=3D C_CUSTOM=20
?=20
"custom":"frozen",<BR> name);<BR>  =
;return=20
NULL;<BR> }<BR> Py_INCREF(m);<BR> break;=
</DIV>
<DIV> </DIV>
<DIV>IS_CUSTOM</DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV>static int<BR>is_custom(char *name)<BR>{<BR> struct =
_customtab=20
*p;</DIV>
<DIV> </DIV>
<DIV>if (!PyImport_Customtab)<BR> return 0;</DIV>
<DIV> </DIV>
<DIV>p=3DPyImport_Customtab;</DIV>
<DIV> </DIV>
<DIV>while(p){<BR> if=20
(p->get_name)<BR> if=20
((*p->get_name)(name))<BR> return=20
1;<BR> p=3Dp->next; <BR>}<BR> return =
0;<BR>}</DIV>
<DIV> </DIV>
<DIV>INIT_CUSTOM</DIV>
<DIV>static int<BR>init_custom(char *name)<BR>{<BR> struct =
_customtab *p =3D=20
PyImport_Customtab;</DIV>
<DIV> </DIV>
<DIV> if (_PyImport_FindExtension(name, name) !=3D=20
NULL)<BR> return 1;</DIV>
<DIV> </DIV>
<DIV> while(p) {<BR> if=20
(p->get_name){<BR> if ((*p->get_name)(name))=20
{<BR> if (p->initfunc =3D=3D NULL)=20
{<BR> PyErr_Format(PyExc_ImportError,<BR>&nb=
sp; "Cannot=20
re-init internal module=20
%.200s",<BR> name);<BR> &nb=
sp; return=20
-1;<BR> }<BR> if=20
(Py_VerboseFlag)<BR> PySys_WriteStderr("impo=
rt %s #=20
builtin\n",=20
name);<BR> (*p->initfunc)(name);<BR>  =
; if=20
(PyErr_Occurred())<BR> return=20
-1;<BR> if (_PyImport_FixupExtension(name, name) =
=3D=3D=20
NULL)<BR> return=20
-1;<BR> return=20
1;<BR> }<BR> }<BR> =20
p=3Dp->next;<BR> }<BR> return 0;<BR>}<BR></DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2><FONT face=3DArial =
size=3D2></FONT></FONT> </DIV>
<DIV><FONT face=3DArial size=3D2> </DIV></FONT></BODY></HTML>
------=_NextPart_000_002D_01C298DF.B68FC6C0--