Skip to content

Commit 0b6bff7

Browse files
committed
docs(profiles): ✨ document check override-by-name and deactivation
1 parent 1acd74d commit 0b6bff7

1 file changed

Lines changed: 148 additions & 0 deletions

File tree

docs/11_writing_a_profile.rst

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,154 @@ These instructions assume you are familiar with code development using Python an
9494
#. When your profile & tests are written, open a pull request to contribute
9595
it back to the repository!
9696

97+
Overriding inherited checks
98+
---------------------------
99+
100+
When a profile inherits from another profile (via ``prof:isProfileOf`` /
101+
``prof:isTransitiveProfileOf``), it automatically receives every check
102+
declared by its ancestors. The validator additionally supports
103+
**override-by-name**: a child profile can replace an inherited check by
104+
declaring a new check with the **same name**.
105+
106+
This allows an extension profile to *redefine* the content of an inherited
107+
check — for example, to make a constraint stricter or looser, change its
108+
severity, or, as described in the next section, fully deactivate it.
109+
110+
Override-by-name is enabled by default. It can be disabled via the
111+
``allow_requirement_check_override`` validation setting (CLI / API), which
112+
will raise an error on duplicate check names instead.
113+
114+
SHACL checks
115+
^^^^^^^^^^^^
116+
117+
Each SHACL ``NodeShape`` / ``PropertyShape`` becomes a check whose name is
118+
its ``sh:name``. To override an inherited check, declare a shape in the
119+
extension profile with the **same** ``sh:name`` as the inherited one:
120+
121+
.. code-block:: turtle
122+
123+
# Parent profile
124+
ro:ShapeC
125+
a sh:NodeShape ;
126+
sh:name "The Shape C" ;
127+
sh:targetNode ro:ro-crate-metadata.json ;
128+
sh:property [
129+
a sh:PropertyShape ;
130+
sh:name "Check Metadata File Descriptor entity existence" ;
131+
sh:path rdf:type ;
132+
sh:minCount 1 ;
133+
sh:message "Missing entity" ;
134+
] .
135+
136+
.. code-block:: turtle
137+
138+
# Extension profile — overrides the inherited PropertyShape by sh:name
139+
ro:ShapeC
140+
a sh:NodeShape ;
141+
sh:name "The Shape C" ;
142+
sh:targetNode ro:ro-crate-metadata.json ;
143+
sh:property [
144+
a sh:PropertyShape ;
145+
sh:name "Check Metadata File Descriptor entity existence" ;
146+
sh:path rdf:type ;
147+
sh:minCount 1 ;
148+
sh:maxCount 1 ;
149+
sh:message "Stricter override from extension profile" ;
150+
] .
151+
152+
Both top-level shapes and ``PropertyShape`` entries nested inside a parent
153+
``NodeShape`` (i.e., declared inline, without an absolute IRI) can be
154+
overridden this way.
155+
156+
Python checks
157+
^^^^^^^^^^^^^
158+
159+
Python checks declared via the ``@check`` decorator are matched by their
160+
``name`` argument. To override an inherited Python check, declare a new
161+
function with the same ``name`` in the extension profile:
162+
163+
.. code-block:: python
164+
165+
# In the extension profile's checks module
166+
from rocrate_validator.requirements.python import check
167+
168+
@check(name="Check Metadata File Descriptor entity existence")
169+
def overridden_check(self, ctx):
170+
# New implementation that replaces the inherited one
171+
...
172+
173+
Deactivating inherited checks
174+
-----------------------------
175+
176+
A child profile can also **fully deactivate** a check inherited from one of
177+
its ancestors. A deactivated check is skipped during validation and
178+
reported as such in the validation result. This is useful when an extension
179+
profile relaxes the parent's expectations, or replaces a coarse-grained
180+
check with a more specific one declared elsewhere in the same profile.
181+
182+
SHACL checks
183+
^^^^^^^^^^^^
184+
185+
Two complementary mechanisms are supported, depending on whether the shape
186+
to disable has an absolute IRI of its own.
187+
188+
**Shape with an absolute IRI** (e.g. a top-level ``NodeShape`` or a named
189+
``PropertyShape``): reference the shape by IRI from the extension profile
190+
and mark it as deactivated, without redeclaring it.
191+
192+
.. code-block:: turtle
193+
194+
# Extension profile
195+
<https://parent-profile/ShapeC> sh:deactivated true .
196+
197+
**Nested ``PropertyShape`` without an absolute IRI** (a property declared
198+
inline inside a parent ``NodeShape``): use the override-by-name mechanism
199+
described in the previous section. Declare a new ``PropertyShape`` in the
200+
extension profile with the same ``sh:name`` as the one to disable, and set
201+
``sh:deactivated true`` on it. This overrides the parent's
202+
``PropertyShape``, and the validator reports the resulting check as
203+
deactivated.
204+
205+
.. code-block:: turtle
206+
207+
# Extension profile — disables the inherited PropertyShape by sh:name
208+
ro:ShapeC
209+
a sh:NodeShape ;
210+
sh:name "The Shape C" ;
211+
sh:targetNode ro:ro-crate-metadata.json ;
212+
sh:property [
213+
a sh:PropertyShape ;
214+
sh:name "Check Metadata File Descriptor entity existence" ;
215+
sh:path rdf:type ;
216+
sh:deactivated true ;
217+
] .
218+
219+
.. note::
220+
221+
Cross-profile deactivation is scoped to the shape's transitive
222+
descendants: a ``sh:deactivated true`` triple declared by a profile
223+
that does not inherit (directly or transitively) from the shape's
224+
owning profile is ignored. This prevents unrelated profiles loaded in
225+
the same process from interfering with one another.
226+
227+
Python checks
228+
^^^^^^^^^^^^^
229+
230+
The ``@check`` decorator accepts a ``deactivated`` flag, mirroring SHACL's
231+
``sh:deactivated``. Combined with override-by-name, an extension profile
232+
can disable an inherited Python check by redeclaring it with
233+
``deactivated=True``:
234+
235+
.. code-block:: python
236+
237+
from rocrate_validator.requirements.python import check
238+
239+
@check(name="Check Metadata File Descriptor entity existence",
240+
deactivated=True)
241+
def disabled(self, ctx):
242+
# Body is irrelevant — the check is skipped during validation.
243+
return True
244+
97245
Running validator & tests during profile development
98246
----------------------------------------------------
99247

0 commit comments

Comments
 (0)