-
Notifications
You must be signed in to change notification settings - Fork 68
Description
There's currently a bit of an issue with the use_shapes argument to validate(). It seems like this causes shapes with IDs to be removed from the graph unless they're included in the list of shapes. This logic makes sense except that it doesn't remove the triples that reference the removed shapes.
For example, if we have a node shape with property shapes A and B and we ask for pySHACL to use only the node shape and property A, it still retains the node shape's link to B which is gone. This results in a SHACL PropertyShape not found error. Example below.
I think this is outside of the SHACL spec (?) so we can do anything sensible here. I would suggest removing all triples that have the removed shape as an object as well as subject in this scenario.
from rdflib.plugins.parsers.jsonld import to_rdf
from rdflib import Graph
import pyshacl
shapes_graph = to_rdf({
"@context": {
"ex": "http://example.org/",
"sh": "http://www.w3.org/ns/shacl#"
},
"@graph": [
{
"@id": "ex:PersonShape",
"@type": "sh:NodeShape",
"sh:targetClass": {"@id": "ex:Person"},
"sh:property": [
{
"@id": "ex:NameProperty",
"sh:path": {"@id": "ex:name"},
"sh:minCount": 1
},
{
"@id": "ex:AgeProperty",
"sh:path": {"@id": "ex:age"},
"sh:minInclusive": 18
}
]
}
]
}, Graph())
data_graph = to_rdf({
"@context": {
"ex": "http://example.org/",
},
"@id": "ex:person1",
"@type": "ex:Person",
"ex:name": "John Doe",
"ex:age": 25
}, Graph())
result = pyshacl.validate(data_graph, shacl_graph=shapes_graph, use_shapes=[
"http://example.org/PersonShape",
"http://example.org/NameProperty"
])Traceback (most recent call last):
File "/Users/milton.m/Programming/MerscopeMetadata/use_shapes.py", line 41, in <module>
result = pyshacl.validate(data_graph, shacl_graph=shapes_graph, use_shapes=[
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/milton.m/Programming/MerscopeMetadata/.venv/lib/python3.12/site-packages/pyshacl/entrypoints.py", line 178, in validate
conforms, report_graph, report_text = validator.run()
^^^^^^^^^^^^^^^
File "/Users/milton.m/Programming/MerscopeMetadata/.venv/lib/python3.12/site-packages/pyshacl/validator.py", line 315, in run
_is_conform, _reports = s.validate(executor, g, focus=on_focus_nodes)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/milton.m/Programming/MerscopeMetadata/.venv/lib/python3.12/site-packages/pyshacl/shape.py", line 772, in validate
_is_conform, _reports = c.evaluate(executor, target_graph, focus_value_nodes, _e_p_copy)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/milton.m/Programming/MerscopeMetadata/.venv/lib/python3.12/site-packages/pyshacl/constraints/core/shape_based_constraints.py", line 99, in evaluate
_nc, _r = self._evaluate_property_shape(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/milton.m/Programming/MerscopeMetadata/.venv/lib/python3.12/site-packages/pyshacl/constraints/core/shape_based_constraints.py", line 116, in _evaluate_property_shape
raise ReportableRuntimeError(
pyshacl.errors.ReportableRuntimeError: SHACL PropertyShape not found: The shape referenced by sh:property does not exist. Please check if the shape 'None' is defined.
pyshacl==0.30.1
rdflib==7.1.4