allpy
changeset 1106:2b3cad50c2b1
Partially reversed [afed1f] (see #49)
As explained in the ticket, in real life usecases having a monomer belong to
several sequences is sometimes extremely useful. ANY approach to attribution of
monomer to only one sequence will be either confusing or hindering.
* Removed `monomer.sequence` attribute
* Removed unncecessary specialcasing in pickle
* Removed unused tests
* Restored APIs to backward-compatible
* Added deprecated messages to the restored APIs
author | Daniil Alexeyevsky <dendik@kodomo.fbb.msu.ru> |
---|---|
date | Sun, 10 Jun 2012 16:08:47 +0400 |
parents | 149cb9d89283 |
children | bc1a7595d9d1 |
files | allpy/base.py test/test_pickle.py |
diffstat | 2 files changed, 34 insertions(+), 49 deletions(-) [+] |
line diff
1.1 --- a/allpy/base.py Sun Jun 10 15:20:37 2012 +0400 1.2 +++ b/allpy/base.py Sun Jun 10 16:08:47 2012 +0400 1.3 @@ -29,9 +29,6 @@ 1.4 by_name = {} 1.5 """A mapping from full monomer name to Monomer subclass.""" 1.6 1.7 - sequence = None 1.8 - """A sequence the monomer belongs to.""" 1.9 - 1.10 @classmethod 1.11 def _subclass(cls, name='', code1='', code3='', is_modified=False): 1.12 """Create new subclass of Monomer for given monomer type.""" 1.13 @@ -70,6 +67,32 @@ 1.14 for code1, is_modified, code3, name in codes: 1.15 cls._subclass(name, code1, code3, is_modified) 1.16 1.17 + @classmethod 1.18 + def from_code1(cls, code1): 1.19 + """Create new monomer from 1-letter code.""" 1.20 + deprecated( 1.21 + "Monomer.from_code1(...) is deprecated in favor of Sequence.append_monomer(code1=...)" 1.22 + ) 1.23 + monomer = cls.by_code1[code1.upper()]() 1.24 + monomer.input_code1 = code1 1.25 + return monomer 1.26 + 1.27 + @classmethod 1.28 + def from_code3(cls, code3): 1.29 + """Create new monomer from 3-letter code.""" 1.30 + deprecated( 1.31 + "Monomer.from_code3(...) is deprecated in favor of Sequence.append_monomer(code3=...)" 1.32 + ) 1.33 + return cls.by_code3[code3.upper()]() 1.34 + 1.35 + @classmethod 1.36 + def from_name(cls, name): 1.37 + """Create new monomer from full name.""" 1.38 + deprecated( 1.39 + "Monomer.from_name(...) is deprecated in favor of Sequence.append_monomer(name=...)" 1.40 + ) 1.41 + return cls.by_name[name.strip().capitalize()]() 1.42 + 1.43 def __repr__(self): 1.44 return "<Monomer %s>" % str(self.code1) 1.45 1.46 @@ -87,30 +110,6 @@ 1.47 def __ne__(self, other): 1.48 return not (self == other) 1.49 1.50 - def __getstate__(self): 1.51 - """Overcome difficulties with pickle. 1.52 - 1.53 - Pickle is unable to store `set`s/`dict`s that have objects referencing 1.54 - back the `set`/`dict` itself, which `sequence` in monomer does. 1.55 - ( http://bugs.python.org/issue9269 ) 1.56 - 1.57 - To sidestep the bug we store the monomer WITHOUT `sequence` attribute. 1.58 - 1.59 - See also `Sequence.__setstate__`. 1.60 - """ 1.61 - state = {} 1.62 - state.update(vars(self)) 1.63 - if 'sequence' in state: 1.64 - del state['sequence'] 1.65 - return state 1.66 - 1.67 - def _obsolete_method(cls, *args, **kws): 1.68 - """OBSOLETE""" 1.69 - raise AttributeError("Call to obsolete method.") 1.70 - from_code1 = classmethod(_obsolete_method) 1.71 - from_code3 = classmethod(_obsolete_method) 1.72 - from_name = classmethod(_obsolete_method) 1.73 - 1.74 class MarkupContainerMixin(object): 1.75 """Common functions for alignment and sequence for dealing with markups. 1.76 """ 1.77 @@ -199,12 +198,19 @@ 1.78 elif name: 1.79 cls = self.types.Monomer.by_name[name.strip().capitalize()] 1.80 monomer = cls() 1.81 - monomer.sequence = self 1.82 monomer.input_code1 = code1 1.83 self.append(monomer) 1.84 return monomer 1.85 1.86 @classmethod 1.87 + def from_monomers(cls, monomers=[], name='', description='', source=''): 1.88 + """Create sequence from a list of monomer objecst.""" 1.89 + deprecated( 1.90 + "Sequence.from_monomers(...) is deprecated in favor of Sequence(...)" 1.91 + ) 1.92 + return cls(monomers, name, description, source) 1.93 + 1.94 + @classmethod 1.95 def from_string(cls, string, name='', description='', source=''): 1.96 """Create sequences from string of one-letter codes.""" 1.97 self = cls([], name=name, description=description, source=source) 1.98 @@ -226,26 +232,6 @@ 1.99 """Hash sequence by identity.""" 1.100 return id(self) 1.101 1.102 - def __setstate__(self, state): 1.103 - """Overcome difficulties with pickle: add `monomer.sequence` after loading. 1.104 - 1.105 - Pickle is unable to store `set`s/`dict`s that have objects referencing 1.106 - back the `set`/`dict` itself, which `sequence` in monomer does. 1.107 - ( http://bugs.python.org/issue9269 ) 1.108 - 1.109 - To sidestep the bug we store the monomer WITHOUT `sequence` attribute. 1.110 - 1.111 - See also `Monomer.__getstate__`. 1.112 - """ 1.113 - vars(self).update(state) 1.114 - for monomer in self: 1.115 - monomer.sequence = self 1.116 - 1.117 - @classmethod 1.118 - def from_monomers(cls, *args, **kws): 1.119 - """OBSOLETE.""" 1.120 - raise AttributeError("Sequence.from_monomers is obsolete") 1.121 - 1.122 class Alignment(MarkupContainerMixin): 1.123 """Alignment. It is a list of Columns.""" 1.124
2.1 --- a/test/test_pickle.py Sun Jun 10 15:20:37 2012 +0400 2.2 +++ b/test/test_pickle.py Sun Jun 10 16:08:47 2012 +0400 2.3 @@ -18,6 +18,5 @@ 2.4 s = pickle.load(file) 2.5 assert s.name == 'sequence' 2.6 assert str(s) == 'SEQVENCE' 2.7 - assert s[0].sequence is s 2.8 2.9 # vim: set et ts=4 sts=4 sw=4: