[Python-Dev] Peculiar import code in pickle.py

Brett Cannon brett at python.org
Tue Jul 13 22:52:29 CEST 2010


On Tue, Jul 13, 2010 at 11:34, Alexander Belopolsky <
alexander.belopolsky at gmail.com> wrote:

> On Tue, Jul 13, 2010 at 1:57 PM, Benjamin Peterson <benjamin at python.org>
> wrote:
> ..
> > No! That's not recommended and a complete hack. The "dance" or
> > importlib.import_module is preferred.
>
> Nevertheless, "a complete hack" is what PyImport_Import does:
>
> PyObject *
> PyImport_Import(PyObject *module_name)
> {
>    static PyObject *silly_list = NULL;
>    ..
>    /* Call the __import__ function with the proper argument list
>     * Always use absolute import here. */
>    r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
>                              globals, silly_list, 0, NULL);
>    ..
> }
>
> and _pickle.c uses  PyImport_Import() and thus is different form
> pickle.py which uses the double-lookup dance.  As a result, the two
> implementations are subtly different.  They cannot be both right.  It
> should be easy to "fix" _pickle.c to do the sys.modules lookup, but I
> am not sure this is right.


Pulling from sys.modules is the correct way to do this. There are subtle
issues when using a bunk fromlist argument (empty modules, double
initialization, etc.). If one does not use importlib.import_module --
written *specifically* to prevent people from doing the nasty hack with the
fromlist -- then you should use the sys.modules approach, period. If
import.c is not doing this then it should get fixed. You can assign me the
issue if you want.

I say this every time I give an import talk and it has been brought up here
before but obviously not everyone catches it (which is understandable as I
think when it came up on python-dev it was at the tail end of a discussion),
so I am just going to repeat myself:

  Do not put junk in fromlist if you call __import__ directly! Use
importlib.import_module! Or if you have a *really* good reason to not use
it, then use ``__import__(name); module = sys.modules[name]``.

I have stopped fixing bugs related to this in import.c because of the
annoying issues it causes and I expect the correct approach to gain traction
at some point (plus get importlib bootstrapped in so I don't have to care
about import.c anymore).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20100713/f1558bac/attachment-0001.html>


More information about the Python-Dev mailing list