Skip to content

Commit 4a2a0eb

Browse files
author
Nicholas Car
authored
Merge pull request #1520 from gjhiggins/fix-for-issue837
Fix for issue #837. Graph.[subjects|objects|predicates] optionally return uniques.
2 parents 75c545e + b76c03e commit 4a2a0eb

File tree

5 files changed

+708
-29
lines changed

5 files changed

+708
-29
lines changed

rdflib/graph.py

Lines changed: 119 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -670,35 +670,125 @@ def set(self, triple):
670670
self.add((subject, predicate, object_))
671671
return self
672672

673-
def subjects(self, predicate=None, object=None) -> Iterable[Node]:
674-
"""A generator of subjects with the given predicate and object"""
675-
for s, p, o in self.triples((None, predicate, object)):
676-
yield s
677-
678-
def predicates(self, subject=None, object=None) -> Iterable[Node]:
679-
"""A generator of predicates with the given subject and object"""
680-
for s, p, o in self.triples((subject, None, object)):
681-
yield p
682-
683-
def objects(self, subject=None, predicate=None) -> Iterable[Node]:
684-
"""A generator of objects with the given subject and predicate"""
685-
for s, p, o in self.triples((subject, predicate, None)):
686-
yield o
687-
688-
def subject_predicates(self, object=None):
689-
"""A generator of (subject, predicate) tuples for the given object"""
690-
for s, p, o in self.triples((None, None, object)):
691-
yield s, p
692-
693-
def subject_objects(self, predicate=None):
694-
"""A generator of (subject, object) tuples for the given predicate"""
695-
for s, p, o in self.triples((None, predicate, None)):
696-
yield s, o
697-
698-
def predicate_objects(self, subject=None):
699-
"""A generator of (predicate, object) tuples for the given subject"""
700-
for s, p, o in self.triples((subject, None, None)):
701-
yield p, o
673+
def subjects(self, predicate=None, object=None, unique=False) -> Iterable[Node]:
674+
"""A generator of (optionally unique) subjects with the given
675+
predicate and object"""
676+
if not unique:
677+
for s, p, o in self.triples((None, predicate, object)):
678+
yield s
679+
else:
680+
subs = set()
681+
for s, p, o in self.triples((None, predicate, object)):
682+
if s not in subs:
683+
yield s
684+
try:
685+
subs.add(s)
686+
except MemoryError as e:
687+
logger.error(
688+
f"{e}. Consider not setting parameter 'unique' to True"
689+
)
690+
raise
691+
692+
def predicates(self, subject=None, object=None, unique=False) -> Iterable[Node]:
693+
"""A generator of (optionally unique) predicates with the given
694+
subject and object"""
695+
if not unique:
696+
for s, p, o in self.triples((subject, None, object)):
697+
yield p
698+
else:
699+
preds = set()
700+
for s, p, o in self.triples((subject, None, object)):
701+
if p not in preds:
702+
yield p
703+
try:
704+
preds.add(p)
705+
except MemoryError as e:
706+
logger.error(
707+
f"{e}. Consider not setting parameter 'unique' to True"
708+
)
709+
raise
710+
711+
def objects(self, subject=None, predicate=None, unique=False) -> Iterable[Node]:
712+
"""A generator of (optionally unique) objects with the given
713+
subject and predicate"""
714+
if not unique:
715+
for s, p, o in self.triples((subject, predicate, None)):
716+
yield o
717+
else:
718+
objs = set()
719+
for s, p, o in self.triples((subject, predicate, None)):
720+
if o not in objs:
721+
yield o
722+
try:
723+
objs.add(o)
724+
except MemoryError as e:
725+
logger.error(
726+
f"{e}. Consider not setting parameter 'unique' to True"
727+
)
728+
raise
729+
730+
def subject_predicates(
731+
self, object=None, unique=False
732+
) -> Generator[Tuple[Node, Node], None, None]:
733+
"""A generator of (optionally unique) (subject, predicate) tuples
734+
for the given object"""
735+
if not unique:
736+
for s, p, o in self.triples((None, None, object)):
737+
yield s, p
738+
else:
739+
subj_preds = set()
740+
for s, p, o in self.triples((None, None, object)):
741+
if (s, p) not in subj_preds:
742+
yield s, p
743+
try:
744+
subj_preds.add((s, p))
745+
except MemoryError as e:
746+
logger.error(
747+
f"{e}. Consider not setting parameter 'unique' to True"
748+
)
749+
raise
750+
751+
def subject_objects(
752+
self, predicate=None, unique=False
753+
) -> Generator[Tuple[Node, Node], None, None]:
754+
"""A generator of (optionally unique) (subject, object) tuples
755+
for the given predicate"""
756+
if not unique:
757+
for s, p, o in self.triples((None, predicate, None)):
758+
yield s, o
759+
else:
760+
subj_objs = set()
761+
for s, p, o in self.triples((None, predicate, None)):
762+
if (s, o) not in subj_objs:
763+
yield s, o
764+
try:
765+
subj_objs.add((s, o))
766+
except MemoryError as e:
767+
logger.error(
768+
f"{e}. Consider not setting parameter 'unique' to True"
769+
)
770+
raise
771+
772+
def predicate_objects(
773+
self, subject=None, unique=False
774+
) -> Generator[Tuple[Node, Node], None, None]:
775+
"""A generator of (optionally unique) (predicate, object) tuples
776+
for the given subject"""
777+
if not unique:
778+
for s, p, o in self.triples((subject, None, None)):
779+
yield p, o
780+
else:
781+
pred_objs = set()
782+
for s, p, o in self.triples((subject, None, None)):
783+
if (p, o) not in pred_objs:
784+
yield p, o
785+
try:
786+
pred_objs.add((p, o))
787+
except MemoryError as e:
788+
logger.error(
789+
f"{e}. Consider not setting parameter 'unique' to True"
790+
)
791+
raise
702792

703793
def triples_choices(self, triple, context=None):
704794
subject, predicate, object_ = triple

0 commit comments

Comments
 (0)