Coverage for python/pyshacl_turbo/shape.py: 100.0%
59 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-16 12:25 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-16 12:25 +0000
1"""RDFLib-facing shape inspection; targeting executes in Rust."""
3import logging
4from decimal import Decimal
6from rdflib.namespace import RDF, RDFS, SH
8from .target_data import prepare_target_data
11class Shape:
12 def __init__(self, sg, node, p=False, path=None, logger=None):
13 self.sg = sg 1efhijgbcd
14 self.node = node 1efhijgbcd
15 self._p = p 1efhijgbcd
16 self._path = path 1efhijgbcd
17 self._advanced = False 1efhijgbcd
18 self.logger = logger or logging.getLogger(__name__) 1efhijgbcd
20 @property
21 def is_property_shape(self):
22 return self._p 1bc
24 @property
25 def deactivated(self):
26 return bool(self.sg.graph.value(self.node, SH.deactivated)) 1bc
28 @property
29 def severity(self):
30 return self.sg.graph.value(self.node, SH.severity, default=SH.Violation) 1d
32 @property
33 def message(self):
34 return iter(set(self.objects(SH.message))) 1d
36 @property
37 def name(self):
38 return iter(set(self.objects(SH.name))) 1d
40 @property
41 def description(self):
42 return iter(set(self.objects(SH.description))) 1d
44 @property
45 def order(self):
46 return Decimal(str(self.sg.graph.value(self.node, SH.order, default=0))) 1d
48 def objects(self, predicate):
49 return self.sg.objects(self.node, predicate) 1bcd
51 def path(self):
52 return self._path if self._p else None 1bc
54 def property_shapes(self):
55 return self.objects(SH.property) 1d
57 def get_other_shape(self, node):
58 return self.sg.lookup_shape_from_node(node) 1d
60 def target_nodes(self):
61 return self.objects(SH.targetNode) 1bc
63 def target_classes(self):
64 return self.objects(SH.targetClass) 1bc
66 def target_objects_of(self):
67 return self.objects(SH.targetObjectsOf) 1bc
69 def target_subjects_of(self):
70 return self.objects(SH.targetSubjectsOf) 1bc
72 def implicit_class_targets(self):
73 classes = set(self.sg.graph.subjects(RDFS.subClassOf, RDFS.Class)) | {RDFS.Class} 1bc
74 return [self.node] if classes.intersection(self.objects(RDF.type)) else [] 1bc
76 def target(self):
77 return ( 1bc
78 self.target_nodes(),
79 self.target_classes(),
80 self.implicit_class_targets(),
81 self.target_objects_of(),
82 self.target_subjects_of(),
83 )
85 def set_advanced(self, value):
86 self._advanced = bool(value) 1efg
88 def focus_nodes(self, data_graph, debug=False):
89 data = prepare_target_data(data_graph) 1efhijgbcd
90 return data._focus_nodes(self.sg._compile(), self.node, self._advanced) 1efhijgbcd