[New-bugs-announce] [issue2210] Nested module import clutters package namespace

Rüdiger Kupper report at bugs.python.org
Fri Feb 29 13:03:59 CET 2008


New submission from Rüdiger Kupper:

When one module of a package imports another module of the same package,
the second module will not only be introduced in the namespace of the
importing module, but also in the namespace of the enclosing package.
I.e., the module will be introduced as variable
<packagename>.<secondmodulename>. If the package namespace contained a
variable of this name before the import, it will be overwritten by the
new value.

For the user, import statements should act like assignments to the local
 namespace. They should never add names to an enclosing namespace. (At
least this is what all documentation and tutorials tell the user.)

Below follows a detailed example for the problem.


Say I have a package named 'pack'. Apart from the '__init__.py' file the 
directory contains two modules 'x.py' and 'y.py':

pack/
      __init__.py
      x.py
      y.py

The files have the following contents:

==== __init__.py ====
import x
=====================

==== x.py ===========
import y
=====================

==== y.py ===========
pass
=====================

I then do
 >>> import pack

This
(1) introduces variable 'x' bound to <module 'pack.x'>
     in pack's namespace (expected)
(2) introduces variable 'q' bound to <module 'pack.y'>
     in x's namespace (expected)
but also
(3) introduces variable 'y' bound to <module 'pack.y'>
     in pack's namespace (*totally unexpected*)

The problem is so bad as to even overwrite any variable 'y' that 
might have existed in pack's namespace before the import.

I created verbose versions of the three files above to illustrate 
what happens (see below.) They do exactly the same as above, but 
print out what they do. This is the output:

---------snip-----------
 >>> import pack
pack: Here is pack.
pack: I now assign y='hello'.
pack: My y is now: 'hello'
pack: I now 'import x' which in turn does 'import y as q'.
   x: Here is x.
   x: I now 'import y as q'.
     y: Here is y.
pack: My y is now: <module 'pack.y' from 'pack/y.pyc'>
pack: Why?
--------snip-------------

I know that any import creates an entry in sys.modules. So 'pack', 
'pack.x' and 'pack.y' get created in sys.modules. That's fine.

Apart from that, an import statement should act equivalent to an 
assignment: it should introduce entries to the local namespace of the
module it appears in. The 'import y as q' appears in x.py, so it 
should add entries to x's namespace *only*.

But why is variable 'y' in pack's namespace overwritten by the 
import in x?


P.S.: These are the files that produce the verbose output. They can be
found in the tgz file attached to this issue.

==== __init__.py ====
print "pack: Here is pack."
print "pack: I now assign y='hello'."
y="hello"
print "pack: My y is now:", repr(y)
print "pack: I now 'import x' which in turn does 'import y as q'."
import x
print "pack: My y is now:", repr(y)
print "pack: Why?"
=====================

==== x.py ===========
print '  x: Here is x.'
print "  x: I now 'import y as q'."
import y as q
=====================

==== y.py ===========
print '    y: Here is y.'
=====================

----------
files: pack.tgz
messages: 63135
nosy: ruediger.kupper
severity: normal
status: open
title: Nested module import clutters package namespace
type: behavior
versions: Python 2.4
Added file: http://bugs.python.org/file9574/pack.tgz

__________________________________
Tracker <report at bugs.python.org>
<http://bugs.python.org/issue2210>
__________________________________


More information about the New-bugs-announce mailing list