[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