[Python-Dev] serious bug in new import X as Y code

Thomas Wouters thomas@xs4all.net
Sun, 20 Aug 2000 15:51:17 +0200


On Sun, Aug 20, 2000 at 01:26:05PM +0200, Sjoerd Mullender wrote:

> Here's another pretty serious bug.  Can you verify that this time it
> isn't my configurations?

It isn't your config, this is a genuine bug. I'll be checking in a quick fix
in a few minutes, and start thinking about a test case that would've caught
this.

> Try this:
> from encodings import cp1006, cp1026

> I get the error
> ImportError: cannot import name cp1026
> but if I try to import the two modules separately I get no error.

Yes. 'find_from_args' wasn't trying hard enough to find out what the
argument to an import were. Previously, all it had to do was scan the
bytecodes immediately following an 'IMPORT_NAME' for IMPORT_FROM statements,
and record its names. However, now that IMPORT_FROM generates a STORE, it
stops looking after the first IMPORT_FROM. This worked fine for normal
object-retrieval imports, which don't use the list generated by
find_from_args, but not for dynamic loading tricks such as 'encodings' uses.

The fix I made was to unconditionally jump over 5 bytes, after an
IMPORT_FROM, rather than 2 (2 for the oparg, 1 for the next instruction (a
STORE) and two more for the oparg for the STORE)

This does present a problem for the proposed change in semantics for the
'as' clause, though. If we allow all expressions that yield valid l-values
in import-as and from-import-as, we can't easily find out what the import
arguments are by examining the future bytecode stream. (It might be
possible, if we changed the POP_TOP to, say, END_IMPORT, that pops the
module from the stack and can be used to end the search for import
arguments.

However, I find this hackery a bit appalling :) Why are we constructing a
list of import arguments at runtime, from compile-time information, if all
that information is available at compile time too ? And more easily so ?
What would break if I made IMPORT_NAME retrieve the from-arguments from a
list, which is built on the stack by com_import_stmt ? Or is there a more
convenient way of passing a variable list of strings to a bytecode ? It
won't really affect performance, since find_from_args is called for all
imports anyway.

-- 
Thomas Wouters <thomas@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!