From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 7E78D1381F3 for ; Thu, 29 Aug 2013 13:53:18 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 0C3CCE0E0C; Thu, 29 Aug 2013 13:53:18 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 5AAC7E0E01 for ; Thu, 29 Aug 2013 13:53:17 +0000 (UTC) Received: from hornbill.gentoo.org (hornbill.gentoo.org [94.100.119.163]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 0FC5E33EC83 for ; Thu, 29 Aug 2013 13:53:16 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id B6F83E468F for ; Thu, 29 Aug 2013 13:53:14 +0000 (UTC) From: "André Erdmann" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "André Erdmann" Message-ID: <1377781992.cbc3333406f8ed796d98f8f5a6fe0ccab60ac7b5.dywi@gentoo> Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/util/ X-VCS-Repository: proj/R_overlay X-VCS-Files: roverlay/util/objects.py X-VCS-Directories: roverlay/util/ X-VCS-Committer: dywi X-VCS-Committer-Name: André Erdmann X-VCS-Revision: cbc3333406f8ed796d98f8f5a6fe0ccab60ac7b5 X-VCS-Branch: master Date: Thu, 29 Aug 2013 13:53:14 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 80ff1042-7f08-4304-b6b8-2c62d32c88a1 X-Archives-Hash: 3fa390743e18cd85e1d9ac97fd085e1d commit: cbc3333406f8ed796d98f8f5a6fe0ccab60ac7b5 Author: André Erdmann mailerd de> AuthorDate: Thu Aug 29 13:13:12 2013 +0000 Commit: André Erdmann mailerd de> CommitDate: Thu Aug 29 13:13:12 2013 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=cbc33334 roverlay/util/objects: comments --- roverlay/util/objects.py | 64 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/roverlay/util/objects.py b/roverlay/util/objects.py index ce4eccb..323bc88 100644 --- a/roverlay/util/objects.py +++ b/roverlay/util/objects.py @@ -11,12 +11,24 @@ class ObjectDisappeared ( Exception ): # --- end of ObjectDisappeared --- class SafeWeakRef ( weakref.ref ): + """A weak reference that supports 'safe' dereferencing, i.e. raising an + exception if the referenced object does no longer exist.""" def deref_unsafe ( self ): + """Dereferences without checking whether the object exists. + + Returns: the object / None + """ return super ( SafeWeakRef, self ).__call__() # --- end of deref_unsafe (...) --- def deref_safe ( self ): + """Safely dereferences the object. + + Returns: the object + + Raises: ObjectDisappeared if the object does no longer exist. + """ obj = super ( SafeWeakRef, self ).__call__() if obj is not None: return obj @@ -28,6 +40,7 @@ class SafeWeakRef ( weakref.ref ): deref = deref_safe def __bool__ ( self ): + """Returns True if the referenced object exists, else False.""" return self.deref_unsafe() is not None # --- end of __bool__ (...) --- @@ -48,6 +61,7 @@ class SafeWeakRef ( weakref.ref ): class NoneRef ( object ): + """A 'reference' to None (compat object).""" def __init__ ( self, obj=None ): super ( NoneRef, self ).__init__() @@ -76,8 +90,17 @@ class NoneRef ( object ): # --- end of NoneRef --- def get_object_ref ( obj ): + """Returns a reference to the given object, either by using the object's + get_ref() function (if defined) or by creating a SafeWeakRef/NoneRef + instance. + + arguments: + * obj -- + """ if obj is None: return NoneRef() + elif isinstance ( obj, ( SafeWeakRef, NoneRef, weakref.ref ) ): + return obj elif hasattr ( obj, 'get_ref' ): return obj.get_ref() else: @@ -129,6 +152,15 @@ class AbstractMethodError ( MethodNotImplementedError ): # --- end of AbstractMethodError --- def _get_exception_wrapper ( err_cls, func ): + """Returns a method that raises the given exception when called. + + arguments: + * err_cls -- class/constructor of the exception that should be raised. + Has to accept 2 args: + - object to which the method is bound + - the actual function + * func -- function to be wrapped + """ def wrapped ( obj, *args, **kwargs ): raise err_cls ( obj, func ) # --- end of wrapped (...) --- @@ -138,7 +170,6 @@ def _get_exception_wrapper ( err_cls, func ): wrapped.__doc__ = func.__doc__ wrapped.__dict__.update ( func.__dict__ ) return wrapped - # --- end of _get_exception_wrapper (...) --- def abstractmethod ( func=None ): @@ -155,6 +186,7 @@ class Referenceable ( object ): CACHE_REF = False def __init__ ( self, *args, **kwargs ): + """Initializes a referenceable object. Ignores all args/kwargs.""" super ( Referenceable, self ).__init__() self._cached_selfref = None if self.CACHE_REF: @@ -162,62 +194,90 @@ class Referenceable ( object ): # --- end of __init__ (...) --- def cache_ref ( self ): + """Creates a cached reference and sets get_ref() so that the cached ref + is returned (when called).""" self._cached_selfref = self.get_new_ref() self.get_ref = self._get_cached_ref # --- end of cache_ref (...) --- def _get_cached_ref ( self ): + """Returns the cached reference.""" return self._cached_selfref # --- end of _get_cached_ref (...) --- def get_new_ref ( self ): + """Returns a new reference.""" return SafeWeakRef ( self ) # --- end of get_new_ref (...) --- + # initially, get_ref() is get_new_ref() get_ref = get_new_ref # --- end of Referenceable --- class ReferenceTree ( Referenceable ): + """A Referenceable that is part of a tree-like data structure with weak + backreferences (each object has one ancestor or None).""" def __init__ ( self, parent ): + """Intializes this referencable object. + + arguments: + * parent -- the parent object (typically not a reference) + """ super ( ReferenceTree, self ).__init__() self.parent_ref = None self.set_parent ( parent ) # --- end of __init__ (...) --- def set_parent ( self, parent ): + """(Re-)sets the parent object. + + arguments: + * parent -- the parent object (typically not a reference) + """ self.parent_ref = get_object_ref ( parent ) # --- end of set_parent (...) --- def get_parent ( self ): + """Returns the parent object (dereferenced parent object reference).""" return self.parent_ref.deref_safe() # --- end of get_parent (...) --- + #get_upper() is an alias to get_parent() get_upper = get_parent # --- end of ReferenceTree --- class ObjectView ( object ): + """A view object (=expose a (sub-)set of another object's data) that + uses weak references.""" ObjectDisappeared = ObjectDisappeared def __init__ ( self, obj ): + """Initializes an object view. + + arguments: + * obj -- object to be "viewed" + """ super ( ObjectView, self ).__init__() - self.obj_ref = get_object_ref ( obj ) + self.obj_ref = get_object_ref ( obj ) self.deref_unsafe = self.obj_ref.deref_unsafe self.deref_safe = self.obj_ref.deref_safe self.deref = self.obj_ref.deref_safe # --- end of __init__ (...) --- def __bool__ ( self ): + """Returns True if the actual object exists, else False.""" return bool ( self.obj_ref ) # --- end of __bool__ (...) --- @abstractmethod def update ( self ): + """Updates this view (collect data from the actual object etc.).""" pass # --- end of update (...) ---