[Python-Dev] Re: [Import-sig] Re: Proposal for a modified import mechanism.

Greg Ward gward@python.net
Wed, 14 Nov 2001 11:02:03 -0500


[Prabhu Ramachandran, claiming "from foo import bar" considered bad]
> Well, the Python howto explains it much better than I could hope to:
> 
>     http://py-howto.sourceforge.net/doanddont/node8.html
> 
> Since re-loading packages is important for me, I prefer using plain
> imports.

Nobody else has responded to this, so I should.  The above page (just a
paragraph, really) claims that "from foo import bar" is bad because it
binds the same object to two different names (or rather, to the same
name in two different namespace).  True enough, but it then claims this
is a Bad Thing because things can go wrong in the face of module
reloading, or (aack!) changes to function definitions at run-time.

Well, let's get one thing straight here: consider the two language
features, "from foo import bar" and "change function definition at
runtime".  These two language features interact in unpleasant ways.
Which language feature should then be considered dangerous, dodgy, to be
avoided in production code, etc?  I don't think there's much controversy
there.

As for module reloading, this is another thing that simply cannot work
in real life.  It's nice that you can do it at the command-line, but
real-life patterns of code and data mean module reloading in non-trivial
applications simply cannot work.  Here's the explanation I posted to
the quixote-users list just yesterday:

    More importantly, it is fundamentally impossible for module
    reloading to work in Python.  Believe me, I've tried several times,
    and each time I run up against the same brick wall: if module b's
    global namespace has an instance of class a.A, what happens when you
    reload module a?  The a.A instance in b still has a bunch of bound
    methods that point to the old code in the old version of a.  You
    lose.  So you reload b and a at the same time: the a.A instance in
    b's global namespace has to be recreated (ie. b re-imported) *after*
    a is re-imported.  What if there's a cyclic dependency, ie. a's
    namespace has a b.B instance and b's has an a.A method?  (Yes, you'd
    be nuts to set things up this way, but it's possible.)  And what
    about other namespaces (eg. instances floating in memory, closures,
    ...) that have a reference to b's a.A instance?  OK, you have to
    scrub all those namespaces too.  It boils down to doing
    sys.modules.clear(), which has its own problems.

If anyone has a solution to this, I'm all ears, but for now I'm pretty
well convinced that it cannot be done.

In case it's not obvious, I think that Python how-to document needs
revision in this regard.  Moshe?

        Greg
-- 
Greg Ward - programmer-at-large                         gward@python.net
http://starship.python.net/~gward/
Do radioactive cats have 18 half-lives?