[Python-ideas] Import and '..', '../..' in serach path.

Ron Adam rrr at ronadam.com
Tue Jan 30 12:35:34 CET 2007


In order to resolve a path conflict where I'm working on several copies of the 
same package.  I found it useful to add the following near the top of modules in 
a package or sub package.


Module in package:

     import sys
     sys.path = ['..'] + sys.path

     import package.module          # Imports module in "this!" package.


Note: There could still be conflicts if a module with the same name is in the 
same directory as the package.  But that's much less likely than one in the rest 
of the path.


Module in sub-package:

     import sys
     sys.path = ['../..'] + sys.path

     import package.subpackage.module   # finds "self" (subpackage) reliably.


By explicitly adding the packages parent directory to the *front* of sys.path it 
resolves cases where imports using absolute imports, import modules from another 
package because they are found first in the search path.


Adding this tip to the documentation some where would be nice.  (providing there 
is no major surprising side effects.)  Of course I may have missed some obvious 
way to do this.  If so, it wasn't in an obvious place to be found. I looked.   ;-)


----------------------------------


It might be useful to have a built-in function to do this.  A function could 
also check for __init__ files and raise errors if they are missing.

    set_package_name(dotted.name)  # Replaces import sys & path modification

Where dotted.name is the full package + sub-package name the current module is 
located in.  The function would search upwards to get the root package directory 
and add that to the *front* of sys.path.


Module in package:

     set_package_name('package')    # Add parent directory to front of sys.path

     import packagename.module  # Finds module in "this!" package reliably.


Module in subpackage:

     set_package_name('package.subpackage')

     import package.subpackage.module  # Finds "self" (subpackage) reliably.


----------------------------------


It may also be able to modify the import behavior to allow relative imports to 
work when the module is run as script.

     set_package_name('package')

     from . import module1    # Imports modules from "this" package.
     from . import module2


Currently an exception is raised you try to run a module with relative 
references as a script.

	ValueError: Attempted relative import in non-package


I think it is very handy to be able to run tests as scripts and keep them in a 
sub-package. Especially while I'm writing them.

Another benefit of using relative imports with an absolute specified package 
name, is if you rename a package or relocate a submodule, you only have one line 
to change.


Cheers,

Ron


















More information about the Python-ideas mailing list