[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Nested module import clutters package namespace?

Dr. Rüdiger Kupper

2/28/2008 1:00:00 PM

Hi!

I'd be grateful for help with a problem of package and module
namespaces. The behaviour I observe is unexpected (to me), and I
couldn't find the answer in the docs, the tutorial, or the mailing
list archive. So here we go:

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.) The 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 th
emodule 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?

Thank you very much in advance,
Best, Rüdiger


P.S.: These are the files that produce the verbose output:

==== __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.'
=====================

--
Dr. Rüdiger Kupper
Honda Research Institute Europe GmbH
Carl-Legien-Straße 30
D-63073 Offenbach/Main, Germany

Phone : +049 (0)69-890 11-725
Fax : +049 (0)69-890 11-749
E-Mail: ruediger.kupper@honda-ri.de
PGP ID: C2303358

1 Answer

Matthew Woodcraft

2/29/2008 5:54:00 PM

0

<ruediger.kupper@honda-ri.de> wrote:
> I'd be grateful for help with a problem of package and module=20
> namespaces. The behaviour I observe is unexpected (to me), and I=20
> couldn't find the answer in the docs, the tutorial, or the mailing=20
> list archive. So here we go:

> I have a package named 'pack'. Apart from the '__init__.py' file the=20
> 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*)


That's right, Python has behaved like this since packages were introduced.

There's no doubt that this is intentional, but the state of the
documentation is rather embarrassing. The reference manual's
explanation of package imports consists largely of this reference:

<<XXX Can't be bothered to spell this out right now; see the URL
http://www.python.org/doc/essays/pac... for more details,>>

The referenced essay is over 10 years old and unsurprisingly somewhat
out of date.

This behaviour gets even more exciting when circular imports are
involved. See for example message
slrnbm2ajt.np4.stain@ozelot.stud.ntnu.no on this list.

-M-