Take the 2-minute tour ×

I have a directory, let's call it Storage full of packages with unwieldy names like mypackage-xxyyzzww, and of course Storage is on my PYTHONPATH. Since packages have long unmemorable names, all of the packages are symlinked to friendlier names, such as mypackage.

Now, I don't want to rely on file system symbolic links to do this, instead I tried mucking around with sys.path and sys.modules. Currently I'm doing something like this:

import imp
imp.load_package('mypackage', 'Storage/mypackage-xxyyzzww')

How bad is it to do things this way, and is there a chance this will break in the future? One funny thing is that there's even no mention of imp.load_package function in the docs.

EDIT: besides not relying on symbolic links, I can't use PYTHONPATH variable anymore.

share|improve this question
How about just choosing shorter named? –  delnan Nov 3 '10 at 19:43
If it ever breaks I suppose you could replace it with load_source +/ load_binary, which are documented. –  James Nov 3 '10 at 19:45
@delnan: Good point. An ounce of prevention worth a pound of hideous hacking around trying to resolve things. Fixing the names seems to simple. And yet... –  S.Lott Nov 3 '10 at 19:45
This is ugly, and will lea to no end of headaches--why aren't you naming the packages in the standard way? If you want separate versions of packages, then put them in different directories ("xyz/package") and add the version to the search path (sys.path.add('xyz')). –  Glenn Maynard Nov 3 '10 at 19:46

3 Answers 3

Instead of using imp, you can assign different names to imported modules.

import mypackage_xxyyzzww as mypackage

If you then create a __init__.py file inside of Storage, you can add several of the above lines to make importing easier.


import mypackage_xxyyzzww as mypackage
import otherpackage_xxyyzzww as otherpackage


>>> from Storage import mypackage, otherpackage
share|improve this answer
"mypackage-xxyyzzww" is not a valid package name. –  Glenn Maynard Nov 3 '10 at 19:50
+1: cleaner and explicit –  Paulo Scardine Nov 3 '10 at 19:54
Ouch, the problem is not the ugliness of the names - you are using ilegal package names! –  Paulo Scardine Nov 3 '10 at 19:57
Thanks for pointing that out. I fixed the package names. –  Garrett Hyde Nov 3 '10 at 20:01
This approach does allow import Storage.mypackage. Tested on python 2.4, 2.6 and 3.1 –  Terrel Shumway Nov 4 '10 at 7:20

importlib may be more appropriate, as it uses/implements the PEP302 mechanism.

Follow the DictImporter example, but override find_module to find the real filename and store it in the dict, then override load_module to get the code from the found file.

You shouldn't need to use sys.path once you've created your Storage module

#from importlib import abc
import imp
import os
import sys
import logging

dprint = logging.debug

class MyImporter(object):
    def __init__(self,path):
        self.names = {}

    def find_module(self,fullname,path=None):
        ml = imp.find_module(fullname,path)
        raise ImportError

    def load_module(self,fullname):
        return imp.load_module(fullname)
        raise ImportError

def load_storage( path, modname=None ):
    if modname is None:
        modname = os.path.basename(path)

    mod = imp.new_module(modname)
    sys.modules[modname] = mod
    assert mod.__name__== modname
    mod.__loader__= MyImporter(path)
    return mod

if __name__=="__main__":

    from Storage import plain
    from Storage import mypkg

Then when you import Storage.mypackage, python will immediately use your importer without bothering to look on sys.path

That doesn't work. The code above does work to import ordinary modules under Storage without requiring Storage to be on sys.path, but both 3.1 and 2.6 seem to ignore the loader attribute mentioned in PEP302. If I uncomment the sys.meta_path line, 3.1 dies with StackOverflow, and 2.6 dies with ImportError. hmmm... I'm out of time now, but may look at it later.

share|improve this answer
oops. importlib is new in python 3.1 –  Terrel Shumway Nov 4 '10 at 0:35

Packages are just entries in the namespace. You should not name your path components with anything that is not a legal python variable name.

share|improve this answer
I forgot to mention one thing: I can't use PYTHONPATH variable anymore, so I don't hinkg that would work. Will update the question. Thanks anyway. –  klzzvn Nov 3 '10 at 19:53
import a.b will throw an error if a/b/__init__.py doesn't exist, even if a/__init__.py sets b to something. –  Glenn Maynard Nov 3 '10 at 19:53

Your Answer


