summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-02-20 06:15:34 +0000
committerZac Medico <zmedico@gentoo.org>2009-02-20 06:15:34 +0000
commitfb05e64acc278e4395b4209e2219c404b3697252 (patch)
treec7a4049dc4ddc100b30e973d7d567984ac656f93
parent2308ea9e8bebf6899b19b04fe58ba8f35521e05c (diff)
downloadportage-fb05e64acc278e4395b4209e2219c404b3697252.tar.gz
portage-fb05e64acc278e4395b4209e2219c404b3697252.tar.bz2
portage-fb05e64acc278e4395b4209e2219c404b3697252.zip
Add a new portage.utils.lazy_import() function which behaves similar to the
snakeoil.demandload.demandload() function. svn path=/main/trunk/; revision=12661
-rw-r--r--pym/portage/__init__.py53
-rw-r--r--pym/portage/dbapi/bintree.py2
-rw-r--r--pym/portage/util.py101
3 files changed, 126 insertions, 30 deletions
diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py
index 15af77571..621daa7be 100644
--- a/pym/portage/__init__.py
+++ b/pym/portage/__init__.py
@@ -73,17 +73,30 @@ if platform.system() in ["FreeBSD"]:
try:
from portage.cache.cache_errors import CacheError
- import portage.cvstree
- import portage.xpak
- import portage.getbinpkg
- import portage.dep
- from portage.dep import dep_getcpv, dep_getkey, get_operator, \
- isjustname, isspecific, isvalidatom, \
- match_from_list, match_to_list, best_match_to_list
-
- # XXX: This needs to get cleaned up.
- import portage.output
- from portage.output import bold, colorize, green, red, yellow
+ import portage.util as util
+ util.lazy_import(globals(),
+ 'portage.checksum',
+ 'portage.checksum:perform_checksum,perform_md5,prelink_capable',
+ 'portage.cvstree',
+ 'portage.dep',
+ 'portage.dep:best_match_to_list,dep_getcpv,dep_getkey,' + \
+ 'get_operator,isjustname,isspecific,isvalidatom,' + \
+ 'match_from_list,match_to_list',
+ 'portage.eclass_cache',
+ 'portage.getbinpkg',
+ 'portage.locks',
+ 'portage.locks:lockdir,lockfile,unlockdir,unlockfile',
+ 'portage.output',
+ 'portage.output:bold,colorize',
+ 'portage.process',
+ 'portage.process:atexit_register,run_exitfuncs',
+ 'portage.update:dep_transform,fixdbentries,grab_updates,' + \
+ 'parse_updates,update_config_files,update_dbentries,' + \
+ 'update_dbentry',
+ 'portage.versions:best,catpkgsplit,catsplit,endversion_keys,' + \
+ 'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify',
+ 'portage.xpak',
+ )
import portage.const
from portage.const import VDB_PATH, PRIVATE_PATH, CACHE_PATH, DEPCACHE_PATH, \
@@ -99,31 +112,13 @@ try:
portage_uid, portage_gid, userpriv_groups
from portage.manifest import Manifest
- import portage.util
from portage.util import atomic_ofstream, apply_secpass_permissions, apply_recursive_permissions, \
dump_traceback, getconfig, grabdict, grabdict_package, grabfile, grabfile_package, \
map_dictlist_vals, new_protect_filename, normalize_path, \
pickle_read, pickle_write, stack_dictlist, stack_dicts, stack_lists, \
unique_array, varexpand, writedict, writemsg, writemsg_stdout, write_atomic
import portage.exception
- import portage.locks
- import portage.process
- from portage.process import atexit_register, run_exitfuncs
- from portage.locks import unlockfile,unlockdir,lockfile,lockdir
- import portage.checksum
- from portage.checksum import perform_md5,perform_checksum,prelink_capable
- import portage.eclass_cache
from portage.localization import _
- from portage.update import dep_transform, fixdbentries, grab_updates, \
- parse_updates, update_config_files, update_dbentries, update_dbentry
-
- # Need these functions directly in portage namespace to not break every external tool in existence
- from portage.versions import best, catpkgsplit, catsplit, pkgcmp, \
- pkgsplit, vercmp, ververify
-
- # endversion and endversion_keys are for backward compatibility only.
- from portage.versions import endversion_keys
- from portage.versions import suffix_value as endversion
except ImportError, e:
sys.stderr.write("\n\n")
diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py
index 7f2c0cbf0..1d2c17ab8 100644
--- a/pym/portage/dbapi/bintree.py
+++ b/pym/portage/dbapi/bintree.py
@@ -16,7 +16,7 @@ from portage.update import update_dbentries
from portage import dep_expand, listdir, _check_distfile, _movefile
-import portage.xpak, portage.getbinpkg
+import portage
import os, errno, stat
import re
diff --git a/pym/portage/util.py b/pym/portage/util.py
index da79d86fe..54df38192 100644
--- a/pym/portage/util.py
+++ b/pym/portage/util.py
@@ -10,6 +10,7 @@ import shlex
import stat
import string
import sys
+import types
from portage.exception import PortageException, FileNotFound, \
OperationNotPermitted, PermissionDenied, ReadOnlyFileSystem
@@ -341,6 +342,8 @@ class ObjectProxy(object):
for implementing lazy initialization.
"""
+ __slots__ = ()
+
def _get_target(self):
raise NotImplementedError(self)
@@ -392,6 +395,104 @@ class ObjectProxy(object):
def __nonzero__(self):
return bool(object.__getattribute__(self, '_get_target')())
+class _LazyImport(ObjectProxy):
+
+ __slots__ = ('_scope', '_alias', '_name', '_target')
+
+ def __init__(self, scope, alias, name):
+ ObjectProxy.__init__(self)
+ object.__setattr__(self, '_scope', scope)
+ object.__setattr__(self, '_alias', alias)
+ object.__setattr__(self, '_name', name)
+
+ def _get_target(self):
+ try:
+ return object.__getattribute__(self, '_target')
+ except AttributeError:
+ pass
+ name = object.__getattribute__(self, '_name')
+ __import__(name)
+ target = sys.modules[name]
+ object.__setattr__(self, '_target', target)
+ object.__getattribute__(self, '_scope')[
+ object.__getattribute__(self, '_alias')] = target
+ return target
+
+class _LazyImportFrom(_LazyImport):
+
+ __slots__ = ()
+
+ def _get_target(self):
+ try:
+ return object.__getattribute__(self, '_target')
+ except AttributeError:
+ pass
+ name = object.__getattribute__(self, '_name')
+ components = name.split('.')
+ parent_name = '.'.join(components[:-1])
+ __import__(parent_name)
+ target = getattr(sys.modules[parent_name], components[-1])
+ object.__setattr__(self, '_target', target)
+ object.__getattribute__(self, '_scope')[
+ object.__getattribute__(self, '_alias')] = target
+ return target
+
+def lazy_import(scope, *args):
+ """
+ Create a proxy in the given scope in order to performa a lazy import.
+
+ Syntax Result
+ foo import foo
+ foo:bar,baz from foo import bar, baz
+ foo:bar@baz from foo import bar as baz
+
+ @param scope: the scope in which to place the import, typically globals()
+ @type myfilename: dict
+ @param args: module names to import
+ @type args: strings
+ """
+
+ for s in args:
+ parts = s.split(':', 1)
+ if len(parts) == 1:
+ name = s
+
+ if not name or not isinstance(name, basestring):
+ raise ValueError(name)
+
+ components = name.split('.')
+ parent_scope = scope
+ for i in xrange(len(components)):
+ alias = components[i]
+ mod = parent_scope.get(alias)
+ if isinstance(mod, types.ModuleType):
+ parent_scope = mod.__dict__
+ continue
+ if i < len(components) - 1:
+ parent_name = ".".join(components[:i+1])
+ __import__(parent_name)
+ mod = sys.modules.get(parent_name)
+ if not isinstance(mod, types.ModuleType):
+ # raise an exception
+ __import__(name)
+ parent_scope[alias] = mod
+ parent_scope = mod.__dict__
+ continue
+ parent_scope[alias] = _LazyImport(parent_scope, alias, name)
+
+ else:
+ name, fromlist = parts
+ fromlist = fromlist.split(',')
+ for s in fromlist:
+ alias = s.split('@', 1)
+ if len(alias) == 1:
+ alias = alias[0]
+ orig = alias
+ else:
+ orig, alias = alias
+ scope[alias] = _LazyImportFrom(scope, alias,
+ name + '.' + orig)
+
class _tolerant_shlex(shlex.shlex):
def sourcehook(self, newfile):
try: