Skip to content

Commit 740266c

Browse files
committed
chore(SHACL-core): reformat and clean up
1 parent 90a9f06 commit 740266c

2 files changed

Lines changed: 137 additions & 65 deletions

File tree

rocrate_validator/requirements/shacl/checks.py

Lines changed: 137 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,27 @@
1616
from timeit import default_timer as timer
1717
from typing import Optional
1818

19-
from rocrate_validator.utils import log as logging
2019
from rocrate_validator.errors import ROCrateMetadataNotFoundError
2120
from rocrate_validator.events import EventType
22-
from rocrate_validator.models import (LevelCollection, Requirement,
23-
RequirementCheck,
24-
RequirementCheckValidationEvent,
25-
SkipRequirementCheck, ValidationContext)
21+
from rocrate_validator.models import (
22+
LevelCollection,
23+
Requirement,
24+
RequirementCheck,
25+
RequirementCheckValidationEvent,
26+
SkipRequirementCheck,
27+
ValidationContext,
28+
)
2629
from rocrate_validator.requirements.shacl.models import Shape
27-
from rocrate_validator.requirements.shacl.utils import make_uris_relative
30+
from rocrate_validator.requirements.shacl.utils import make_uris_relative, resolve_parent_shape
2831
from rocrate_validator.requirements.shacl.validator import (
29-
SHACLValidationAlreadyProcessed, SHACLValidationContext,
30-
SHACLValidationContextManager, SHACLValidationSkip, SHACLValidator,
31-
SHACLViolation)
32+
SHACLValidationAlreadyProcessed,
33+
SHACLValidationContext,
34+
SHACLValidationContextManager,
35+
SHACLValidationSkip,
36+
SHACLValidator,
37+
SHACLViolation,
38+
)
39+
from rocrate_validator.utils import log as logging
3240

3341
logger = logging.getLogger(__name__)
3442

@@ -41,25 +49,27 @@ class SHACLCheck(RequirementCheck):
4149
# Map shape to requirement check instances
4250
__instances__ = {}
4351

44-
def __init__(self,
45-
requirement: Requirement,
46-
shape: Shape,
47-
name: Optional[str] = None,
48-
root: bool = False,
49-
hidden: Optional[bool] = None,
50-
level: Optional[bool] = None) -> None:
52+
def __init__(
53+
self,
54+
requirement: Requirement,
55+
shape: Shape,
56+
name: Optional[str] = None,
57+
root: bool = False,
58+
hidden: Optional[bool] = None,
59+
level: Optional[bool] = None,
60+
) -> None:
5161
self._shape = shape
5262
self._root = root
5363
# init the check
54-
super().__init__(requirement,
55-
name or shape.name if shape and shape.name
56-
else shape.parent.name if shape.parent
57-
else None,
58-
description=shape.description if shape and shape.description
59-
else shape.parent.description if shape.parent
60-
else None,
61-
level=level,
62-
hidden=hidden)
64+
super().__init__(
65+
requirement,
66+
(name or shape.name if shape and shape.name else shape.parent.name if shape.parent else None),
67+
description=(
68+
shape.description if shape and shape.description else shape.parent.description if shape.parent else None
69+
),
70+
level=level,
71+
hidden=hidden,
72+
)
6373
# store the instance
6474
SHACLCheck.__add_instance__(shape, self)
6575

