[Python-checkins] r47270 - peps/trunk/pep-0338.txt

nick.coghlan python-checkins at python.org
Thu Jul 6 14:36:24 CEST 2006


Author: nick.coghlan
Date: Thu Jul  6 14:36:24 2006
New Revision: 47270

Modified:
   peps/trunk/pep-0338.txt
Log:
Updated writeup about import statements to strongly recommend absolute imports from main modules

Modified: peps/trunk/pep-0338.txt
==============================================================================
--- peps/trunk/pep-0338.txt	(original)
+++ peps/trunk/pep-0338.txt	Thu Jul  6 14:36:24 2006
@@ -180,39 +180,67 @@
 and then invokes ``run_module(sys.argv[0], run_name="__main__",
 alter_sys=True)``.
 
-Relative Imports
-================
-
-2.5b1 showed an annoying interaction between this PEP and PEP 328 -
-explicit relative imports don't work from a main module, because
-relative imports rely on ``__name__`` to determine the current module's
-position in the package hierarchy.
-
-Accordingly, the operation of ``run_module()`` was modified so that
-another special variable ``__module_name__`` was defined in the
-namespace of the module being executed. This variable always holds
-the true module name, even if ``__name__`` is set to something else
-(like ``'__main__'``)
-
-Modules that don't rely on relative imports can be used from a
-package as a main module without any changes. In order to both use
-relative imports and also be usable as a main module, a module in a
-package will currently need to use a structure similar to the
-following::
-
-  # Docstring and any future statements
-  _is_main = False
-  if __name__ == "__main__":
-      _is_main = True
-      __name__ = __module_name__
-
-  # Support module section, including relative imports
-
-  if _is_main:
-      # Main module section
+Import Statements and the Main Module
+=====================================
 
-That said, Guido's recommended solution is to avoid using relative
-imports in the first place.
+The release of 2.5b1 showed a surprising  (although obvious in
+retrospect) interaction between this PEP and PEP 328 - explicit
+relative imports don't work from a main module. This is due to
+the fact that relative imports rely on ``__name__`` to determine
+the current module's position in the package hierarchy. In a main
+module, the value of ``__name__`` is always ``'__main__'``, so
+explicit relative imports will always fail (as they only work for
+a module inside a package).
+
+Investigation into why implicit relative imports *appear* to work when
+a main module is executed directly but fail when executed using -m
+showed that such imports are actually always treated as absolute
+imports. Because of the way direct execution works, the package
+containing the executed module is added to sys.path, so its sibling
+modules are actually imported as top level modules. This can easily
+lead to multiple copies of the sibling modules in the application if
+implicit relative imports are used in modules that may be directly
+executed (e.g. test modules or utility scripts).
+
+For the 2.5 release, the recommendation is to always use absolute
+imports in any module that is intended to be used as a main module.
+The -m switch provides a benefit here, as it inserts the current
+directory into sys.path, instead of the directory contain the main
+module. This means that it is possible to run a module from inside a
+package using -m so long as the current directory contains the top
+level directory for the package. Absolute imports will work correctly
+even if the package isn't installed anywhere else on sys.path. If the
+module is executed directly and uses absolute imports to retrieve its
+sibling modules, then the top level package directory needs to be
+installed somewhere on sys.path (since the current directory won't be
+added automatically).
+
+Here's an example file layout::
+
+    devel/
+        pkg/
+            __init__.py
+            moduleA.py
+            moduleB.py
+            test/
+                __init__.py
+                test_A.py
+                test_B.py
+
+So long as the current directory is ``devel``, or ``devel`` is already
+on ``sys.path`` and the test modules use absolute imports (such as
+``import pkg moduleA`` to retrieve the module under test, PEP 338
+allows the tests to be run as::
+
+    python -m pkg.test.test_A
+    python -m pkg.test.test_B
+
+The question of whether or not relative imports should be supported
+when a main module is executed with -m is something that will be
+revisited for Python 2.6. Permitting it would require changes to
+either Python's import semantics or the semantics used to indicate
+when a module is the main module, so it is not a decision to be made
+hastily.
 
 Resolved Issues
 ================


More information about the Python-checkins mailing list