From c15a1b698cf144a39a147b2444202bae590e43fc Mon Sep 17 00:00:00 2001 From: holger krekel Date: Mon, 5 Oct 2009 02:22:48 +0200 Subject: [PATCH] forgot to commit the verbatim copy of apipkg in _py/apipkg.py --HG-- branch : trunk --- _py/apipkg.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 _py/apipkg.py diff --git a/_py/apipkg.py b/_py/apipkg.py new file mode 100644 index 000000000..0751719ab --- /dev/null +++ b/_py/apipkg.py @@ -0,0 +1,71 @@ +""" +apipkg: control the exported namespace of a python package. + +see http://pypi.python.org/pypi/apipkg + +(c) holger krekel, 2009 - MIT license +""" +import os, sys +from types import ModuleType + +__version__ = "1.0b1" + +def initpkg(pkgname, exportdefs): + """ initialize given package from the export definitions. """ + pkgmodule = sys.modules[pkgname] + mod = ApiModule(pkgname, exportdefs) + for name, value in mod.__dict__.items(): + if name[:2] != "__" or name == "__all__": + setattr(pkgmodule, name, value) + +def importobj(importspec): + """ return object specified by importspec.""" + modpath, attrname = importspec.split(":") + module = __import__(modpath, None, None, ['__doc__']) + return getattr(module, attrname) + +class ApiModule(ModuleType): + def __init__(self, name, importspec, parent=None): + self.__name__ = name + self.__all__ = list(importspec) + self.__map__ = {} + if parent: + fullname = parent.__fullname__ + "." + name + setattr(parent, name, self) + else: + fullname = name + self.__fullname__ = fullname + for name, importspec in importspec.items(): + if isinstance(importspec, dict): + apimod = ApiModule(name, importspec, parent=self) + sys.modules[apimod.__fullname__] = apimod + else: + if not importspec.count(":") == 1: + raise ValueError("invalid importspec %r" % (importspec,)) + if name == '__doc__': + self.__doc__ = importobj(importspec) + else: + self.__map__[name] = importspec + + def __repr__(self): + return '' % (self.__fullname__,) + + def __getattr__(self, name): + try: + importspec = self.__map__.pop(name) + except KeyError: + raise AttributeError(name) + else: + result = importobj(importspec) + setattr(self, name, result) + return result + + 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: + for name in self.__all__: + hasattr(self, name) # force attribute load, ignore errors + return dict + __dict__ = property(__dict__)