def test_singlular(self): """Clade, Phylogeny: Singular properties for plural attributes.""" conf = PX.Confidence(0.9, "bootstrap") taxo = PX.Taxonomy(rank="genus") # Clade.taxonomy, Clade.confidence clade = PX.Clade(confidences=[conf], taxonomies=[taxo]) self.assertEqual(clade.confidence.type, "bootstrap") self.assertEqual(clade.taxonomy.rank, "genus") # raise if len > 1 clade.confidences.append(conf) self.assertRaises(AttributeError, getattr, clade, "confidence") clade.taxonomies.append(taxo) self.assertRaises(AttributeError, getattr, clade, "taxonomy") # None if [] clade.confidences = [] self.assertEqual(clade.confidence, None) clade.taxonomies = [] self.assertEqual(clade.taxonomy, None) # Phylogeny.confidence tree = PX.Phylogeny(True, confidences=[conf]) self.assertEqual(tree.confidence.type, "bootstrap") tree.confidences.append(conf) self.assertRaises(AttributeError, getattr, tree, "confidence") tree.confidences = [] self.assertEqual(tree.confidence, None)
def _parse_phylogeny(self, parent): """Parse a single phylogeny within the phyloXML tree (PRIVATE). Recursively builds a phylogenetic tree with help from parse_clade, then clears the XML event history for the phylogeny element and returns control to the top-level parsing function. """ phylogeny = PX.Phylogeny( **_dict_str2bool(parent.attrib, ["rooted", "rerootable"])) list_types = { # XML tag, plural attribute "confidence": "confidences", "property": "properties", "clade_relation": "clade_relations", "sequence_relation": "sequence_relations", } for event, elem in self.context: namespace, tag = _split_namespace(elem.tag) if event == "start" and tag == "clade": if phylogeny.root is not None: raise ValueError( "Phylogeny object should only have 1 clade") phylogeny.root = self._parse_clade(elem) continue if event == "end": if tag == "phylogeny": parent.clear() break # Handle the other non-recursive children if tag in list_types: getattr(phylogeny, list_types[tag]).append(getattr(self, tag)(elem)) # Complex types elif tag in ("date", "id"): setattr(phylogeny, tag, getattr(self, tag)(elem)) # Simple types elif tag in ("name", "description"): setattr(phylogeny, tag, _collapse_wspace(elem.text)) # Unknown tags elif namespace != NAMESPACES["phy"]: phylogeny.other.append(self.other(elem, namespace, tag)) parent.clear() else: # NB: This shouldn't happen in valid files raise PhyloXMLError("Misidentified tag: " + tag) return phylogeny
def _parse_phylogeny(self, parent): """Parse a single phylogeny within the phyloXML tree (PRIVATE). Recursively builds a phylogenetic tree with help from parse_clade, then clears the XML event history for the phylogeny element and returns control to the top-level parsing function. """ phylogeny = PX.Phylogeny(**_dict_str2bool(parent.attrib, ['rooted', 'rerootable'])) list_types = { # XML tag, plural attribute 'confidence': 'confidences', 'property': 'properties', 'clade_relation': 'clade_relations', 'sequence_relation': 'sequence_relations', } for event, elem in self.context: namespace, tag = _split_namespace(elem.tag) if event == 'start' and tag == 'clade': assert phylogeny.root is None, \ "Phylogeny object should only have 1 clade" phylogeny.root = self._parse_clade(elem) continue if event == 'end': if tag == 'phylogeny': parent.clear() break # Handle the other non-recursive children if tag in list_types: getattr(phylogeny, list_types[tag]).append( getattr(self, tag)(elem)) # Complex types elif tag in ('date', 'id'): setattr(phylogeny, tag, getattr(self, tag)(elem)) # Simple types elif tag in ('name', 'description'): setattr(phylogeny, tag, _collapse_wspace(elem.text)) # Unknown tags elif namespace != NAMESPACES['phy']: phylogeny.other.append(self.other(elem, namespace, tag)) parent.clear() else: # NB: This shouldn't happen in valid files raise PhyloXMLError('Misidentified tag: ' + tag) return phylogeny