Permalink
Browse files

SearchIO: Add optionalcascade getter/setter to allow Hit objects with…

…out HSPs

Signed-off-by: Kai Blin <kai.blin@biotech.uni-tuebingen.de>
  • Loading branch information...
1 parent 74d44f5 commit 1bbeb6826e5c9389e62f3f93ddb400d157d055d2 Kai Blin committed with peterjc Dec 13, 2012
Showing with 35 additions and 6 deletions.
  1. +5 −5 Bio/SearchIO/_model/hit.py
  2. +30 −1 Bio/SearchIO/_utils.py
View
@@ -8,7 +8,7 @@
from itertools import chain
from Bio._utils import getattr_str, trim_str
-from Bio.SearchIO._utils import allitems, fullcascade
+from Bio.SearchIO._utils import allitems, optionalcascade
from _base import _BaseSearchObject
from hsp import HSP
@@ -239,11 +239,11 @@ def _validate_hsp(self, hsp):
"found %r instead." % (self.query_id, hsp.query_id))
## properties ##
- description = fullcascade('hit_description', """Hit description""")
- query_description = fullcascade('query_description',
+ description = optionalcascade('hit_description', """Hit description""")
+ query_description = optionalcascade('query_description',
"""Description of the query that produced the hit""")
- id = fullcascade('hit_id', """Hit ID string.""")
- query_id = fullcascade('query_id',
+ id = optionalcascade('hit_id', """Hit ID string.""")
+ query_id = optionalcascade('query_id',
"""ID string of the query that produced the hit""")
# returns all hsps
hsps = allitems(doc="""HSP objects contained in the Hit""")
View
@@ -98,7 +98,7 @@ def getter(self):
" %s objects: %r" % (self._items[0].__class__.__name__,
list(attrset)))
else:
- raise AttributeError("%r attribute requires %s objects to be"
+ raise AttributeError("%r attribute requires %s objects to be "
"filled" % (attr, self.__class__.__name__))
return getattr(self._items[0], attr)
@@ -109,6 +109,35 @@ def setter(self, value):
return property(fget=getter, fset=setter, doc=doc)
+def optionalcascade(attr, doc=''):
+ """Returns a getter property with a cascading setter.
+
+ This is similar to `fullcascade`, but for SearchIO containers that have
+ at zero or more items. The getter always tries to retrieve the attribute
+ value from the first item, but falls back to the value in the container.
+ If the items have more than one attribute values, an error will be raised.
+ The setter behaves like `partialcascade`.
+
+ """
+ def getter(self):
+ attrset = set([getattr(item, attr) for item in self._items])
+ if len(attrset) != 1:
+ if len(attrset) > 1:
+ raise ValueError("More than one value present in the contained"
+ " %s objects: %r" % (self._items[0].__class__.__name__,
+ list(attrset)))
+ else:
+ return getattr(self, "_%s" % attr)
+
+ return getattr(self._items[0], attr)
+
+ def setter(self, value):
+ setattr(self, "_%s" % attr, value)
+ for item in self:
+ setattr(item, attr, value)
+
+ return property(fget=getter, fset=setter, doc=doc)
+
def fragcascade(attr, seq_type, doc=''):
"""Returns a getter property with cascading setter, for HSPFragment objects.

0 comments on commit 1bbeb68

Please sign in to comment.