[Python-Dev] __import__ problems

Nick Coghlan ncoghlan at gmail.com
Thu Nov 27 22:22:42 CET 2008


Mart Somermaa wrote:
>>>> __import__('foo.bar', globals(), locals(), ['baz'], -1)
> <module 'foo.bar' from 'foo/bar/__init__.py'>
> 
> i.e. 'bar' is imported, not 'baz' (or 'ham' and not 'eggs').

You're reading it wrong. 'baz' *is* imported, but 'bar' is returned from
the function call. You will find that the import statement generates
some additional opcodes to then do the assignment statements off the VM
stack.

This is stated explicitly in the documentation of __import__:

"""Note that even though locals() and ['eggs'] are passed in as
arguments, the __import__() function does not set the local variable
named eggs; this is done by subsequent code that is generated for the
import statement."""

And as described later:

"""when using from spam.ham import eggs, the spam.ham subpackage must be
used to find the eggs variable."""

i.e.

"from foo.bar import baz" ---->

<stack top> = __import__('foo.bar', globals(), locals(), ['baz'], -1)
baz = <stack top>.baz

When there are multiple names being imported or an 'as' clause is
involved, I hope the reasons for doing it this way become more obvious:

"from foo.bar import baz, bob" ---->

<stack top> = __import__('foo.bar', globals(), locals(), ['baz', 'bob'], -1)
baz = <stack top>.baz
bob = <stack top>.bob

"from foo.bar import baz as bob" ---->

<stack top> = __import__('foo.bar', globals(), locals(), ['baz', 'bob'], -1)
bob = <stack top>.baz

There's a perfectly correct approach documented as part of the
__import__ docs that you referenced in your original email. If
developers decide not to use that approach and use an undocumented hack
instead, they have no right to complain when their code doesn't work
properly.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------


More information about the Python-Dev mailing list