From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([69.77.167.62] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1KBk1j-0005Ym-Ns for garchives@archives.gentoo.org; Thu, 26 Jun 2008 05:28:12 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id CAC6BE02AC; Thu, 26 Jun 2008 05:28:10 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 7FC87E02AC for ; Thu, 26 Jun 2008 05:28:10 +0000 (UTC) Received: from stork.gentoo.org (stork.gentoo.org [64.127.104.133]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTP id 101026752C for ; Thu, 26 Jun 2008 05:28:10 +0000 (UTC) Received: from zmedico by stork.gentoo.org with local (Exim 4.69) (envelope-from ) id 1KBk1d-00074s-SV for gentoo-commits@lists.gentoo.org; Thu, 26 Jun 2008 05:28:05 +0000 To: gentoo-commits@lists.gentoo.org From: "Zac Medico (zmedico)" Subject: [gentoo-commits] portage r10798 - main/trunk/pym/portage X-VCS-Repository: portage X-VCS-Revision: 10798 X-VCS-Files: main/trunk/pym/portage/__init__.py main/trunk/pym/portage/util.py X-VCS-Directories: main/trunk/pym/portage X-VCS-Committer: zmedico X-VCS-Committer-Name: Zac Medico Content-Type: text/plain; charset=UTF-8 Message-Id: Sender: Zac Medico Date: Thu, 26 Jun 2008 05:28:05 +0000 Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: 71161747-d0cc-43ff-ad97-2033f157fb7d X-Archives-Hash: c0c2633acbe6c6bda992fc3a9d5edcf8 Author: zmedico Date: 2008-06-26 05:28:04 +0000 (Thu, 26 Jun 2008) New Revision: 10798 Modified: main/trunk/pym/portage/__init__.py main/trunk/pym/portage/util.py Log: Implement lazy initialization of global "portdb", "settings" and other variables that pollute the portage module. This works by initializing the global variables with dummy "proxy" objects that serve as a means to trigger lazy initialization. As soon as the first attribute access or method call occurs on one of the proxy objects, it causes all the proxy objects to be replaced with the real ones. It's possible for an unsupported attribute access or method call on a proxy object to trigger an error, leading to breakage. However, hopefully these such corner cases will negligible (only time will tell). Modified: main/trunk/pym/portage/__init__.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- main/trunk/pym/portage/__init__.py 2008-06-26 00:49:10 UTC (rev 10797= ) +++ main/trunk/pym/portage/__init__.py 2008-06-26 05:28:04 UTC (rev 10798= ) @@ -6907,6 +6907,20 @@ binarytree, myroot, mysettings["PKGDIR"], settings=3Dmysettings) return trees =20 +class _LegacyGlobalProxy(portage.util.ObjectProxy): + """ + Instances of these serve as proxies to global variables + that are initialized on demand. + """ + def __init__(self, name): + portage.util.ObjectProxy.__init__(self) + object.__setattr__(self, '_name', name) + + def _get_target(self): + init_legacy_globals() + name =3D object.__getattribute__(self, '_name') + return globals()[name] + # Initialization of legacy globals. No functions/classes below this poi= nt # please! When the above functions and classes become independent of th= e # below global variables, it will be possible to make the below code @@ -6915,7 +6929,14 @@ # code that is aware of this flag to import portage without the unnecess= ary # overhead (and other issues!) of initializing the legacy globals. =20 +_globals_initialized =3D False + def init_legacy_globals(): + global _globals_initialized + if _globals_initialized: + return + _globals_initialized =3D True + global db, settings, root, portdb, selinux_enabled, mtimedbfile, mtimed= b, \ archlist, features, groups, pkglines, thirdpartymirrors, usedefaults, \ profiledir, flushmtimedb @@ -6974,7 +6995,11 @@ # use within Portage. External use of this variable is unsupported beca= use # it is experimental and it's behavior is likely to change. if "PORTAGE_LEGACY_GLOBALS" not in os.environ: - init_legacy_globals() + for k in ("db", "settings", "root", "portdb", "selinux_enabled", + "mtimedbfile", "mtimedb", "archlist", "features", "groups", + "pkglines", "thirdpartymirrors", "usedefaults", "profiledir", + "flushmtimedb"): + globals()[k] =3D _LegacyGlobalProxy(k) =20 # Clear the cache dircache=3D{} Modified: main/trunk/pym/portage/util.py =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- main/trunk/pym/portage/util.py 2008-06-26 00:49:10 UTC (rev 10797) +++ main/trunk/pym/portage/util.py 2008-06-26 05:28:04 UTC (rev 10798) @@ -912,6 +912,67 @@ perms_modified =3D apply_permissions(dir_path, *args, **kwargs) return created_dir or perms_modified =20 +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. + """ + + def _get_target(self): + raise NotImplementedError(self) + + def __getattribute__(self, attr): + result =3D object.__getattribute__(self, '_get_target')() + return getattr(result, attr) + + def __setattr__(self, attr, value): + result =3D object.__getattribute__(self, '_get_target')() + setattr(result, attr, value) + + def __call__(self, *args, **kwargs): + result =3D object.__getattribute__(self, '_get_target')() + return result(*args, **kwargs) + + def __setitem__(self, key, value): + object.__getattribute__(self, '_get_target')()[key] =3D 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')() =3D=3D other + + def __ne__(self, other): + return object.__getattribute__(self, '_get_target')() !=3D other + + def __nonzero__(self): + if object.__getattribute__(self, '_get_target')(): + return True + return False + class LazyItemsDict(dict): """A mapping object that behaves like a standard dict except that it al= lows for lazy initialization of values via callable objects. Lazy items can= be --=20 gentoo-commits@lists.gentoo.org mailing list