From: Zac Medico Date: Wed, 11 Mar 2009 06:08:40 +0000 (-0000) Subject: Reduce bloat in portage.util by splitting ObjectProxy and lazyimport into a X-Git-Tag: v2.1.6.8~141 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=15d1574979961526de50632d54a5eac316ffd3ab;p=portage.git Reduce bloat in portage.util by splitting ObjectProxy and lazyimport into a new portage.proxy package. (trunk r12676) svn path=/main/branches/2.1.6/; revision=12936 --- diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 5ab44d762..e54898735 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -73,8 +73,9 @@ if platform.system() in ["FreeBSD"]: try: from portage.cache.cache_errors import CacheError - import portage.util as util - util.lazy_import(globals(), + import portage.proxy.lazyimport + import portage.proxy as proxy + proxy.lazyimport.lazyimport(globals(), 'portage.checksum', 'portage.checksum:perform_checksum,perform_md5,prelink_capable', 'portage.cvstree', @@ -93,6 +94,14 @@ try: 'portage.update:dep_transform,fixdbentries,grab_updates,' + \ 'parse_updates,update_config_files,update_dbentries,' + \ 'update_dbentry', + 'portage.util', + 'portage.util: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', 'portage.versions:best,catpkgsplit,catsplit,endversion_keys,' + \ 'suffix_value@endversion,pkgcmp,pkgsplit,vercmp,ververify', 'portage.xpak', @@ -111,12 +120,6 @@ try: from portage.data import ostype, lchown, userland, secpass, uid, wheelgid, \ portage_uid, portage_gid, userpriv_groups from portage.manifest import Manifest - - 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 from portage.localization import _ @@ -7691,13 +7694,13 @@ def create_trees(config_root=None, target_root=None, trees=None): binarytree, myroot, mysettings["PKGDIR"], settings=mysettings) return trees -class _LegacyGlobalProxy(portage.util.ObjectProxy): +class _LegacyGlobalProxy(proxy.objectproxy.ObjectProxy): """ Instances of these serve as proxies to global variables that are initialized on demand. """ def __init__(self, name): - portage.util.ObjectProxy.__init__(self) + proxy.objectproxy.ObjectProxy.__init__(self) object.__setattr__(self, '_name', name) def _get_target(self): @@ -7705,7 +7708,7 @@ class _LegacyGlobalProxy(portage.util.ObjectProxy): name = object.__getattribute__(self, '_name') return globals()[name] -class _PortdbProxy(portage.util.ObjectProxy): +class _PortdbProxy(proxy.objectproxy.ObjectProxy): """ The portdb is initialized separately from the rest of the variables, since sometimes the other variables @@ -7720,13 +7723,13 @@ class _PortdbProxy(portage.util.ObjectProxy): _portdb_initialized = True return portdb -class _MtimedbProxy(portage.util.ObjectProxy): +class _MtimedbProxy(proxy.objectproxy.ObjectProxy): """ The mtimedb is independent from the portdb and other globals. """ def __init__(self, name): - portage.util.ObjectProxy.__init__(self) + proxy.objectproxy.ObjectProxy.__init__(self) object.__setattr__(self, '_name', name) def _get_target(self): 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')()) diff --git a/pym/portage/util.py b/pym/portage/util.py index 14481a111..a8dbf6c27 100644 --- a/pym/portage/util.py +++ b/pym/portage/util.py @@ -1,7 +1,17 @@ -# Copyright 2004 Gentoo Foundation +# Copyright 2004-2009 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Id$ +__all__ = ['apply_permissions', 'apply_recursive_permissions', + 'apply_secpass_permissions', 'apply_stat_permissions', 'atomic_ofstream', + 'cmp_sort_key', 'ConfigProtect', 'dump_traceback', 'ensure_dirs', + 'getconfig', 'getlibpaths', 'grabdict', 'grabdict_package', 'grabfile', + 'grabfile_package', 'grablines', 'initialize_logger', 'LazyItemsDict', + 'map_dictlist_vals', 'new_protect_filename', 'normalize_path', + 'pickle_read', 'stack_dictlist', 'stack_dicts', 'stack_lists', + 'unique_array', 'varexpand', 'write_atomic', 'writedict', 'writemsg', + 'writemsg_level', 'writemsg_stdout'] + import os import errno import logging @@ -15,6 +25,7 @@ from portage.exception import PortageException, FileNotFound, \ OperationNotPermitted, PermissionDenied, ReadOnlyFileSystem import portage.exception from portage.dep import isvalidatom +from portage.proxy.objectproxy import ObjectProxy try: import cPickle as pickle @@ -333,176 +344,6 @@ def writedict(mydict,myfilename,writekey=True): return 0 return 1 -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')()) - -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 - """ - - 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) - class _tolerant_shlex(shlex.shlex): def sourcehook(self, newfile): try: