Source

apipkg / apipkg.py

Full commit
holger krekel 804937f 






Ronny Pfannschmi… ef6f2e4 
holger krekel d53b2f5 
holger krekel 804937f 

holger krekel 7306d96 
holger krekel 804937f 
Ralf Schmitt 7d1548e 
holger krekel d833d46 
Ralf Schmitt fd590ef 
holger krekel b3d10fd 




holger krekel c5b20c2 

Ronny Pfannschmi… ef6f2e4 
holger krekel b3d10fd 
Ronny Pfannschmi… ef6f2e4 
holger krekel b3d10fd 
holger krekel f7ad3ae 
Ralf Schmitt fb8c163 
Ralf Schmitt 7d1548e 
Ralf Schmitt fd590ef 

holger krekel b3d10fd 
Ronny Pfannschmi… 9fee4eb 
holger krekel 804937f 
holger krekel d833d46 
holger krekel 5a104e5 
Ralf Schmitt 144664a 







holger krekel 804937f 

holger krekel f7ad3ae 









holger krekel b3d10fd 
holger krekel 804937f 
holger krekel b517c03 
holger krekel 804937f 
holger krekel d833d46 
holger krekel b3d10fd 



holger krekel 804937f 

holger krekel d833d46 


Ronny Pfannschmi… 78ac2d0 
holger krekel 804937f 
holger krekel 56f2070 


holger krekel d833d46 

Ralf Schmitt afac3bb 




holger krekel 4baca1f 

holger krekel 804937f 
holger krekel f7ad3ae 
holger krekel 804937f 

holger krekel 47756ab 






Ronny Pfannschmi… 78ac2d0 
holger krekel 804937f 
Ronny Pfannschmi… 9e411e7 
holger krekel 5fc11da 
holger krekel b3d10fd 
holger krekel e630694 



holger krekel 47756ab 
holger krekel 40bc1c4 
holger krekel 804937f 
holger krekel b517c03 

holger krekel e630694 
holger krekel 804937f 

holger krekel d833d46 
holger krekel 5a104e5 
holger krekel 8c7bb85 



holger krekel 5a104e5 
holger krekel 804937f 
holger krekel 5fc11da 
Ronny Pfannschmi… 9e411e7 
holger krekel 804937f 




holger krekel b517c03 
holger krekel 804937f 
Ronny Pfannschmi… 9e411e7 



holger krekel 804937f 

Ralf Schmitt afac3bb 

holger krekel e7ffdd5 
Ralf Schmitt 7c23fa6 
Ralf Schmitt afac3bb 
Ralf Schmitt 7c23fa6 

holger krekel e7ffdd5 



Ralf Schmitt 7c23fa6 
Ralf Schmitt afac3bb 
Ralf Schmitt 7c23fa6 


holger krekel e7ffdd5 



Ralf Schmitt 7c23fa6 









"""
apipkg: control the exported namespace of a python package.

see http://pypi.python.org/pypi/apipkg

(c) holger krekel, 2009 - MIT license
"""
import os
import sys
from types import ModuleType

__version__ = '1.3.dev'

def initpkg(pkgname, exportdefs, attr=dict()):
    """ initialize given package from the export definitions. """
    oldmod = sys.modules.get(pkgname)
    d = {}
    f = getattr(oldmod, '__file__', None)
    if f:
        f = os.path.abspath(f)
    d['__file__'] = f
    if hasattr(oldmod, '__version__'):
        d['__version__'] = oldmod.__version__
    if hasattr(oldmod, '__loader__'):
        d['__loader__'] = oldmod.__loader__
    if hasattr(oldmod, '__path__'):
        d['__path__'] = [os.path.abspath(p) for p in oldmod.__path__]
    if '__doc__' not in exportdefs and getattr(oldmod, '__doc__', None):
        d['__doc__'] = oldmod.__doc__
    d.update(attr)
    if hasattr(oldmod, "__dict__"):
        oldmod.__dict__.update(d)
    mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d)
    sys.modules[pkgname]  = mod

def importobj(modpath, attrname):
    module = __import__(modpath, None, None, ['__doc__'])
    if not attrname:
        return module

    retval = module
    names = attrname.split(".")
    for x in names:
        retval = getattr(retval, x)
    return retval

class ApiModule(ModuleType):
    def __docget(self):
        try:
            return self.__doc
        except AttributeError:
            if '__doc__' in self.__map__:
                return self.__makeattr('__doc__')
    def __docset(self, value):
        self.__doc = value
    __doc__ = property(__docget, __docset)

    def __init__(self, name, importspec, implprefix=None, attr=None):
        self.__name__ = name
        self.__all__ = [x for x in importspec if x != '__onfirstaccess__']
        self.__map__ = {}
        self.__implprefix__ = implprefix or name
        if attr:
            for name, val in attr.items():
                #print "setting", self.__name__, name, val
                setattr(self, name, val)
        for name, importspec in importspec.items():
            if isinstance(importspec, dict):
                subname = '%s.%s'%(self.__name__, name)
                apimod = ApiModule(subname, importspec, implprefix)
                sys.modules[subname] = apimod
                setattr(self, name, apimod)
            else:
                parts = importspec.split(':')
                modpath = parts.pop(0)
                attrname = parts and parts[0] or ""
                if modpath[0] == '.':
                    modpath = implprefix + modpath

                if not attrname:
                    subname = '%s.%s'%(self.__name__, name)
                    apimod = AliasModule(subname, modpath)
                    sys.modules[subname] = apimod
                    if '.' not in name:
                        setattr(self, name, apimod)
                else:
                    self.__map__[name] = (modpath, attrname)

    def __repr__(self):
        l = []
        if hasattr(self, '__version__'):
            l.append("version=" + repr(self.__version__))
        if hasattr(self, '__file__'):
            l.append('from ' + repr(self.__file__))
        if l:
            return '<ApiModule %r %s>' % (self.__name__, " ".join(l))
        return '<ApiModule %r>' % (self.__name__,)

    def __makeattr(self, name):
        """lazily compute value for name or raise AttributeError if unknown."""
        #print "makeattr", self.__name__, name
        target = None
        if '__onfirstaccess__' in self.__map__:
            target = self.__map__.pop('__onfirstaccess__')
            importobj(*target)()
        try:
            modpath, attrname = self.__map__[name]
        except KeyError:
            if target is not None and name != '__onfirstaccess__':
                # retry, onfirstaccess might have set attrs
                return getattr(self, name)
            raise AttributeError(name)
        else:
            result = importobj(modpath, attrname)
            setattr(self, name, result)
            try:
                del self.__map__[name]
            except KeyError:
                pass # in a recursive-import situation a double-del can happen
            return result

    __getattr__ = __makeattr

    def __dict__(self):
        # force all the content of the module to be loaded when __dict__ is read
        dictdescr = ModuleType.__dict__['__dict__']
        dict = dictdescr.__get__(self)
        if dict is not None:
            hasattr(self, 'some')
            for name in self.__all__:
                try:
                    self.__makeattr(name)
                except AttributeError:
                    pass
        return dict
    __dict__ = property(__dict__)


def AliasModule(modname, modpath, attrname=None):
    mod = []

    def getmod():
        if not mod:
            x = importobj(modpath, None)
            if attrname is not None:
                x = getattr(x, attrname)
            mod.append(x)
        return mod[0]

    class AliasModule(ModuleType):

        def __repr__(self):
            x = modpath
            if attrname:
                x += "." + attrname
            return '<AliasModule %r for %r>' % (modname, x)

        def __getattribute__(self, name):
            return getattr(getmod(), name)

        def __setattr__(self, name, value):
            setattr(getmod(), name, value)

        def __delattr__(self, name):
            delattr(getmod(), name)

    return AliasModule(modname)