summaryrefslogtreecommitdiffstats
path: root/pym/portage/proxy
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2009-02-22 02:46:26 +0000
committerZac Medico <zmedico@gentoo.org>2009-02-22 02:46:26 +0000
commitb111f7defd5e1cbc704d7a4cf500a139807b8b1f (patch)
treea76edf84550ddd67484d464652d79da221d644e6 /pym/portage/proxy
parent6c33a6b5314bf45de7106362b746fa86cc05a98a (diff)
downloadportage-b111f7defd5e1cbc704d7a4cf500a139807b8b1f.tar.gz
portage-b111f7defd5e1cbc704d7a4cf500a139807b8b1f.tar.bz2
portage-b111f7defd5e1cbc704d7a4cf500a139807b8b1f.zip
Reduce bloat in portage.util by splitting ObjectProxy and lazyimport into a
new portage.proxy package. svn path=/main/trunk/; revision=12676
Diffstat (limited to 'pym/portage/proxy')
-rw-r--r--pym/portage/proxy/__init__.py3
-rw-r--r--pym/portage/proxy/lazyimport.py118
-rw-r--r--pym/portage/proxy/objectproxy.py66
3 files changed, 187 insertions, 0 deletions
diff --git a/pym/portage/proxy/__init__.py b/pym/portage/proxy/__init__.py
new file mode 100644
index 000000000..95cbda1ed
--- /dev/null
+++ b/pym/portage/proxy/__init__.py
@@ -0,0 +1,3 @@
+# Copyright 2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
diff --git a/pym/portage/proxy/lazyimport.py b/pym/portage/proxy/lazyimport.py
new file mode 100644
index 000000000..6e9717642
--- /dev/null
+++ b/pym/portage/proxy/lazyimport.py
@@ -0,0 +1,118 @@
+# Copyright 2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+__all__ = ['lazy_import']
+
+import sys
+import types
+from portage.proxy.objectproxy import ObjectProxy
+
+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 lazyimport(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
+ """
+
+ modules = sys.modules
+
+ 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]
+ if i < len(components) - 1:
+ parent_name = ".".join(components[:i+1])
+ __import__(parent_name)
+ mod = modules.get(parent_name)
+ if not isinstance(mod, types.ModuleType):
+ # raise an exception
+ __import__(name)
+ parent_scope[alias] = mod
+ parent_scope = mod.__dict__
+ continue
+
+ already_imported = modules.get(name)
+ if already_imported is not None:
+ parent_scope[alias] = already_imported
+ else:
+ parent_scope[alias] = \
+ _LazyImport(parent_scope, alias, name)
+
+ else:
+ name, fromlist = parts
+ already_imported = modules.get(name)
+ fromlist = fromlist.split(',')
+ for s in fromlist:
+ alias = s.split('@', 1)
+ if len(alias) == 1:
+ alias = alias[0]
+ orig = alias
+ else:
+ orig, alias = alias
+ if already_imported is not None:
+ try:
+ scope[alias] = getattr(already_imported, orig)
+ except AttributeError:
+ raise ImportError('cannot import name %s' % orig)
+ else:
+ scope[alias] = _LazyImportFrom(scope, alias,
+ name + '.' + orig)
diff --git a/pym/portage/proxy/objectproxy.py b/pym/portage/proxy/objectproxy.py
new file mode 100644
index 000000000..00d3f6157
--- /dev/null
+++ b/pym/portage/proxy/objectproxy.py
@@ -0,0 +1,66 @@
+# Copyright 2008-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+__all__ = ['ObjectProxy']
+
+class ObjectProxy(object):
+
+ """
+ Object that acts as a proxy to another object, forwarding
+ attribute accesses and method calls. This can be useful
+ for implementing lazy initialization.
+ """
+
+ __slots__ = ()
+
+ def _get_target(self):
+ raise NotImplementedError(self)
+
+ def __getattribute__(self, attr):
+ result = object.__getattribute__(self, '_get_target')()
+ return getattr(result, attr)
+
+ def __setattr__(self, attr, value):
+ result = object.__getattribute__(self, '_get_target')()
+ setattr(result, attr, value)
+
+ def __call__(self, *args, **kwargs):
+ result = object.__getattribute__(self, '_get_target')()
+ return result(*args, **kwargs)
+
+ def __setitem__(self, key, value):
+ object.__getattribute__(self, '_get_target')()[key] = value
+
+ def __getitem__(self, key):
+ return object.__getattribute__(self, '_get_target')()[key]
+
+ def __delitem__(self, key):
+ del object.__getattribute__(self, '_get_target')()[key]
+
+ def __contains__(self, key):
+ return key in object.__getattribute__(self, '_get_target')()
+
+ def __iter__(self):
+ return iter(object.__getattribute__(self, '_get_target')())
+
+ def __len__(self):
+ return len(object.__getattribute__(self, '_get_target')())
+
+ def __repr__(self):
+ return repr(object.__getattribute__(self, '_get_target')())
+
+ def __str__(self):
+ return str(object.__getattribute__(self, '_get_target')())
+
+ def __hash__(self):
+ return hash(object.__getattribute__(self, '_get_target')())
+
+ def __eq__(self, other):
+ return object.__getattribute__(self, '_get_target')() == other
+
+ def __ne__(self, other):
+ return object.__getattribute__(self, '_get_target')() != other
+
+ def __nonzero__(self):
+ return bool(object.__getattribute__(self, '_get_target')())