Since their introduction in Python 2.5 I only reviewed the new "relative import" notation briefly by reading the "What's new in Python 2.5" article. Now I wanted checkout if I get comfortable with them.
Opening the tutorial I found following notice ( 6.4.2 ): "Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application should always use absolute imports." The distinction between modules and scripts was new to me. One of the primary features I always appreciated in Python was that modules had a dual purpose: they were components and they were programs. One could use them in isolation or as a part of a package something I always missed when I programmed in languages with the tyranny of a single main. However 'implicit relative imports' work as usual and Py3K just changes the priority of search - one might simply ignore the 'explicit' variant and care for unambiguous names. Now things are not so easy in life and when you are confronted with other peoples software you have to know at least the rules of the game. Digging a little deeper I found the following section in "What's new in Python 2.6" 'Python’s -m switch allows running a module as a script. When you ran a module that was located inside a package, relative imports didn’t work correctly.' Hmm... they worked as specified or at least as documented. I admit I'm confused but I suspect I'm not the only one. Now everything is fine. You just run each and every module with the -m option "as a script" because there is a chance that somewhere is a relative import ( e.g. local to a function ) and suddenly the module fails to import stuff due to a modality in the import behavior. Let's see how it works in practice. This here my very first attempt to start Pythons 2to3 refactoring tool written by the master himself. I looked at it and he used relative imports. C:\Python30\Lib\lib2to3>C:\Python30\python -m refactor.py Traceback (most recent call last): File "C:\Python30\lib\runpy.py", line 103, in _run_module_as_main loader, code, fname = _get_module_details(mod_name) File "C:\Python30\lib\runpy.py", line 78, in _get_module_details loader = get_loader(mod_name) File "C:\Python30\lib\pkgutil.py", line 456, in get_loader return find_loader(fullname) File "C:\Python30\lib\pkgutil.py", line 466, in find_loader for importer in iter_importers(fullname): File "C:\Python30\lib\pkgutil.py", line 422, in iter_importers __import__(pkg) File "C:\Python30\lib\lib2to3\refactor.py", line 23, in <module> from .pgen2 import driver ValueError: Attempted relative import in non-package Not working. I'm perfectly sure I don't understand the error message but what's worse is that runpy.py fails which was just created ( in Python 2.6 ) to fix the issue with the apparently broken relative imports that is o.k. according to the introductory material that is dedicated to newbies. I'm trying to fix this naively by turning the explicit into implicit relative (or absolute?) imports and see what happens. refactor.py ------------------------ ... # Local imports from pgen2 import driver from pgen2 import tokenize import pytree import patcomp import fixes import pygram .... C:\Python30\Lib\lib2to3>C:\Python30\python -m refactor.py Traceback (most recent call last): File "C:\Python30\lib\runpy.py", line 103, in _run_module_as_main loader, code, fname = _get_module_details(mod_name) File "C:\Python30\lib\runpy.py", line 78, in _get_module_details loader = get_loader(mod_name) File "C:\Python30\lib\pkgutil.py", line 456, in get_loader return find_loader(fullname) File "C:\Python30\lib\pkgutil.py", line 466, in find_loader for importer in iter_importers(fullname): File "C:\Python30\lib\pkgutil.py", line 422, in iter_importers __import__(pkg) File "refactor.py", line 27, in <module> import patcomp File "C:\Python30\lib\lib2to3\patcomp.py", line 17, in <module> from .pgen2 import driver ValueError: Attempted relative import in non-package This time patcomp fails with its relative imports despite the fact that it is not imported as a "script" but as a module inside the lib2to3 package and it is not __main__ but refactor.py is. I give up. I always thought migration from Python 2.X to Python 3.0 was an issue not the conversion tool ;) -- http://mail.python.org/mailman/listinfo/python-list