@@ -69,10 +79,14 @@ def __init__(self,
6979
declared_level = shape.get_declared_level()
7080
if declared_level:
7181
if shape.level.severity != requirement_level_from_path.severity:
72-
logger.warning("Mismatch in requirement level for check \"%s\": "
73-
"shape level %s does not match the level from the containing folder %s. "
74-
"Consider moving the shape property or removing the severity property.",
75-
self.name, shape.level, requirement_level_from_path)
82+
logger.warning(
83+
'Mismatch in requirement level for check "%s": '
84+
"shape level %s does not match the level from the containing folder %s. "
85+
"Consider moving the shape property or removing the severity property.",
86+
self.name,
87+
shape.level,
88+
requirement_level_from_path,
89+
)
7690
self._level = level
7791

7892
@property
@@ -85,7 +99,11 @@ def root(self) -> bool:
8599

86100
@property
87101
def description(self) -> str:
88-
return self._shape.description
102+
if self._shape.description:
103+
return self._shape.description
104+
if self._shape.parent and self._shape.parent.description:
105+
return self._shape.parent.description
106+
return f"Check for {self._shape.name}" if self._shape.name else "SHACL validation check"
89107

90108
def __compute_requirement_level__(self) -> LevelCollection:
91109
if self._shape and self._shape.get_declared_level():
@@ -107,31 +125,50 @@ def severity(self) -> str:
107125
def execute_check(self, context: ValidationContext):
108126
logger.debug("Starting check %s", self)
109127
try:
110-
logger.debug("SHACL Validation of profile %s requirement %s started",
111-
self.requirement.profile.identifier, self.identifier)
128+
logger.debug(
129+
"SHACL Validation of profile %s requirement %s started",
130+
self.requirement.profile.identifier,
131+
self.identifier,
132+
)
112133
with SHACLValidationContextManager(self, context) as ctx:
113134
# The check is executed only if the profile is the most specific one
114-
logger.debug("SHACL Validation of requirement check %s (profile: %s) started",
115-
self.requirement.profile.identifier, self.identifier)
135+
logger.debug(
136+
"SHACL Validation of requirement check %s (profile: %s) started",
137+
self.requirement.profile.identifier,
138+
self.identifier,
139+
)
116140
result = self.__do_execute_check__(ctx)
117141
ctx.current_validation_result = self.identifier not in result
118-
logger.debug("SHACL Validation of requirement check %s (profile: %s) finished with result %s",
119-
self.requirement.profile.identifier, self.identifier, ctx.current_validation_result)
142+
logger.debug(
143+
"SHACL Validation of requirement check %s (profile: %s) finished with result %s",
144+
self.requirement.profile.identifier,
145+
self.identifier,
146+
ctx.current_validation_result,
147+
)
120148
return ctx.current_validation_result
121149
except SHACLValidationAlreadyProcessed:
122-
logger.debug("SHACL Validation of requirement check %s (profile: %s) already processed",
123-
self.requirement.identifier, self.requirement.profile.identifier)
150+
logger.debug(
151+
"SHACL Validation of requirement check %s (profile: %s) already processed",
152+
self.requirement.identifier,
153+
self.requirement.profile.identifier,
154+
)
124155
# The check belongs to a profile which has already been processed
125156
# so we can skip the validation and return the specific result for the check
126157
return self.identifier not in [i.check.identifier for i in context.result.get_issues()]
127158
except SHACLValidationSkip as e:
128-
logger.debug("SHACL Validation of profile %s requirement %s skipped",
129-
self.requirement.profile.identifier, self.identifier)
159+
logger.debug(
160+
"SHACL Validation of profile %s requirement %s skipped",
161+
self.requirement.profile.identifier,
162+
self.identifier,
163+
)
130164
# The validation is postponed to the more specific profiles
131165
# so the check is not considered as failed.
132166
raise SkipRequirementCheck(self, str(e))
133167
except ROCrateMetadataNotFoundError as e:
134-
logger.debug("Unable to perform metadata validation due to missing metadata file: %s", e)
168+
logger.debug(
169+
"Unable to perform metadata validation due to missing metadata file: %s",
170+
e,
171+
)
135172
return False
136173

137174
def __do_execute_check__(self, shacl_context: SHACLValidationContext):
@@ -151,12 +188,17 @@ def __do_execute_check__(self, shacl_context: SHACLValidationContext):
151188
end_time = timer()
152189
logger.debug(f"Execution time for getting data graph: {end_time - start_time} seconds")
153190
except json.decoder.JSONDecodeError as e:
154-
logger.debug("Unable to perform metadata validation "
155-
"due to one or more errors in the JSON-LD data file: %s", e)
191+
logger.debug(
192+
"Unable to perform metadata validation " "due to one or more errors in the JSON-LD data file: %s",
193+
e,
194+
)
156195
shacl_context.result.add_issue(
157-
"Unable to perform metadata validation due to one or more errors in the JSON-LD data file", self)
196+
"Unable to perform metadata validation due to one or more errors in the JSON-LD data file",
197+
self,
198+
)
158199
raise ROCrateMetadataNotFoundError(
159-
"Unable to perform metadata validation due to one or more errors in the JSON-LD data file")
200+
"Unable to perform metadata validation due to one or more errors in the JSON-LD data file"
201+
)
160202

