import hooks

Patrick Stinson patrickkidd.lists at gmail.com
Wed Apr 16 14:04:36 CEST 2008


I am defining a simple finder/loader object and adding it to sys.meta_path
like this:

PyRun_SimpleString("import sys; import ousiainternal; sys.meta_path =
[ousiainternal.OusiaImporter]");


The following C code defines the loader object:


static void

MyImporter_dealloc(PyObject *self)

{

self->ob_type->tp_free(self);

}



static int

MyImporter_init(MyImporter *self, PyObject *args, PyObject *kwds)

{

  return 0;

}


static PyObject *

MyImporter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)

{

  MyOutput *self;



  self = (MyOutput *)type->tp_alloc(type, 0);



  return (PyObject *)self;

}




/* Check whether we can satisfy the import of the module named by

'fullname'. Return self if we can, None if we can't.


FYI: MyImporter imports modules from the local instrument.

*/

static PyObject *

MyImporter_find_module(PyObject *obj, PyObject *args)

{

MyImporter *self = (MyImporter *)obj;

PyObject *path = NULL;

char *fullname;



if (!PyArg_ParseTuple(args, "s|O",

                        &fullname, &path))

return NULL;



  mod = lookup_module_in_my_app(name); //borrowed ref



  if(mod == NULL);

  {

Py_INCREF(Py_None);

return Py_None;

}



Py_INCREF(self);

return (PyObject *)self;

}



/* Load and return the module named by 'fullname'. */

static PyObject *

MyImporter_load_module(PyObject *obj, PyObject *args)

{

MyImporter *self = (MyImporter *)obj;

PyObject *mod = NULL;

char *fullname;



if (!PyArg_ParseTuple(args, "s", &fullname))

return NULL;




  mod = lookup_module_in_my_app(name); // borrowed ref



  if(mod)

    Py_INCREF(mod);



return mod;

}



static PyMethodDef MyImporter_methods[] = {

{"find_module", MyImporter_find_module, METH_VARARGS,

    "find a module"},

{"load_module", MyImporter_load_module, METH_VARARGS,

    "load a module"},

{NULL, NULL} /* sentinel */

};



static PyTypeObject MyImporterType = {

  PyObject_HEAD_INIT(NULL)

  0,                         /*ob_size*/

  "Myinternal.MyImporter",     /*tp_name*/

  sizeof( MyImporter),             /*tp_basicsize*/

  0,                         /*tp_itemsize*/

  (destructor)  MyImporter_dealloc,    /*tp_dealloc*/

  0,                         /*tp_print*/

  0,                         /*tp_getattr*/

  0,                         /*tp_setattr*/

  0,                         /*tp_compare*/

  0,                         /*tp_repr*/

  0,                         /*tp_as_number*/

  0,                         /*tp_as_sequence*/

  0,                         /*tp_as_mapping*/

  0,                         /*tp_hash */

  0,                         /*tp_call*/

  0,                         /*tp_str*/

  0,                         /*tp_getattro*/

  0,                         /*tp_setattro*/

  0,                         /*tp_as_buffer*/

  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/

  "import hook for loading embedded modules",           /* tp_doc */

  0,               /* tp_traverse */

  0,               /* tp_clear */

  0,               /* tp_richcompare */

  0,               /* tp_weaklistoffset */

  0,               /* tp_iter */

  0,               /* tp_iternext */

  MyImporter_methods,       /* tp_methods */

  0, //MyImporter_members,                   /* tp_members */

  0,                         /* tp_getset */

  0,                         /* tp_base */

  0,                         /* tp_dict */

  0,                         /* tp_descr_get */

  0,                         /* tp_descr_set */

  0,                         /* tp_dictoffset */

  (initproc)  MyImporter_init,      /* tp_init */

  0,                         /* tp_alloc */

  MyImporter_new,                 /* tp_new */

};

A simpler example that yields the same results would be this:

static const char *importer_source =

"import sys\n"

"class Importer:\n"

"    def __init__(self, path):\n"

"        print \'Import.__init__\', path\n"

"    def find_module(self, fullname, path=None):\n"

"        print self\n"

"        if fullname == \'bleh\':\n"

"            return self\n"

"    def load_module(self, fullname):\n"

"        print self\n"

"        if fullname == \'bleh\':\n"

"            return sys\n"

"sys.meta_path.append(Importer)\n";


PyRun_SimpleString(importer_source);



For both examples none of the methods are called (I set breakpoints for the
C functions) but a statement like "import os" or
PyImport_ImportModule("traceback") don't work.


Thanks for your help


On Wed, Apr 16, 2008 at 12:02 AM, Gabriel Genellina <gagsl-py2 at yahoo.com.ar>
wrote:

> En Tue, 15 Apr 2008 22:14:18 -0300, Patrick Stinson
> <patrickkidd.lists at gmail.com> escribió:
>
> > What's the current way to install an import hook? I've got an embedded
> > app
> > that has a few scripts that I want to import each other, but that are
> > not in
> > sys.modules. I intentionally keep them out of sys.modules because their
> > names will not be unique across the app. They will, however, be unique
> > between scripts that I (do* want to see each other).
> > Basically, I want to return a certain module from a name-based filter.
> > I've
> > already written a type in C with find_module and load_module, but it
> > doesn't
> > seem to work when I add the type to sys.path_hooks. I wrote a simple one
> > that worked just fine from a pure script file run through python.exe.
>
>  From that description alone I can't say what's happening; you should post
> some code.
> Also, if your importer isn't disk-based, perhaps using sys.meta_path is
> better.
>
> --
> Gabriel Genellina
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>



-- 
Patrick Kidd Stinson
http://www.patrickkidd.com/
http://pkaudio.sourceforge.net/
http://pksampler.sourceforge.net/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20080416/2c040ac8/attachment.html>


More information about the Python-list mailing list