def test_remove(self): igt = Igt(tiers=[Tier(id='a'), Tier(id='b')]) assert len(igt) == 2 igt.remove(igt[0]) assert len(igt) == 1 assert igt[0].id == 'b' with pytest.raises(KeyError): igt['a']
def separate_tiers(args): tiers = set(args.tiers) # assuming XML for now with open(args.infile, 'r') as instream: src_xc = xigtxml.load(instream) sep_xc = XigtCorpus(attributes=src_xc.attributes, metadata=src_xc.metadata) for igt in src_xc.igts: sep_xc.add( Igt(id=igt.id, type=igt.type, attributes=igt.attributes, metadata=igt.metadata, tiers=[t for t in igt.tiers if t.type in tiers])) xigtxml.dump(open(args.outfile, 'w'), sep_xc) if not args.remainder: return with open(args.infile, 'r') as instream: src_xc = xigtxml.load(instream) rem_xc = XigtCorpus(attributes=src_xc.attributes, metadata=src_xc.metadata) for igt in src_xc.igts: rem_xc.add( Igt(id=igt.id, type=igt.type, attributes=igt.attributes, metadata=igt.metadata, tiers=[t for t in igt.tiers if t.type not in tiers])) xigtxml.dump(open(args.remainder, 'w'), rem_xc)
def test_get_attribute(self): igt = Igt(id='i1', attributes={'one': 1, 'two': 2}) xc = XigtCorpus(igts=[igt], attributes={'three': 3}) self.assertEqual(igt.get_attribute('one'), 1) self.assertEqual(igt.get_attribute('two'), 2) self.assertIs(igt.get_attribute('three'), None) self.assertEqual(igt.get_attribute('three', inherit=True), 3) self.assertEqual(igt.get_attribute('three', default=4), 4)
def test_get_attribute(self): igt = Igt(id='i1', attributes={'one': 1, 'two': 2}) xc = XigtCorpus(igts=[igt], attributes={'three': 3}) assert igt.get_attribute('one') == 1 assert igt.get_attribute('two') == 2 assert igt.get_attribute('three') is None assert igt.get_attribute('three', inherit=True) == 3 assert igt.get_attribute('three', default=4) == 4
def setUp(self): self.i1 = Igt() self.i2 = Igt( id='i1', type='basic', attributes={'attr':'val'}, metadata=[Metadata(type='meta', metas=[Meta(text='meta')])], tiers=[Tier(id='a', items=[Item(id='a1'), Item(id='a2')]), Tier(id='b', items=[Item(id='b1'), Item(id='b2')])] )
def test_append(self): igt = Igt() self.assertRaises(XigtStructureError, igt.append, Item()) self.assertRaises(XigtStructureError, igt.append, Igt()) self.assertRaises(XigtStructureError, igt.append, XigtCorpus()) self.assertRaises(XigtStructureError, igt.append, Metadata()) self.assertRaises(XigtStructureError, igt.append, Meta()) self.assertEqual(len(igt), 0) igt.append(Tier(id='t')) self.assertEqual(len(igt), 1) self.assertRaises(XigtError, igt.append, Tier(id='t')) igt.append(Tier(id='x')) self.assertEqual(len(igt), 2) self.assertEqual(igt[0].id, 't') self.assertEqual(igt[1].id, 'x')
def test_insert(self): igt = Igt() assert len(igt) == 0 igt.insert(0, Tier(id='t')) assert len(igt) == 1 with pytest.raises(XigtError): igt.insert(0, Tier(id='t')) igt.insert(0, Tier(id='x')) igt.insert(100, Tier(id='y')) assert len(igt) == 3 assert igt[0].id == 'x' assert igt[1].id == 't' assert igt[2].id == 'y'
def test_clear(self): igt = Igt() igt.extend([Tier(id='t'), Tier(id='x'), Tier(id='y')]) assert len(igt) == 3 igt.clear() assert len(igt) == 0 assert igt.get(0) is None assert igt.get('t') is None
def test_clear(self): igt = Igt() igt.extend([Tier(id='t'), Tier(id='x'), Tier(id='y')]) self.assertEqual(len(igt), 3) igt.clear() self.assertEqual(len(igt), 0) self.assertIs(igt.get(0), None) self.assertIs(igt.get('t'), None)
def make_igt(block, options): igt_id = block.get('igt_id', None) attributes = make_igt_attributes(block, options) metadata = make_igt_metadata(block, options) raw_tier = make_igt_raw_tier(block, options) return Igt(id=igt_id, attributes=attributes, metadata=[metadata], tiers=[raw_tier])
class WordTypeTest(TestCase): def setUp(self): self.i = Igt(id='i1') self.w = Tier(id='w', type=WORDS_TYPE) self.gw =Tier(id='gw', type=GLOSS_WORD_TYPE, alignment=self.w.id) self.i.extend([self.w, self.gw]) def test_wo_metadata(self): self.assertTrue(is_word_level_gloss(self.gw)) def test_w_metadata(self): self.gw.alignment = None self.assertFalse(is_word_level_gloss(self.gw)) add_word_level_info(self.gw, INTENT_GLOSS_WORD) self.assertTrue(is_word_level_gloss(self.gw)) add_word_level_info(self.gw, INTENT_GLOSS_MORPH) self.assertFalse(is_word_level_gloss(self.gw))
def test_resolve_ref(self): # item has no reference attribute b1 = Item(id='b1') self.assertRaises(KeyError, b1.resolve_ref, 'alignment') # has a reference attribute, but is not contained by a tier b1.alignment = 'a1' self.assertRaises(XigtStructureError, b1.resolve_ref, 'alignment') # item in tier, but tier has no reference attribute t_b = Tier(id='b', items=[b1]) self.assertRaises(KeyError, b1.resolve_ref, 'alignment') # tier has reference attribute, but is not contained by an Igt t_b.alignment = 'a' self.assertRaises(XigtStructureError, b1.resolve_ref, 'alignment') # item in IGT, but referred tier doesn't exist igt = Igt(tiers=[t_b]) self.assertRaises(XigtStructureError, b1.resolve_ref, 'alignment') # referred tier exists, but has no item referred by item's alignment t_a = Tier(id='a') igt.append(t_a) self.assertRaises(XigtStructureError, b1.resolve_ref, 'alignment') # referred item exists, but has no value (which resolves to '') a1 = Item(id='a1') t_a.append(a1) self.assertEqual(b1.resolve_ref('alignment'), '') # referred item has a value a1.text = 'text' self.assertEqual(b1.resolve_ref('alignment'), 'text') # stored item tests self.assertRaises(KeyError, self.i1.resolve_ref, 'alignment') self.assertRaises(KeyError, self.i2.resolve_ref, 'alignment') self.assertEqual(self.i_ac.resolve_ref('alignment'), 'text') self.assertEqual(self.i_ac.resolve_ref('content'), 'te') self.assertEqual(self.i_s.resolve_ref('segmentation'), 'xt') self.assertEqual(self.i_t.resolve_ref('content'), 'text')
def default_decode_igt(elem): ns, tag = _qname_split(elem.tag) assert tag == 'igt' igt = Igt( id=elem.get('id'), type=elem.get('type'), attributes=get_attributes(elem, ignore=('id', 'type')), metadata=[decode_metadata(md) for md in elem.findall('metadata')], tiers=[decode_tier(tier) for tier in elem.findall('tier')], namespace=ns, nsmap=elem.attrib.nsmap) elem.clear() return igt
def test_extend(self): igt = Igt() self.assertEqual(len(igt), 0) igt.extend([Tier(id='t')]) self.assertEqual(len(igt), 1) igt.extend([]) self.assertEqual(len(igt), 1) igt.extend([Tier(id='x'), Tier(id='y')]) self.assertEqual(len(igt), 3) self.assertEqual(igt[0].id, 't') self.assertEqual(igt[1].id, 'x') self.assertEqual(igt[2].id, 'y')
def test_insert(self): igt = Igt() self.assertEqual(len(igt), 0) igt.insert(0, Tier(id='t')) self.assertEqual(len(igt), 1) self.assertRaises(XigtError, igt.insert, 0, Tier(id='t')) igt.insert(0, Tier(id='x')) igt.insert(100, Tier(id='y')) self.assertEqual(len(igt), 3) self.assertEqual(igt[0].id, 'x') self.assertEqual(igt[1].id, 't') self.assertEqual(igt[2].id, 'y')
def test_extend(self): igt = Igt() assert len(igt) == 0 igt.extend([Tier(id='t')]) assert len(igt) == 1 igt.extend([]) assert len(igt) == 1 igt.extend([Tier(id='x'), Tier(id='y')]) assert len(igt) == 3 assert igt[0].id == 't' assert igt[1].id == 'x' assert igt[2].id == 'y'
def make_igt(block, options): igt_id = make_igt_id(block['i'], options['used_igt_ids']) options['used_igt_ids'].add(igt_id) attributes = make_igt_attributes(block, options) metadata = make_igt_metadata(block, options) raw_tier = make_igt_raw_tier(block, options) return Igt( id=igt_id, attributes=attributes, metadata=[metadata], tiers=[raw_tier] )
def make_igt(key, data, context, options): # IDs must start with a letter assert key if not key[0].isalpha(): key = 'igt{}'.format(key) if context is None: context = {} attrs = {} attmap = options['igt_attribute_map'] for (mkr, val) in chain(data, context.items()): if val is None: # will be None if mkr not encountered continue if mkr in attmap: attrs[attmap[mkr]] = val metadata = None w = None with warnings.catch_warnings(record=True) as ws: warnings.simplefilter('always') try: tiers = make_all_tiers(data, options) igt = Igt( id=key, attributes=attrs, metadata=metadata, tiers=tiers ) except (toolbox.ToolboxError, XigtImportError) as ex: logging.error('Error during import of item {}:\n {}' .format(key, str(ex))) igt = None if len(ws) > 0: w = ws[0] if w is not None: if issubclass(w.category, toolbox.ToolboxWarning): warnings.warn('{}: {}'.format(key, w.message), w.category) else: warnings.warn_explicit(w.message, w.category, w.filename, w.lineno) return igt
class TierIdTests(TestCase): def setUp(self): self.i = Igt(id='i1') self.i.append(Tier(id='tw')) self.i.append(Tier(id='w')) def same_type_different_tiers_test(self): pos1_id = gen_tier_id(self.i, 'pos', tier_type='pos', alignment='tw') self.assertEqual(pos1_id, 'tw-pos') self.i.append(Tier(id=pos1_id, type='pos', alignment='tw')) pos2_id = gen_tier_id(self.i, 'pos', tier_type='pos', alignment='tw') self.assertEqual(pos2_id, 'tw-pos_b') def unique_tier_test(self): tw_id = gen_tier_id(self.i, 'w', tier_type='words', alignment='t', no_hyphenate=True) print(tw_id)
def naacl_to_xigt(naacl_path): """ Convert the NAACL format to XIGT. :param naacl_path: """ content = open(naacl_path, 'r').read() # First, collect all the instances. instances = re.findall('Igt_id[\s\S]+?Q6.*Answer', content) xc = XigtCorpus() for instance_txt in instances: # id = re.search('Igt_id=([\S]+)', instance_txt).group(1) inst = Igt(id='i{}'.format(len(xc))) lang_raw, gloss_raw, trans_raw = instance_txt.split('\n')[1:4] # Now, create the raw tier... raw_tier = Tier(id=gen_tier_id(inst, 'r'), type='odin', attributes={STATE_ATTRIBUTE:RAW_STATE}) raw_tier.append(Item(id=ask_item_id(raw_tier), text=lang_raw, attributes={ODIN_TAG_ATTRIBUTE:ODIN_LANG_TAG})) raw_tier.append(Item(id=ask_item_id(raw_tier), text=gloss_raw, attributes={ODIN_TAG_ATTRIBUTE:ODIN_GLOSS_TAG})) raw_tier.append(Item(id=ask_item_id(raw_tier), text=trans_raw, attributes={ODIN_TAG_ATTRIBUTE:ODIN_TRANS_TAG})) inst.append(raw_tier) xc.append(inst) # Generate the clean/normal tiers, but without any cleaning. generate_normal_tier(inst, clean=False) # Lang Dependency representation handling... lang_ds_str = re.search('Q6:([\s\S]+?)Q6:', instance_txt).group(1) lang_ds_lines = lang_ds_str.split('\n')[5:-3] try: lang_dt = parse_naacl_dep(lang(inst), lang_ds_lines) create_dt_tier(inst, lang_dt, lang(inst), parse_method=INTENT_POS_MANUAL) except TreeError as te: pass except IndexError as ie: pass # Eng DS handling... eng_ds_str = re.search('Q3:([\s\S]+?)Q3:', instance_txt).group(1) eng_ds_lines = eng_ds_str.split('\n')[2:-3] try: eng_dt = parse_naacl_dep(trans(inst), eng_ds_lines) create_dt_tier(inst, eng_dt, trans(inst), parse_method=INTENT_POS_MANUAL) except TreeError as te: pass except IndexError as ie: pass except ValueError as ve: pass # Add Alignment... biling_aln_str = re.search('Q5:([\s\S]+?)Q5:', instance_txt).group(1) biling_aln_lines = biling_aln_str.split('\n')[4:-3] trans_offset = trans_raw.startswith(' ') gloss_offset = gloss_raw.startswith(' ') try: a = Alignment() for line in biling_aln_lines: gloss_s, trans_s = line.split()[0:2] if '.' in gloss_s: continue gloss_i = int(gloss_s) for trans_token in trans_s.split(','): trans_i = int(trans_token) if trans_i == 0: continue else: if trans_offset: trans_i -= 1 if gloss_offset: gloss_i -= 1 a.add((trans_i, gloss_i)) except: pass set_bilingual_alignment(inst, trans(inst), gloss(inst), a, aln_method=INTENT_ALN_MANUAL) return xc
def setUp(self): self.i = Igt(id='i1') self.i.append(Tier(id='tw')) self.i.append(Tier(id='w'))
def convert_pml(aln_path, out_path, hindi=True): if hindi: igt_data = retrieve_hindi() else: igt_data = retrieve_naacl() a_root = load_xml(aln_path) doc_a = a_root.find(".//reffile[@name='document_a']").get('href') doc_b = a_root.find(".//reffile[@name='document_b']").get('href') doc_a = os.path.join(os.path.join(os.path.dirname(aln_path), doc_a)) doc_b = os.path.join(os.path.join(os.path.dirname(aln_path), doc_b)) # Load the sentences for each document. a_sents, a_glossed = load_sents(doc_a) b_sents, b_glossed = load_sents(doc_b) sent_alignments = a_root.findall(".//body/LM") assert (a_glossed and not b_glossed) or (b_glossed and not a_glossed), "Only one file should have glosses" xc = XigtCorpus() for sent_alignment in sent_alignments: # Get the sentence id... aln_id = sent_alignment.attrib.get('id') a_snt_id = re.search('^.+?-(.*)$', aln_id).group(1) if a_snt_id not in igt_data: continue # Get the text and tokens from the naacl data. pre_txt, lang_txt, gloss_txt, trans_txt = igt_data[a_snt_id] lang_tokens = lang_txt.split() gloss_tokens = gloss_txt.split() trans_tokens = trans_txt.split() a_snt_ref = sent_alignment.find('./tree_a.rf').text.split('#')[1] b_snt_ref = sent_alignment.find('./tree_b.rf').text.split('#')[1] word_alignments = sent_alignment.findall('./node_alignments/LM') a_snt, a_edges = a_sents[a_snt_ref] b_snt, b_edges = b_sents[b_snt_ref] assert isinstance(a_snt, Sentence) assert isinstance(b_snt, Sentence) # ------------------------------------------- # Skip sentences if they are not found for whatever reason # ------------------------------------------- if not a_snt or not b_snt: continue # ------------------------------------------- # Start constructing the IGT Instance. # ------------------------------------------- trans_snt, trans_indices = a_snt, a_edges gloss_snt, gloss_indices = b_snt, b_edges if a_glossed: trans_snt, trans_indices = b_snt, b_edges gloss_snt, gloss_indices = a_snt, a_edges # Hindi stuff... if hindi: lang_tokens = [w.text for w in gloss_snt] lang_postags = [w.pos for w in gloss_snt] lang_txt = ' '.join(lang_tokens) trans_tokens = [w.text for w in trans_snt] trans_postags = [w.pos for w in trans_snt] trans_txt = ' '.join(trans_tokens) gloss_tokens = [w.gloss if w.gloss else 'NULL' for w in gloss_snt] gloss_postags = lang_postags gloss_txt = ' '.join(gloss_tokens) inst = Igt(id=re.sub('s-', 'igt', a_snt_ref)) nt = Tier(type=ODIN_TIER_TYPE, id=NORM_ID, attributes={STATE_ATTRIBUTE:NORM_STATE}) ll = Item(id='n1', attributes={ODIN_TAG_ATTRIBUTE:ODIN_LANG_TAG}, text=lang_txt) gl = Item(id='n2', attributes={ODIN_TAG_ATTRIBUTE:ODIN_GLOSS_TAG}, text=gloss_txt) tl = Item(id='n3', attributes={ODIN_TAG_ATTRIBUTE:ODIN_TRANS_TAG}, text=trans_txt) nt.extend([ll,gl,tl]) inst.append(nt) # ------------------------------------------- # Handle the phrase tiers # ------------------------------------------- generate_lang_phrase_tier(inst) generate_trans_phrase_tier(inst) def process_postags(sent, tokens): postags = [] for i, token in enumerate(tokens): word = sent.getorder(i+1) if word is None: postags.append(None) else: postags.append(word.pos) return postags # ------------------------------------------- # Now, handle the translation words. # ------------------------------------------- tt = create_word_tier(ODIN_TRANS_TAG, trans_tokens, trans_phrase(inst)[0]) inst.append(tt) if not hindi: trans_postags = process_postags(trans_snt, trans_tokens) add_pos_tags(inst, tt.id, trans_postags, tag_method=INTENT_POS_MANUAL) # ------------------------------------------- # Handle the words tiers... # ------------------------------------------- wt = create_word_tier(ODIN_LANG_TAG, lang_tokens, lang_phrase(inst)[0]) gwt= create_word_tier(ODIN_GLOSS_TAG, gloss_tokens, gl) inst.extend([wt, gwt]) # Quickly set the alignment for the gloss words. for w, gw in zip(wt, gwt): gw.alignment = w.id if not hindi: lang_postags = process_postags(gloss_snt, gloss_tokens) gloss_postags = lang_postags add_pos_tags(inst, wt.id, lang_postags, tag_method=INTENT_POS_MANUAL) add_pos_tags(inst, gwt.id, gloss_postags, tag_method=INTENT_POS_MANUAL) create_dt_tier(inst, assemble_ds(gloss_snt, gloss_indices), wt, INTENT_DS_MANUAL) create_dt_tier(inst, assemble_ds(trans_snt, trans_indices), tt, INTENT_DS_MANUAL) # ------------------------------------------- # Now, the word alignments. # ------------------------------------------- a = Alignment() for word_alignment in word_alignments: a_ref = word_alignment.find('./a.rf').text.split('#')[1] b_ref = word_alignment.find('./b.rf').text.split('#')[1] a_word = a_snt.getid(a_ref) b_word = b_snt.getid(b_ref) if a_word is None or b_word is None: continue if not hindi: a_idx = a_word.order b_idx = b_word.order else: a_idx = a_snt.index(a_word)+1 b_idx = b_snt.index(b_word)+1 # Make sure the gloss is in the if a_glossed: trans_idx = b_idx lang_idx = a_idx else: trans_idx = a_idx lang_idx = b_idx a.add((trans_idx, lang_idx)) set_bilingual_alignment(inst, trans(inst), lang(inst), a, INTENT_ALN_MANUAL) set_bilingual_alignment(inst, trans(inst), gloss(inst), a, INTENT_ALN_MANUAL) xc.append(inst) with open(out_path, 'w', encoding='utf-8') as f: xigtxml.dump(f, xc)
def test_append(self): igt = Igt() with pytest.raises(XigtStructureError): igt.append(Item()) with pytest.raises(XigtStructureError): igt.append(Igt()) with pytest.raises(XigtStructureError): igt.append(XigtCorpus()) with pytest.raises(XigtStructureError): igt.append(Metadata()) with pytest.raises(XigtStructureError): igt.append(Meta()) assert len(igt) == 0 igt.append(Tier(id='t')) assert len(igt) == 1 with pytest.raises(XigtError): igt.append(Tier(id='t')) igt.append(Tier(id='x')) assert len(igt) == 2 assert igt[0].id == 't' assert igt[1].id == 'x'
def setUp(self): self.i = Igt(id='i1') self.w = Tier(id='w', type=WORDS_TYPE) self.gw =Tier(id='gw', type=GLOSS_WORD_TYPE, alignment=self.w.id) self.i.extend([self.w, self.gw])
class TestIgt(unittest.TestCase): def setUp(self): self.i1 = Igt() self.i2 = Igt( id='i1', type='basic', attributes={'attr':'val'}, metadata=[Metadata(type='meta', metas=[Meta(text='meta')])], tiers=[Tier(id='a', items=[Item(id='a1'), Item(id='a2')]), Tier(id='b', items=[Item(id='b1'), Item(id='b2')])] ) def test_init(self): self.assertRaises(ValueError, Igt, id='1') # invalid id # don't allow multiple tiers with the same ID self.assertRaises(XigtError, Igt, tiers=[Tier(id='a'), Tier(id='a')]) def test_id(self): self.assertIs(self.i1.id, None) self.assertEqual(self.i2.id, 'i1') def test_type(self): self.assertIs(self.i1.type, None) self.assertEqual(self.i2.type, 'basic') def test_tiers(self): self.assertEqual(len(self.i1.tiers), 0) self.assertEqual(len(self.i2.tiers), 2) # contained Tiers should now have their igt specified for t in self.i2.tiers: self.assertIs(t.igt, self.i2) def test_parents(self): self.assertIs(self.i1.corpus, None) self.assertIs(self.i2.corpus, None) def test_metadata(self): self.assertEqual(len(self.i1.metadata), 0) self.assertEqual(self.i2.metadata[0].type, 'meta') self.assertEqual(len(self.i2.metadata[0].metas), 1) self.assertEqual(self.i2.metadata[0][0].text, 'meta') def test_attributes(self): self.assertEqual(self.i1.attributes, dict()) self.assertEqual(self.i2.attributes, {'attr':'val'}) def test_get(self): self.assertIs(self.i1.get(0), None) self.assertIs(self.i1.get('t'), None) self.assertEqual(self.i1.get('t', default=1), 1) self.assertEqual(self.i2.get(0).id, 'a') self.assertIs(self.i2.get(3), None) self.assertEqual(self.i2.get('a').id, 'a') self.assertEqual( self.i2.get('a', default=Tier(id='x')).id, 'a' ) def test_get_item(self): self.assertIs(self.i1.get_item('a'), None) self.assertIs(self.i1.get_item('a1'), None) self.assertIs(self.i2.get_item('a'), None) self.assertEqual(self.i2.get_item('a1').id, 'a1') self.assertEqual(self.i2.get_item('b2').id, 'b2') def test_get_any(self): self.assertIs(self.i1.get_any('a'), None) self.assertIs(self.i1.get_any('a1'), None) self.assertIs(self.i2.get_any('a').id, 'a') self.assertEqual(self.i2.get_any('a1').id, 'a1') self.assertEqual(self.i2.get_any('b2').id, 'b2') def test_append(self): igt = Igt() self.assertRaises(XigtStructureError, igt.append, Item()) self.assertRaises(XigtStructureError, igt.append, Igt()) self.assertRaises(XigtStructureError, igt.append, XigtCorpus()) self.assertRaises(XigtStructureError, igt.append, Metadata()) self.assertRaises(XigtStructureError, igt.append, Meta()) self.assertEqual(len(igt), 0) igt.append(Tier(id='t')) self.assertEqual(len(igt), 1) self.assertRaises(XigtError, igt.append, Tier(id='t')) igt.append(Tier(id='x')) self.assertEqual(len(igt), 2) self.assertEqual(igt[0].id, 't') self.assertEqual(igt[1].id, 'x') def test_insert(self): igt = Igt() self.assertEqual(len(igt), 0) igt.insert(0, Tier(id='t')) self.assertEqual(len(igt), 1) self.assertRaises(XigtError, igt.insert, 0, Tier(id='t')) igt.insert(0, Tier(id='x')) igt.insert(100, Tier(id='y')) self.assertEqual(len(igt), 3) self.assertEqual(igt[0].id, 'x') self.assertEqual(igt[1].id, 't') self.assertEqual(igt[2].id, 'y') def test_extend(self): igt = Igt() self.assertEqual(len(igt), 0) igt.extend([Tier(id='t')]) self.assertEqual(len(igt), 1) igt.extend([]) self.assertEqual(len(igt), 1) igt.extend([Tier(id='x'), Tier(id='y')]) self.assertEqual(len(igt), 3) self.assertEqual(igt[0].id, 't') self.assertEqual(igt[1].id, 'x') self.assertEqual(igt[2].id, 'y') def test_clear(self): igt = Igt() igt.extend([Tier(id='t'), Tier(id='x'), Tier(id='y')]) self.assertEqual(len(igt), 3) igt.clear() self.assertEqual(len(igt), 0) self.assertIs(igt.get(0), None) self.assertIs(igt.get('t'), None) def test_get_attribute(self): igt = Igt(id='i1', attributes={'one': 1, 'two': 2}) xc = XigtCorpus(igts=[igt], attributes={'three': 3}) self.assertEqual(igt.get_attribute('one'), 1) self.assertEqual(igt.get_attribute('two'), 2) self.assertIs(igt.get_attribute('three'), None) self.assertEqual(igt.get_attribute('three', inherit=True), 3) self.assertEqual(igt.get_attribute('three', default=4), 4)