161203
# Begin the timer
162204
start_time = timer()
@@ -177,7 +219,10 @@ def __do_execute_check__(self, shacl_context: SHACLValidationContext):
177219
start_time = timer()
178220
shacl_validator = SHACLValidator(shapes_graph=shapes_graph, ont_graph=ontology_graph)
179221
shacl_result = shacl_validator.validate(
180-
data_graph=data_graph, ontology_graph=ontology_graph, **shacl_context.settings.to_dict())
222+
data_graph=data_graph,
223+
ontology_graph=ontology_graph,
224+
**shacl_context.settings.to_dict(),
225+
)
181226
# shacl_result.results_graph.serialize("logs/validation_results.ttl", format="turtle")
182227
# parse the validation result
183228
end_time = timer()
@@ -190,8 +235,10 @@ def __do_execute_check__(self, shacl_context: SHACLValidationContext):
190235
# if the validation fails, process the failed checks
191236
failed_requirements_checks = set()
192237
failed_requirements_checks_violations: dict[str, SHACLViolation] = {}
193-
failed_requirement_checks_notified = [_.check.identifier for _ in shacl_context.result.get_issues(
194-
min_severity=shacl_context.settings.requirement_severity)]
238+
failed_requirement_checks_notified = [
239+
_.check.identifier
240+
for _ in shacl_context.result.get_issues(min_severity=shacl_context.settings.requirement_severity)
241+
]
195242

196243
logger.debug("Parsing Validation with result: %s", shacl_result)
197244
# process the failed checks to extract the requirement checks involved
@@ -234,8 +281,10 @@ def __do_execute_check__(self, shacl_context: SHACLValidationContext):
234281
for requirementCheck in sorted(failed_requirements_checks, key=lambda x: (x.identifier, x.severity)):
235282
# if the check is not in the current profile
236283
# and the disable_inherited_profiles_reporting is enabled, skip it
237-
if requirementCheck.requirement.profile != shacl_context.current_validation_profile and \
238-
shacl_context.settings.disable_inherited_profiles_issue_reporting:
284+
if (
285+
requirementCheck.requirement.profile != shacl_context.current_validation_profile
286+
and shacl_context.settings.disable_inherited_profiles_issue_reporting
287+
):
239288
continue
240289
for violation in failed_requirements_checks_violations[requirementCheck.identifier]:
241290
violating_entity = make_uris_relative(violation.focusNode.toPython(), shacl_context.publicID)
@@ -246,13 +295,18 @@ def __do_execute_check__(self, shacl_context: SHACLValidationContext):
246295
# check if the violation is already registered
247296
# and skip the requirement check if it is
248297
for check_issue in registered_check_issues:
249-
if check_issue.message == violation_message and \
250-
check_issue.violatingProperty == violating_property and \
251-
check_issue.violatingEntity == violating_entity and \
252-
check_issue.violatingPropertyValue == violation.value:
298+
if (
299+
check_issue.message == violation_message
300+
and check_issue.violatingProperty == violating_property
301+
and check_issue.violatingEntity == violating_entity
302+
and check_issue.violatingPropertyValue == violation.value
303+
):
253304
skip_requirement_check = True
254-
logger.debug("Skipping requirement check %s: %s", requirementCheck.identifier,
255-
violation_message)
305+
logger.debug(
306+
"Skipping requirement check %s: %s",
307+
requirementCheck.identifier,
308+
violation_message,
309+
)
256310
break
257311
# if the check is not to be skipped, add the issue to the context
258312
if not skip_requirement_check:
@@ -261,7 +315,9 @@ def __do_execute_check__(self, shacl_context: SHACLValidationContext):
261315
check=requirementCheck,
262316
violatingProperty=violating_property,
263317
violatingEntity=violating_entity,
264-
violatingPropertyValue=violation.value)
318+
violatingPropertyValue=violation.value,
319+
)
320+
logger.debug("Added validation issue to the context: %s", c)
265321
# if the fail fast mode is enabled, stop the validation after the first issue
266322
if shacl_context.fail_fast:
267323
break
@@ -279,7 +335,10 @@ def __do_execute_check__(self, shacl_context: SHACLValidationContext):
279335
shacl_context.validator.notify(RequirementCheckValidationEvent(
280336
EventType.REQUIREMENT_CHECK_VALIDATION_END,
281337
requirementCheck, validation_result=False))
282-
logger.debug("Added validation issue to the context: %s", c)
338+
logger.debug(
339+
"Added failed check to the context: %s",
340+
requirementCheck.identifier,
341+
)
283342

