The issue is that the actual names inserted into the scope can only be determined at runtime. I would propose that this only be enabled at the module-level scope to avoid costly lookups and other major complications. Python now makes this assertion too for similar reasons. (See the bottom of http://docs.python.org/ref/import.html.)
One would not be able to override a builtin function with something of the same name from *. Also, this would disable the compile-time name-error warnings.
Explicit imports of course can be done anywhere.
DagSverreSeljebotn: Would it be expensive to insert code at module startup to basically try to resolve all builtin functions used towards *-imports, and if they succeed then fail hard?
- robertwb: No, I don't think this would be overly expensive. I think printing out a warning would be enough.
DagSverreSeljebotn: Actually, a check compile-time can help us here. Look:
- If the symbol is resolved (by having the compiler import the module and search for it through its Python instance), then it is a "dangerous" symbol and is flagged for runtime lookup which will always work (from numpy import * ... will at least work this way). If not, use the approach above by compiling directly but check and warn at module loading.
- There is still a problem, but only in a specific case: That the module imported contains a new symbol in the runtime system compared with the compilation system. In this case, using the "new" symbol is probably not what was intended, so outputting a simple warning ("Using import * but library symbols differ") would do.
(Basically, a way of looking at this is that"from blah import *" is "resolved" compile-time; ie "from numpy import *" is resolved into "from numpy import min, max, round, pi" while compiling based on compile-time knowledge of the library. In fact, if we specify that this is what happens it leaves the way open for compile-time resolving the symbols completely even when star-imported. This is not very clean, but is is a very practical solution which should cover 90% of the cases; and one can always not use *-import if one is compiling in a sandbox or whatever. + big fat warnings if we detect that run-time behaviour would have been different (ie a module *-imported after numpy suddenly also defines pi)).