Skip to content


Subversion checkout URL

You can clone with
Download ZIP
88 lines (69 sloc) 2.453 kB
"""Loader for Skytools modules.
Primary idea is to allow several major versions to co-exists.
Secondary idea - allow checking minimal minor version.
import sys, os, os.path, re
__all__ = ['require']
_top = os.path.dirname(os.path.abspath(os.path.normpath(__file__)))
_pkg_cache = None
_import_cache = {}
_pat = re.compile('^([a-z]+)-([0-9]+).([0-9]+)$')
def _load_pkg_cache():
global _pkg_cache
if _pkg_cache is not None:
return _pkg_cache
_pkg_cache = {}
for dir in os.listdir(_top):
m = _pat.match(dir)
if not m:
modname =
modver = (int(, int(
_pkg_cache.setdefault(modname, []).append((modver, dir))
for vlist in _pkg_cache.itervalues():
vlist.sort(reverse = True)
return _pkg_cache
def _install_path(pkg, newpath):
for p in sys.path:
pname = os.path.basename(p)
m = _pat.match(pname)
if m and == pkg:
sys.path.insert(0, newpath)
def require(pkg, reqver):
# parse arg
reqval = tuple([int(n) for n in reqver.split('.')])
need = reqval[:2] # cut minor ver
# check if we already have one installed
if pkg in _import_cache:
got = _import_cache[pkg]
if need[0] != got[0] or reqval > got:
raise ImportError("Request for package '%s' ver '%s', have '%s'" % (
pkg, reqver, '.'.join(got)))
# pick best ver from available ones
cache = _load_pkg_cache()
if pkg not in cache:
for pkgver, pkgdir in cache[pkg]:
if pkgver[0] == need[0] and pkgver >= need:
# install the best on
_install_path(pkg, os.path.join(_top, pkgdir))
inst_ver = reqval
# now import whatever is available
mod = __import__(pkg)
# check if it is actually useful
ver_str = mod.__version__
for i, c in enumerate(ver_str):
if c != '.' and not c.isdigit():
ver_str = ver_str[:i]
full_ver = tuple([int(x) for x in ver_str.split('.')])
if full_ver[0] != reqval[0] or reqval > full_ver:
raise ImportError("Request for package '%s' ver '%s', have '%s'" % (
pkg, reqver, '.'.join(full_ver)))
inst_ver = full_ver
# remember full version
_import_cache[pkg] = inst_ver
return mod
Jump to Line
Something went wrong with that request. Please try again.