Eric Snow added the comment: Things are working as they should here. The key points:
* when running a script, sys.path[0] is set to the script's directory (with no script sys.path[0] is set to the CWD, see issue13475), * pkg/tests/__init__.py is loaded and executed twice: once as the script under the __main__ module and once during import as pkg.tests, * Python does not handle circular imports very well, * bad things happen when a "top-level" module has the same name as a module in the stdlib. Together those explain what's going on. The import you did at the REPL happened with '' at sys.path[0], so modules are found at the right relative places: pkg, pkg.http, pkg.tests, and pkg.tests.http. There is no script involved, just imports, so no double-loading happens. Things go south when you run "PYTHONPATH=. python3 pkg/tests/__init__.py". First of all, pkg/tests/__init__.py is executed twice: once as the script and once under import. Though you set PYTHONPATH, sys.path[0] is set to "pkg/tests", the directory the script is in. sys.path[1] is ".", what you were expecting to be at sys.path[0]. So when finding modules, the import system will first look in "pkg/tests" then in ".". Thus the pkg.* imports work as expected. However, "from http.client import HTTPConnection" in pkg/tests/http.py finds the same http.py (this time as the "http" module instead of "pkg.tests.http") in pkg/tests rather than the stdlib module as you expected. So it tries to import it a second time with a different module name. Since pkg/tests/http.py is already being loaded due to pkg/test/__init__.py, you get a circular import. Even if you did not get the circular import you would have gotten an ImportError for "http.client" since pkg/tests/http.py neither behaves li ke a package nor actually has any "client" submodule. Part of the fix is to use relative imports where appropriate. For instance, change pkg/tests/__init__.py like this: from . import http Also, don't run pkg/tests/__init__.py directly. Instead try this: PYTHONPATH=. python3 -m pkg.tests However, this implies that you wanted to run the package as a script, so you should have pkg/tests/__main__.py which would import pkg.tests. Alternately, you could have a dedicated script elsewhere, perhaps next to the pkg directory that does the same thing. Here's what I mean: some_project/ pkg/ tests/ __init__.py __main__.py (option 1) http.py __init__.py run_unittests.py (option 2) Finally, don't name your modules with the same names as those in the stdlib. <wink> ---------- nosy: +eric.snow _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue16570> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com