Skip to content

Commit 23164b7

Browse files
committed
refactor(SHACL): ♻️ rewrite build_node_subgraph as an iterative BNode traversal
1 parent 25bc7b4 commit 23164b7

1 file changed

Lines changed: 19 additions & 20 deletions

File tree

  • rocrate_validator/requirements/shacl

rocrate_validator/requirements/shacl/utils.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
from rdflib import RDF, BNode, Graph, Namespace
2222
from rdflib.term import Node
2323

24-
from rocrate_validator.utils import log as logging
25-
from rocrate_validator.constants import RDF_SYNTAX_NS, SHACL_NS
24+
from rocrate_validator.constants import SHACL_NS
2625
from rocrate_validator.errors import BadSyntaxError
2726
from rocrate_validator.models import Severity
27+
from rocrate_validator.utils import log as logging
2828

2929
if TYPE_CHECKING:
3030
from rocrate_validator.requirements.shacl.models import Shape
@@ -34,24 +34,23 @@
3434

3535

3636
def build_node_subgraph(graph: Graph, node: Node) -> Graph:
37-
shape_graph = Graph()
38-
shape_graph += graph.triples((node, None, None))
39-
40-
# add BNodes
41-
for _, _, o in shape_graph:
42-
shape_graph += graph.triples((o, None, None))
43-
44-
# Use the triples method to get all triples that are part of a list
45-
RDF = Namespace(RDF_SYNTAX_NS)
46-
first_predicate = RDF.first
47-
rest_predicate = RDF.rest
48-
shape_graph += graph.triples((None, first_predicate, None))
49-
shape_graph += graph.triples((None, rest_predicate, None))
50-
for _, _, object in shape_graph:
51-
shape_graph += graph.triples((object, None, None))
52-
53-
# return the subgraph
54-
return shape_graph
37+
"""
38+
Build a subgraph with every triple reachable from ``node`` by following BNode objects.
39+
"""
40+
subgraph = Graph()
41+
visited: set = set()
42+
stack: list = [node]
43+
while stack:
44+
current = stack.pop()
45+
if current in visited:
46+
continue
47+
visited.add(current)
48+
for triple in graph.triples((current, None, None)):
49+
subgraph.add(triple)
50+
_, _, obj = triple
51+
if isinstance(obj, BNode) and obj not in visited:
52+
stack.append(obj)
53+
return subgraph
5554

5655

5756
def map_severity(shacl_severity: str) -> Severity:

0 commit comments

Comments
 (0)