issue on internal import in a package

  • Thread starter 人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶
  • Start date
Ä

人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶

Here is a simple example:
[app]
[module]
__init__.py --> empty
a.py --> import b
b.py --> defined a function foo()
test.py

In the test.py, contains the below statement:
from module import a
Execute the test.py will get error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "module\a.py", line 1, in <module>
import b
ImportError: No module named b

Why the b.py can not be found by a.py?
 
Ä

人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶

Here is a simple example:
[app]
      [module]
            __init__.py   --> empty
            a.py   --> import b
            b.py  --> defined a function foo()
      test.py

In the test.py, contains the below statement:
from module import a
Execute the test.py will get error:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "module\a.py", line 1, in <module>
    import b
ImportError: No module named b

Why the b.py can not be found by a.py?

PS. This issue occurred on Python3.2
It's okay in the Python2.6 & Python2.5
 
Ä

人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶

人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶ said:
Here is a simple example:
[app]
      [module]
            __init__.py   --> empty
            a.py   --> import b
            b.py  --> defined a function foo()
      test.py
In the test.py, contains the below statement:
from module import a
Execute the test.py will get error:

This works fine for me::

    $ mkdir --parents app/module/
    $ touch app/module/__init__.py
    $ printf "import b\n" > app/module/a.py
    $ printf "def foo(): pass\n" > app/module/b.py
    $ printf "from module import a\n" > app/test.py
    $ find .
    .
    ./app
    ./app/module
    ./app/module/__init__.py
    ./app/module/a.py
    ./app/module/b.py
    ./app/test.py

    $ python app/test.py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "module\a.py", line 1, in <module>
    import b
ImportError: No module named b
Why the b.py can not be found by a.py?

I get no errors; the code appears to run fine. Perhaps the scenario is
not exactly as you describe?

--
 \       “If we listen only to those who are like us, we will squander |
  `\   the great opportunity before us: To live together peacefully in |
_o__)            a world of unresolved differences.†—David Weinberger |
Ben Finney

Thanks for your reply.
What's the version of your Python? My version is 3.2.
Python 2.5/2.6 doesn't have this issue.
 
F

Frank Millman

Ben Finney said:
人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶ said:
Here is a simple example:
[app]
[module]
__init__.py --> empty
a.py --> import b
b.py --> defined a function foo()
test.py

In the test.py, contains the below statement:
from module import a
Execute the test.py will get error:

This works fine for me::

$ mkdir --parents app/module/
$ touch app/module/__init__.py
$ printf "import b\n" > app/module/a.py
$ printf "def foo(): pass\n" > app/module/b.py
$ printf "from module import a\n" > app/test.py
$ find .
.
./app
./app/module
./app/module/__init__.py
./app/module/a.py
./app/module/b.py
./app/test.py

$ python app/test.py
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "module\a.py", line 1, in <module>
import b
ImportError: No module named b

Why the b.py can not be found by a.py?

I get no errors; the code appears to run fine. Perhaps the scenario is
not exactly as you describe?

I get exactly the same result as the OP, using python 3.2 on both windows
and linux. It works using python 2.6.

I can fix it by changing a.py from 'import b' to 'from . import b'.

As I understand it, the reason is that python 3.x will no longer look for an
absolute import in the current package - it will only look in sys.path.

Frank Millman
 
Ä

人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶

Here is a simple example:
[app]
      [module]
            __init__.py   --> empty
            a.py   --> import b
            b.py  --> defined a function foo()
      test.py
In the test.py, contains the below statement:
from module import a
Execute the test.py will get error:
This works fine for me::
   $ mkdir --parents app/module/
   $ touch app/module/__init__.py
   $ printf "import b\n" > app/module/a.py
   $ printf "def foo(): pass\n" > app/module/b.py
   $ printf "from module import a\n" > app/test.py
   $ find .
   .
   ./app
   ./app/module
   ./app/module/__init__.py
   ./app/module/a.py
   ./app/module/b.py
   ./app/test.py
   $ python app/test.py
I get no errors; the code appears to run fine. Perhaps the scenario is
not exactly as you describe?

I get exactly the same result as the OP, using python 3.2 on both windows
and linux. It works using python 2.6.

I can fix it by changing a.py from 'import b' to 'from . import b'.

As I understand it, the reason is that python 3.x will no longer look foran
absolute import in the current package - it will only look in sys.path.

Frank Millman

This behavior is by design or just a bug for Python3.x ?
 
F

Frank Millman

人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶ said:
This behavior is by design or just a bug for Python3.x ?

Definitely by design.

Have a look at PEP 328 - http://www.python.org/dev/peps/pep-0328/

"In Python 2.4 and earlier, if you're reading a module located inside a
package, it is not clear whether
import foo
refers to a top-level module or to another module inside the package. As
Python's library expands, more and more existing package internal modules
suddenly shadow standard library modules by accident. It's a particularly
difficult problem inside packages because there's no way to specify which
module is meant. To resolve the ambiguity, it is proposed that foo will
always be a module or package reachable from sys.path. This is called an
absolute import."

HTH

Frank
 
Ä

人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶

Definitely by design.

Have a look at PEP 328 -http://www.python.org/dev/peps/pep-0328/

"In Python 2.4 and earlier, if you're reading a module located inside a
package, it is not clear whether
import foo
refers to a top-level module or to another module inside the package. As
Python's library expands, more and more existing package internal modules
suddenly shadow standard library modules by accident. It's a particularly
difficult problem inside packages because there's no way to specify which
module is meant. To resolve the ambiguity, it is proposed that foo will
always be a module or package reachable from sys.path. This is called an
absolute import."

HTH

Frank

Yes, it's okay with the change in a.py with below line:
from . import b

But another issue occurred if I want to run the a.py separately.
$ cd module
$ python a.py
Traceback (most recent call last):
File "a.py", line 1, in <module>
from . import b
ValueError: Attempted relative import in non-package

Does that mean the relative import only allowed in the package.
And it cannot be run as __main__ program unless I change the relative
import back to absolute import?
I think this behavior is strange and difficult to use.


Doesn't
 
F

Frank Millman

人言è½æ—¥æ˜¯å¤©æ¶¯ï¼Œæœ›æžå¤©æ¶¯ä¸è§å®¶ said:
Yes, it's okay with the change in a.py with below line:
from . import b

But another issue occurred if I want to run the a.py separately.
$ cd module
$ python a.py
Traceback (most recent call last):
File "a.py", line 1, in <module>
from . import b
ValueError: Attempted relative import in non-package

Does that mean the relative import only allowed in the package.
And it cannot be run as __main__ program unless I change the relative
import back to absolute import?
I think this behavior is strange and difficult to use.

I think that PEP 366 addresses your question -

http://www.python.org/dev/peps/pep-0366/

I came across this while investigating a separate problem. It looks a bit
complicated, and I don't have such a requirement, so I did not look at it
too closely.

Have a read and see if it solves your problem. If not post a follow-up
message here and see if someone else can offer more information.

Frank
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top