nested scopes

Jeremy Hylton jeremy at alum.mit.edu
Fri Feb 2 17:48:24 EST 2001


In article <msXosJAT0oe6Ewmn at jessikat.fsnet.co.uk>,
  Robin Becker <robin at jessikat.fsnet.co.uk> wrote:
> Is it really true that J Hylton's nested scopes will cause code like
>
> def bingo():
>   from string import *
>   ....
>
> to be declared bad? I'm already against nested scopes, but requiring
> this to be wrong seems awful. We seem to be replacing a simple 2-level
> system by a more complex one & restrictions.

This code will not work in 2.1 alpha 2.  It will raise a SyntaxError
exception.  I expect the restriction to be eased somewhat for 2.1b1, so
that it will be allowed as long as the function doesn't contain other
function definitions.

This is partly the result of the nested scopes change, and partly the
result of some confusion about the reference manual.  I'll explain the
real problem first.

def f():
    from string import strip
    def g(s):
        return strip(s)
    return g

In 2.1a2, the name strip in g() will use the binding for strip in f().
The resolution of names is determined at compile time.  If f() didn't
have a binding for strip, then the use in g() would check in globals
and builtins.  I think this is straightforward.

The 'from ... import *' form is a problem, because the compiler can't
tell what names will be present in a function scope at compile time.

def f():
    from string import *
    def g(s):
        return strip(s)
    return g

The compiler has know way to know whether 'from string import *' will
create a binding for strip in f().  It could ignore the possibility
that a binding would be created at runtime and treat strip as a global,
but that would be a confusing special case.  Instead, the compiler flags
it as an error and forces the programmer to be explicit about the
binding.

While I was working on nested scopes, I noticed that the 2.0 reference
manual says that "from ... import *" is illegal anywhere except at the
module level (and noted that the compiler did not enforce this rule).
Since I was modifying the compiler anyway, I decided to enforce this
rule.  It meant I didn't have to work about the case I just described
above, because any use of 'from ... import *' would be illegal.

No one seems to remember why the reference manual outlawed this form of
import.  (It also outlawed assigning to a name declared global, e.g.
"def f(): global time; import time" and we're not sure about that
either.)  This form seems to be used often enough that we should allow
it when there is no ambiguity.  I plan to fix the compiler for the
next release so that it only complains when 'from ... import *' is used
in the presence of nested scopes.  As Thomas noted in another message,
use of a lambda statement counts as "in the presence of nested scopes."

--
-- Jeremy Hylton, <http://www.python.org/~jeremy/>


Sent via Deja.com
http://www.deja.com/



More information about the Python-list mailing list