284343
# if the fail fast mode is enabled, stop the validation after the first failed check
285344
if shacl_context.fail_fast:
@@ -296,16 +355,30 @@ def __do_execute_check__(self, shacl_context: SHACLValidationContext):
296355
if requirementCheck.identifier not in failed_requirement_checks_notified:
297356
failed_requirement_checks_notified.append(requirementCheck.identifier)
298357
shacl_context.result._add_executed_check(requirementCheck, True)
299-
if requirementCheck.requirement.profile != shacl_context.target_profile and \
300-
shacl_context.settings.disable_inherited_profiles_issue_reporting:
358+
if (
359+
requirementCheck.requirement.profile != shacl_context.target_profile
360+
and shacl_context.settings.disable_inherited_profiles_issue_reporting
361+
):
301362
continue
302-
shacl_context.validator.notify(RequirementCheckValidationEvent(
303-
EventType.REQUIREMENT_CHECK_VALIDATION_END, requirementCheck, validation_result=True))
304-
logger.debug("Added skipped check to the context: %s", requirementCheck.identifier)
363+
shacl_context.validator.notify(
364+
RequirementCheckValidationEvent(
365+
EventType.REQUIREMENT_CHECK_VALIDATION_END,
366+
requirementCheck,
367+
validation_result=True,
368+
)
369+
)
370+
logger.debug(
371+
"Added skipped check to the context: %s",
372+
requirementCheck.identifier,
373+
)
305374

306375
logger.debug("Remaining skipped checks: %r", len(shacl_context.result.skipped_checks))
307376
for requirementCheck in shacl_context.result.skipped_checks:
308-
logger.debug("Remaining skipped check: %r - %s", requirementCheck.identifier, requirementCheck.name)
377+
logger.debug(
378+
"Remaining skipped check: %r - %s",
379+
requirementCheck.identifier,
380+
requirementCheck.name,
381+
)
309382
end_time = timer()
310383
logger.debug(f"Execution time for parsing the validation result: {end_time - start_time} seconds")
311384

rocrate_validator/requirements/shacl/models.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ def __process_property_group__(groups: dict[str, PropertyGroup], property_shape:
431431
if group_name:
432432
if group_name not in groups:
433433
groups[group_name] = PropertyGroup(URIRef(property_shape.group), property_shape.graph)
434-
property_shape.graph.serialize("logs/property_shape.ttl", format="turtle")
435434
groups[group_name].add_property(property_shape)
436435
property_shape._property_group = groups[group_name]
437436
return groups[group_name]

0 commit comments

Comments
 (0)