confusion about package/module imports

Discussion in 'Python' started by Jugdish, Jan 1, 2008.

  1. Jugdish

    Jugdish Guest

    Why doesn't the following work?

    >>> ls $HOME

    $HOME/pkg/__init__.py
    $HOME/pkg/subpkg/__init__.py
    $HOME/pkg/subpkg/a.py
    $HOME/pkg/subpkg/b.py

    >>> cat $HOME/pkg/__init__.py

    # empty

    >>> cat $HOME/pkg/subpkg/__init__.py

    import a
    import b

    >>> cat $HOME/pkg/subpkg/a.py

    class A:
    pass

    >>> cat $HOME/pkg/subpkg/b.py

    import pkg.subpkg.a
    class B(pkg.subpkg.a.A):
    pass

    >>> setenv PYTHONPATH $HOME:$PYTHONPATH
    >>> python $HOME/pkg/subpkg/b.py

    Traceback (most recent call last):
    File "pkg/subpkg/b.py", line 1, in ?
    import pkg.subpkg.a
    File "$HOME/pkg/subpkg/__init__.py", line 2, in ?
    import b
    File "$HOME/pkg/subpkg/b.py", line 2, in ?
    class B(pkg.subpkg.a.A):
    AttributeError: 'module' object has no attribute 'subpkg'
    Jugdish, Jan 1, 2008
    #1
    1. Advertising

  2. Jugdish wrote:
    > Why doesn't the following work?
    > ...

    [well boiled-down code skipped]
    >>>> setenv PYTHONPATH $HOME:$PYTHONPATH
    >>>> python $HOME/pkg/subpkg/b.py

    > Traceback (most recent call last):
    > File "pkg/subpkg/b.py", line 1, in ?
    > import pkg.subpkg.a
    > File "$HOME/pkg/subpkg/__init__.py", line 2, in ?
    > import b
    > File "$HOME/pkg/subpkg/b.py", line 2, in ?
    > class B(pkg.subpkg.a.A):
    > AttributeError: 'module' object has no attribute 'subpkg'


    OK, here's a trick for finding import problems:
    python -v <file to fiddle>
    (shows all imports)

    And for this case:
    sprinkle prints to find out what is happening.

    so, add "print __name, __file__" to the top of each file where
    you wonder what is going on.
    I later added prints in pkg/subpkg/__init__.py to make the steps clear.

    You'll see that b is executed (making module __main__),
    it imports pkg.subpkg.a,
    which is accomplished by importing pkg (successfully),
    then by importing pkg.subpkg
    which imports pkg.subpkg.a (successfully)
    and then imports pkg.subpkg.b
    which then attempts to import pkg.subpkg.a
    At that point, only the module pkg
    and what should eventually become pkg.subpkg.a
    have been successfully imported. pkg.subpkg had not yet been imported.
    If you remove the "import b" from subpkg's __init__, you will find
    your problems going away.
    Alternatively, you can remove the import a / import b from subpkg
    and add import subpkg.a, subpkg.b to pkg's __init__. Essentially,
    you need pkg.subpkg fully imported before you import pkg.subpkg.b

    Of course, in most of these cases you will have imported the code
    for b twice, once as a main program, and once as a module in the
    hierarchy, which is probably your actual problem (and why I use
    "print __name__, __file__").


    --Scott David Daniels
    Scott David Daniels, Jan 1, 2008
    #2
    1. Advertising

  3. Jugdish

    Jugdish Guest

    Thanks very much for your helpful response!

    > You'll see that b is executed (making module __main__),
    > (1) it imports pkg.subpkg.a,
    > (2) which is accomplished by importing pkg (successfully),
    > (3) then by importing pkg.subpkg
    > (4) which imports pkg.subpkg.a (successfully)
    > (5) and then imports pkg.subpkg.b
    > (6) which then attempts to import pkg.subpkg.a


    What I'm not really understanding here is why this fails at lines (5)
    and (6). If pkg.subpkg.a has already been successfully imported at
    line (4), then (6) should be detected as a duplicate import and just
    be skipped, right? So the import at line (5) should succeed.
    Jugdish, Jan 1, 2008
    #3
  4. Jugdish wrote:
    > Thanks very much for your helpful response!
    >
    >> You'll see that b is executed (making module __main__),
    >> (1) it imports pkg.subpkg.a,
    >> (2) which is accomplished by importing pkg (successfully),
    >> (3) then by importing pkg.subpkg
    >> (4) which imports pkg.subpkg.a (successfully)
    >> (5) and then imports pkg.subpkg.b
    >> (6) which then attempts to import pkg.subpkg.a

    >
    > What I'm not really understanding here is why this fails at lines (5)
    > and (6). If pkg.subpkg.a has already been successfully imported at
    > line (4), then (6) should be detected as a duplicate import and just
    > be skipped, right? So the import at line (5) should succeed.


    I'm sorry, I used shorthand. While a module is being imported,
    it only provisionally has a name. Until subpkg is fully imported,
    there is no module named pkg.subpkg. At the root level (pkg, for
    example), the module is provisionally added. Further down the tree,
    the module (such as that for pkg/subpkg/__init__.py) is only added
    to the symbol table (the packages __dict__) when the module has been
    completely imported.

    -Scott
    Scott David Daniels, Jan 1, 2008
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Pratt
    Replies:
    4
    Views:
    320
    David Pratt
    May 13, 2006
  2. Albert
    Replies:
    4
    Views:
    10,818
    Albert
    Jul 10, 2008
  3. Peng Yu
    Replies:
    30
    Views:
    665
    Steven D'Aprano
    Nov 1, 2009
  4. zildjohn01
    Replies:
    0
    Views:
    626
    zildjohn01
    Feb 22, 2011
  5. Victor Hooi
    Replies:
    1
    Views:
    96
    Devin Jeanpierre
    Nov 25, 2013
Loading...

Share This Page