Python 2 namespace change? (was Re: [Python-Dev] Changing existing class instances)

Jim Fulton jim@digicool.com
Fri, 04 Feb 2000 12:22:20 -0500


Guido van Rossum wrote:
> 
> [me]
> > > But I don't think that changing the "from M import v" semantics so
> > > that local assignment to v changes the binding of M.v as well is
> > > defensible.
> >
> > I agree, however, I think that having:
> >
> >   from M import v
> >
> > causing a name binding that is broken by local
> > assigment to v *is* defensible and reasonably
> > implementable.
> >
> > Changes to 'v' in M (including by reload of M) would be
> > reflected locally unless someone did:
> >
> >   v=something
> >
> > locally. Local assignment would negate an import, as it
> > does now.
> 
> Hm, but it still wouldn't have the same semantics as currently,

Agreed. Think Python 3000.

I think that the semantics differ in boundary cases though.

> and that's still a monster hiding under the bed until you're nearly
> asleep.  Consider this example:
> 
> # in M:
> verbose = 1
> 
> # in __main__:
> from M import verbose
> 
> # somewhere else:
> M.verbose = 0
> 
> Under the current semantics, that would have no effect on verbose in
> __main__; but with your semantics it would. 

Yup.

> I think that is very hard
> to explain; even more so if you say that assigning a different value
> to __main__.verbose does not change M.verbose and furthermore breaks
> the connection.  This means that if I add
> 
> verbose = verbose
> 
> to the __main__ code the semantics are different!

I'm suggesting a model where from "M import x" has a different
meaning than it does now.  I think the notion of sharing a name
is useful. I'll admit that using "M.x" achieves the same thing, 
although at a higher performance cost (and, OK, typing cost ;).

> I don't understand why you wanted these semantics in the first place.

First, let me say that this isn't super important to me.
It does solve a problem with reload, which is the context in which
I brought it up.

Now, consider:

  from M import x

  .....

  use(x)

Many people would (wrongly) consider this to be 
equivalent to:

  import M

  .....


  use(M.x)

In fact, I'd *prefer* these to be equivalent
even in the face of changes to M (e.g. reload).
I'd prefer different semantics.

Note that if I had:

  from M import x

  .....

  x=y

  .....

  use(x)

I'd no longer exprect x to have any connection to M.

Of course:

  x=x 

or 

  x=M.x

would be a bit more puzzling, but then they're meant
to be. ;) They are addressed by a simple rule, which is
that assignment in a module overrides imported name
definition.

Hm...ooh ooh

A better solution would be to disallow assignments
to imported names, as they are very likely to be errors.
This could be detected without any fancy type inferencing.
In fact, we could also decide to disallow an import-from
to override an existing name binding. Ahhhhhh. :)

In any case, I'd feel comfortable explaining a system in which

  from M import x # reference semantics wrt name

had a different meaning from:

  import M
  x=M.x # copy semantics

since I expect an attribute access to give me
a value, not a name, whereas:

  from M import x 

seems more to me like it's talking about names.

Jim
  







--
Jim Fulton           mailto:jim@digicool.com   Python Powered!        
Technical Director   (888) 344-4332            http://www.python.org  
Digital Creations    http://www.digicool.com   http://www.zope.org    

Under US Code Title 47, Sec.227(b)(1)(C), Sec.227(a)(2)(B) This email
address may not be added to any commercial mail list with out my
permission.  Violation of my privacy with advertising or SPAM will
result in a suit for a MINIMUM of $500 damages/incident, $1500 for
repeats.