1111 NormalizeFunction ,
1212 LemmatizeFunction ,
1313)
14- from wn ._util import normalize_form
14+ from wn ._util import normalize_form , unique_list
1515from wn ._db import NON_ROWID
1616from wn ._queries import (
1717 find_lexicons ,
@@ -487,12 +487,6 @@ def __repr__(self) -> str:
487487 + f"({ self .name !r} , { self .source_id !r} , { self .target_id !r} )"
488488 )
489489
490- def source (self ) -> '_Relatable' :
491- raise NotImplementedError
492-
493- def target (self ) -> '_Relatable' :
494- raise NotImplementedError
495-
496490 def metadata (self ) -> Metadata :
497491 """Return the synset's metadata."""
498492 return get_metadata (self ._id , self ._ENTITY_TYPE )
@@ -501,53 +495,30 @@ def metadata(self) -> Metadata:
501495class SynsetRelation (_Relation ):
502496 _ENTITY_TYPE = _EntityType .SYNSET_RELATIONS
503497
504- def source (self ) -> 'Synset' :
505- return self ._wordnet .synset (id = self .source_id )
506-
507- def target (self ) -> 'Synset' :
508- return self ._wordnet .synset (id = self .target_id )
509-
510498
511499class SenseRelation (_Relation ):
512500 _ENTITY_TYPE = _EntityType .SENSE_RELATIONS
513501
514- def source (self ) -> 'Sense' :
515- return self ._wordnet .sense (id = self .source_id )
516-
517- def target (self ) -> 'Sense' :
518- return self ._wordnet .sense (id = self .target_id )
519-
520502
521503class SenseSynsetRelation (_Relation ):
522504 _ENTITY_TYPE = _EntityType .SENSE_SYNSET_RELATIONS
523505
524- def source (self ) -> 'Sense' :
525- return self ._wordnet .sense (id = self .source_id )
526-
527- def target (self ) -> 'Synset' :
528- return self ._wordnet .synset (id = self .target_id )
529-
530506
531507T = TypeVar ('T' , bound = '_Relatable' )
532508
533509
534510class _Relatable (_LexiconElement ):
535- __slots__ = 'id' , '_in_rel'
511+ __slots__ = 'id' ,
536512
537513 def __init__ (
538514 self ,
539515 id : str ,
540516 _lexid : int = NON_ROWID ,
541517 _id : int = NON_ROWID ,
542- _in_rel : Optional [_Relation ] = None ,
543518 _wordnet : Optional ['Wordnet' ] = None
544519 ):
545520 super ().__init__ (_lexid = _lexid , _id = _id , _wordnet = _wordnet )
546521 self .id = id
547- self ._in_rel = _in_rel
548-
549- def incoming_relation (self ) -> Optional [_Relation ]:
550- return self ._in_rel
551522
552523 def relations (self : T , * args : str ) -> dict [str , list [T ]]:
553524 raise NotImplementedError
@@ -598,21 +569,16 @@ class Synset(_Relatable):
598569
599570 _ENTITY_TYPE = _EntityType .SYNSETS
600571
601- _in_rel : Union [SynsetRelation , SenseSynsetRelation , None ]
602-
603572 def __init__ (
604573 self ,
605574 id : str ,
606575 pos : str ,
607576 ili : Optional [str ] = None ,
608577 _lexid : int = NON_ROWID ,
609578 _id : int = NON_ROWID ,
610- _in_rel : Union [SynsetRelation , SenseSynsetRelation , None ] = None ,
611579 _wordnet : Optional ['Wordnet' ] = None ,
612580 ):
613- super ().__init__ (
614- id = id , _lexid = _lexid , _id = _id , _in_rel = _in_rel , _wordnet = _wordnet
615- )
581+ super ().__init__ (id = id , _lexid = _lexid , _id = _id , _wordnet = _wordnet )
616582 self .pos = pos
617583 self ._ili = ili
618584
@@ -622,12 +588,9 @@ def empty(
622588 id : str ,
623589 ili : Optional [str ] = None ,
624590 _lexid : int = NON_ROWID ,
625- _in_rel : Union [SynsetRelation , SenseSynsetRelation , None ] = None ,
626591 _wordnet : Optional ['Wordnet' ] = None
627592 ):
628- return cls (
629- id , pos = '' , ili = ili , _lexid = _lexid , _in_rel = _in_rel , _wordnet = _wordnet
630- )
593+ return cls (id , pos = '' , ili = ili , _lexid = _lexid , _wordnet = _wordnet )
631594
632595 @property
633596 def ili (self ):
@@ -722,9 +685,6 @@ def lemmas(self) -> list[Form]:
722685 """
723686 return [w .lemma () for w in self .words ()]
724687
725- def incoming_relation (self ) -> Union [SynsetRelation , SenseSynsetRelation , None ]:
726- return self ._in_rel
727-
728688 def relations (self , * args : str ) -> dict [str , list ['Synset' ]]:
729689 """Return a mapping of relation names to lists of synsets.
730690
@@ -746,15 +706,12 @@ def relations(self, *args: str) -> dict[str, list['Synset']]:
746706 hyponym [['coat button'], ['shirt button']]
747707
748708 """
749- d : dict [str , list [Synset ]] = {}
750- for ss in self .get_related (* args ):
751- if relation := ss .incoming_relation ():
752- relname = relation .name
753- if relname in d :
754- d [relname ].append (ss )
755- else :
756- d [relname ] = [ss ]
757- return d
709+ # inner dict is used as an order-preserving set
710+ relmap : dict [str , dict [Synset , bool ]] = {}
711+ for relation , synset in self ._iter_relations (* args ):
712+ relmap .setdefault (relation .name , {})[synset ] = True
713+ # now convert inner dicts to lists
714+ return {relname : list (ss_dict ) for relname , ss_dict in relmap .items ()}
758715
759716 def get_related (self , * args : str ) -> list ['Synset' ]:
760717 """Return the list of related synsets.
@@ -774,36 +731,44 @@ def get_related(self, *args: str) -> list['Synset']:
774731 >>> [ss.lemmas() for ss in fulcrum.get_related()]
775732 [['pin', 'pivot'], ['lever']]
776733 """
777- targets : list [Synset ] = []
734+ return unique_list (synset for _ , synset in self ._iter_relations (* args ))
735+
736+ def relation_map (self ) -> dict [SynsetRelation , 'Synset' ]:
737+ return dict (self ._iter_relations ())
738+
739+ def _iter_relations (self , * args : str ) -> Iterator [tuple [SynsetRelation , 'Synset' ]]:
778740 # first get relations from the current lexicon(s)
779741 if self ._id != NON_ROWID :
780- targets . extend ( self ._get_local_relations (args ) )
742+ yield from self ._iter_local_relations (args )
781743 # then attempt to expand via ILI
782744 if self ._ili is not None and self ._wordnet ._expanded_ids :
783- targets .extend (self ._get_expanded_relations (args ))
784- return targets
745+ yield from self ._iter_expanded_relations (args )
785746
786- def _get_local_relations (self , args : Sequence [str ]) -> Iterator ['Synset' ]:
747+ def _iter_local_relations (
748+ self ,
749+ args : Sequence [str ],
750+ ) -> Iterator [tuple [SynsetRelation , 'Synset' ]]:
787751 _wn = self ._wordnet
788752 lexids = self ._get_lexicon_ids ()
789753 iterable = get_synset_relations ({self ._id }, args , lexids )
790754 for relname , rellexid , relrowid , _ , ssid , pos , ili , lexid , rowid in iterable :
791- if lexid not in lexids :
792- continue
793755 synset_rel = SynsetRelation (
794756 relname , self .id , ssid , rellexid , relrowid , _wordnet = _wn
795757 )
796- yield Synset (
758+ synset = Synset (
797759 ssid ,
798760 pos ,
799761 ili ,
800762 _lexid = lexid ,
801763 _id = rowid ,
802- _in_rel = synset_rel ,
803764 _wordnet = _wn
804765 )
766+ yield synset_rel , synset
805767
806- def _get_expanded_relations (self , args : Sequence [str ]) -> Iterator ['Synset' ]:
768+ def _iter_expanded_relations (
769+ self ,
770+ args : Sequence [str ],
771+ ) -> Iterator [tuple [SynsetRelation , 'Synset' ]]:
807772 _wn = self ._wordnet
808773 lexids = self ._get_lexicon_ids ()
809774 expids = self ._wordnet ._expanded_ids
@@ -825,17 +790,17 @@ def _get_expanded_relations(self, args: Sequence[str]) -> Iterator['Synset']:
825790 )
826791 local_ss_rows = list (get_synsets_for_ilis ([ili ], lexicon_rowids = lexids ))
827792
828- for row in local_ss_rows :
829- yield Synset ( * row , _in_rel = synset_rel , _wordnet = _wn )
830-
831- if not local_ss_rows :
832- yield Synset .empty (
793+ if local_ss_rows :
794+ for row in local_ss_rows :
795+ yield synset_rel , Synset ( * row , _wordnet = _wn )
796+ else :
797+ synset = Synset .empty (
833798 id = _INFERRED_SYNSET ,
834799 ili = ili ,
835800 _lexid = self ._lexid ,
836- _in_rel = synset_rel ,
837801 _wordnet = _wn ,
838802 )
803+ yield synset_rel , synset
839804
840805 def hypernym_paths (self , simulate_root : bool = False ) -> list [list ['Synset' ]]:
841806 """Return the list of hypernym paths to a root synset."""
@@ -980,21 +945,16 @@ class Sense(_Relatable):
980945
981946 _ENTITY_TYPE = _EntityType .SENSES
982947
983- _in_rel : Optional [SenseRelation ]
984-
985948 def __init__ (
986949 self ,
987950 id : str ,
988951 entry_id : str ,
989952 synset_id : str ,
990953 _lexid : int = NON_ROWID ,
991954 _id : int = NON_ROWID ,
992- _in_rel : Optional [SenseRelation ] = None ,
993955 _wordnet : Optional ['Wordnet' ] = None
994956 ):
995- super ().__init__ (
996- id = id , _lexid = _lexid , _id = _id , _in_rel = _in_rel , _wordnet = _wordnet
997- )
957+ super ().__init__ (id = id , _lexid = _lexid , _id = _id , _wordnet = _wordnet )
998958 self ._entry_id = entry_id
999959 self ._synset_id = synset_id
1000960
@@ -1061,9 +1021,6 @@ def metadata(self) -> Metadata:
10611021 """Return the sense's metadata."""
10621022 return get_metadata (self ._id , 'senses' )
10631023
1064- def incoming_relation (self ) -> Optional [SenseRelation ]:
1065- return self ._in_rel
1066-
10671024 def relations (self , * args : str ) -> dict [str , list ['Sense' ]]:
10681025 """Return a mapping of relation names to lists of senses.
10691026
@@ -1076,15 +1033,12 @@ def relations(self, *args: str) -> dict[str, list['Sense']]:
10761033 senses.
10771034
10781035 """
1079- d : dict [str , list [Sense ]] = {}
1080- for s in self .get_related (* args ):
1081- if relation := s .incoming_relation ():
1082- relname = relation .name
1083- if relname in d :
1084- d [relname ].append (s )
1085- else :
1086- d [relname ] = [s ]
1087- return d
1036+ # inner dict is used as an order-preserving set
1037+ relmap : dict [str , dict [Sense , bool ]] = {}
1038+ for relation , sense in self ._iter_sense_relations (* args ):
1039+ relmap .setdefault (relation .name , {})[sense ] = True
1040+ # now convert inner dicts to lists
1041+ return {relname : list (s_dict ) for relname , s_dict in relmap .items ()}
10881042
10891043 def get_related (self , * args : str ) -> list ['Sense' ]:
10901044 """Return a list of related senses.
@@ -1103,35 +1057,38 @@ def get_related(self, *args: str) -> list['Sense']:
11031057 incoherent
11041058
11051059 """
1106- lexids = self ._get_lexicon_ids ()
1107- iterable = get_sense_relations (self ._id , args , lexids )
1108- targets : list ['Sense' ] = []
1109- for relname , rellexid , relrowid , sid , eid , ssid , lexid , rowid in iterable :
1110- if lexid not in lexids :
1111- continue
1112- sense_rel = SenseRelation (
1060+ return unique_list (sense for _ , sense in self ._iter_sense_relations (* args ))
1061+
1062+ def get_related_synsets (self , * args : str ) -> list [Synset ]:
1063+ """Return a list of related synsets."""
1064+ return unique_list (
1065+ synset for _ , synset in self ._iter_sense_synset_relations (* args )
1066+ )
1067+
1068+ def _iter_sense_relations (self , * args : str ) -> Iterator [tuple [SenseRelation , 'Sense' ]]:
1069+ iterable = get_sense_relations (self ._id , args , self ._get_lexicon_ids ())
1070+ for relname , rellexid , relrowid , _ , sid , eid , ssid , lexid , rowid in iterable :
1071+ relation = SenseRelation (
11131072 relname , self .id , sid , rellexid , relrowid , _wordnet = self ._wordnet
11141073 )
1115- target = Sense (
1116- sid , eid , ssid , lexid , rowid , _in_rel = sense_rel , _wordnet = self ._wordnet
1074+ sense = Sense (
1075+ sid , eid , ssid , lexid , rowid , _wordnet = self ._wordnet
11171076 )
1118- targets .append (target )
1119- return targets
1077+ yield relation , sense
11201078
1121- def get_related_synsets ( self , * args : str ) -> list [ Synset ]:
1122- """Return a list of related synsets."""
1123- lexids = self . _get_lexicon_ids ()
1124- iterable = get_sense_synset_relations ( self . _id , args , lexids )
1125- targets : list [ Synset ] = []
1126- for relname , rellexid , relrowid , _ , ssid , pos , ili , lexid , rowid in iterable :
1079+ def _iter_sense_synset_relations (
1080+ self ,
1081+ * args : str ,
1082+ ) -> Iterator [ tuple [ SenseSynsetRelation , 'Synset' ]]:
1083+ iterable = get_sense_synset_relations ( self . _id , args , self . _get_lexicon_ids ())
1084+ for relname , rellexid , relrowid , _ , sid , pos , ili , lexid , rowid in iterable :
11271085 relation = SenseSynsetRelation (
11281086 relname , self .id , ssid , rellexid , relrowid , _wordnet = self ._wordnet
11291087 )
1130- target = Synset (
1131- ssid , pos , ili , lexid , rowid , _in_rel = relation , _wordnet = self ._wordnet
1088+ synset = Synset (
1089+ ssid , pos , ili , lexid , rowid , _wordnet = self ._wordnet
11321090 )
1133- targets .append (target )
1134- return targets
1091+ yield relation , synset
11351092
11361093 def translate (
11371094 self ,
0 commit comments