Skip to content

Commit c94fefd

Browse files
committed
Enhance reduce_need logic to improve handling of default values and unevaluated properties; update related tests
1 parent 97427e5 commit c94fefd

3 files changed

Lines changed: 178 additions & 11 deletions

File tree

sphinx_needs/schema/core.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -484,14 +484,17 @@ def reduce_need(
484484
continue
485485

486486
schema_field = field_properties[field]
487-
if "default" in schema_field and (
488-
(schema_field["default"] is None)
489-
or (schema_field["default"] == "" and value != "")
490-
):
491-
# there is a default and if it is None, and the value is not, keep it
492-
# or if the default is "" and the value is not "", keep it
493-
# this covers the SN5 (no-schema) and SN6 (with-schema) cases
494-
reduced_need[field] = value
487+
if "default" in schema_field:
488+
if schema_field["default"] is None:
489+
# keep all non-None values - they are actively set
490+
reduced_need[field] = value
491+
elif schema_field["default"] == "":
492+
# SN5 case: only keep non-empty values
493+
if value != "":
494+
reduced_need[field] = value
495+
else:
496+
# keep the value - there is a default that is not None/"" or a real RST value
497+
reduced_need[field] = value
495498

496499
for field, value in need.iter_links_items():
497500
if value:
@@ -503,6 +506,7 @@ def reduce_need(
503506
continue
504507

505508
if field in schema_properties:
509+
# actively included by schema - include to validate constraints
506510
reduced_need[field] = value
507511
continue
508512

tests/schema/__snapshots__/test_schema.ambr

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4792,7 +4792,7 @@
47924792
}),
47934793
})
47944794
# ---
4795-
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_core_field_in_schema_and_invalid]
4795+
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_core_status_in_schema_and_invalid]
47964796
'''
47974797
ERROR: Need 'IMPL_1' has schema violations:
47984798
Severity: violation
@@ -4803,7 +4803,7 @@
48034803

48044804
'''
48054805
# ---
4806-
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_core_field_in_schema_and_invalid].1
4806+
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_core_status_in_schema_and_invalid].1
48074807
dict({
48084808
'validated_needs_count': 1,
48094809
'validation_warnings': dict({
@@ -4956,6 +4956,102 @@
49564956
}),
49574957
})
49584958
# ---
4959+
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_error_core_status_with_default]
4960+
'''
4961+
ERROR: Need 'IMPL_1' has schema violations:
4962+
Severity: violation
4963+
Need path: IMPL_1
4964+
Schema path: [0] > local > unevaluatedProperties
4965+
Schema message: Unevaluated properties are not allowed ('status' was unexpected) [sn_schema_violation.local_fail]
4966+
4967+
'''
4968+
# ---
4969+
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_error_core_status_with_default].1
4970+
dict({
4971+
'validated_needs_count': 1,
4972+
'validation_warnings': dict({
4973+
'IMPL_1': list([
4974+
dict({
4975+
'children': list([
4976+
]),
4977+
'details': dict({
4978+
'need_path': 'IMPL_1',
4979+
'schema_path': '[0] > local > unevaluatedProperties',
4980+
'severity': 'violation',
4981+
'validation_msg': "Unevaluated properties are not allowed ('status' was unexpected)",
4982+
}),
4983+
'log_lvl': 'error',
4984+
'subtype': 'local_fail',
4985+
'type': 'sn_schema_violation',
4986+
}),
4987+
]),
4988+
}),
4989+
})
4990+
# ---
4991+
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_error_core_tags_with_default]
4992+
'''
4993+
ERROR: Need 'IMPL_1' has schema violations:
4994+
Severity: violation
4995+
Need path: IMPL_1
4996+
Schema path: [0] > local > unevaluatedProperties
4997+
Schema message: Unevaluated properties are not allowed ('tags' was unexpected) [sn_schema_violation.local_fail]
4998+
4999+
'''
5000+
# ---
5001+
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_error_core_tags_with_default].1
5002+
dict({
5003+
'validated_needs_count': 1,
5004+
'validation_warnings': dict({
5005+
'IMPL_1': list([
5006+
dict({
5007+
'children': list([
5008+
]),
5009+
'details': dict({
5010+
'need_path': 'IMPL_1',
5011+
'schema_path': '[0] > local > unevaluatedProperties',
5012+
'severity': 'violation',
5013+
'validation_msg': "Unevaluated properties are not allowed ('tags' was unexpected)",
5014+
}),
5015+
'log_lvl': 'error',
5016+
'subtype': 'local_fail',
5017+
'type': 'sn_schema_violation',
5018+
}),
5019+
]),
5020+
}),
5021+
})
5022+
# ---
5023+
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_error_extra_with_default]
5024+
'''
5025+
ERROR: Need 'IMPL_1' has schema violations:
5026+
Severity: violation
5027+
Need path: IMPL_1
5028+
Schema path: [0] > local > unevaluatedProperties
5029+
Schema message: Unevaluated properties are not allowed ('comment' was unexpected) [sn_schema_violation.local_fail]
5030+
5031+
'''
5032+
# ---
5033+
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_error_extra_with_default].1
5034+
dict({
5035+
'validated_needs_count': 1,
5036+
'validation_warnings': dict({
5037+
'IMPL_1': list([
5038+
dict({
5039+
'children': list([
5040+
]),
5041+
'details': dict({
5042+
'need_path': 'IMPL_1',
5043+
'schema_path': '[0] > local > unevaluatedProperties',
5044+
'severity': 'violation',
5045+
'validation_msg': "Unevaluated properties are not allowed ('comment' was unexpected)",
5046+
}),
5047+
'log_lvl': 'error',
5048+
'subtype': 'local_fail',
5049+
'type': 'sn_schema_violation',
5050+
}),
5051+
]),
5052+
}),
5053+
})
5054+
# ---
49595055
# name: test_schemas[schema/fixtures/unevaluated-unevaluated_error_extra_with_schema_given_in_rst_no_constraint]
49605056
'''
49615057
ERROR: Need 'IMPL_1' has schema violations:

tests/schema/fixtures/unevaluated.yml

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,29 @@ unevaluated_error_extra_with_schema_given_in_rst_no_constraint:
163163
properties: {"asil": {}}
164164
unevaluatedProperties: false
165165

166+
unevaluated_error_extra_with_default:
167+
# should complain, the comment field is set via default, and it will appear in the
168+
# unevaluatedProperties evaluation as forbidden additional field
169+
conf: |
170+
extensions = ["sphinx_needs"]
171+
needs_from_toml = "ubproject.toml"
172+
needs_schema_definitions_from_json = "schemas.json"
173+
ubproject: |
174+
[needs.fields.asil]
175+
[needs.fields.comment]
176+
schema.type = "string"
177+
default = "default"
178+
rst: |
179+
.. impl:: title
180+
:id: IMPL_1
181+
:asil: QM
182+
schemas:
183+
schemas:
184+
- validate:
185+
local:
186+
properties: {"asil": {}}
187+
unevaluatedProperties: false
188+
166189
unevaluated_error_allof:
167190
# check whether unevaluatedProperties implementation applies to combined schemas (allOf)
168191
# should complain about "approved" given as additional field, but not for comment or asil
@@ -262,7 +285,7 @@ unevaluated_core_status_set_not_in_schema:
262285
properties: {"asil": {}}
263286
unevaluatedProperties: false
264287

265-
unevaluated_core_field_in_schema_and_invalid:
288+
unevaluated_core_status_in_schema_and_invalid:
266289
# should complain about status, because it is part of the user schema and actively set,
267290
# therefore it must be kept in the reduced need and validated
268291
conf: |
@@ -283,6 +306,28 @@ unevaluated_core_field_in_schema_and_invalid:
283306
properties: {"asil": {}, "status": {"enum": ["CLOSED"]}}
284307
unevaluatedProperties: false
285308

309+
unevaluated_error_core_status_with_default:
310+
# should complain, the status field has a default, and it will appear in the
311+
# unevaluatedProperties evaluation as forbidden additional field
312+
conf: |
313+
extensions = ["sphinx_needs"]
314+
needs_from_toml = "ubproject.toml"
315+
needs_schema_definitions_from_json = "schemas.json"
316+
ubproject: |
317+
[needs.fields.asil]
318+
[needs.fields.status]
319+
default = "default"
320+
rst: |
321+
.. impl:: title
322+
:id: IMPL_1
323+
:asil: QM
324+
schemas:
325+
schemas:
326+
- validate:
327+
local:
328+
properties: {"asil": {}}
329+
unevaluatedProperties: false
330+
286331
unevaluated_core_tags_set_not_in_schema:
287332
# should complain, because the core field tags is treated like an extra field,
288333
# so it is kept when explicitly set and triggers unevaluatedProperties.
@@ -329,6 +374,28 @@ unevaluated_core_tags_in_schema_and_invalid:
329374
items: {type: string, enum: ["tag_b"]}
330375
unevaluatedProperties: false
331376

377+
unevaluated_error_core_tags_with_default:
378+
# should complain, the tags field has a default, and it will appear in the
379+
# unevaluatedProperties evaluation as forbidden additional field
380+
conf: |
381+
extensions = ["sphinx_needs"]
382+
needs_from_toml = "ubproject.toml"
383+
needs_schema_definitions_from_json = "schemas.json"
384+
ubproject: |
385+
[needs.fields.asil]
386+
[needs.fields.tags]
387+
default = ["default"]
388+
rst: |
389+
.. impl:: title
390+
:id: IMPL_1
391+
:asil: QM
392+
schemas:
393+
schemas:
394+
- validate:
395+
local:
396+
properties: {"asil": {}}
397+
unevaluatedProperties: false
398+
332399
unevaluated_core_docname_in_schema_and_invalid:
333400
# should complain about docname, because it is part of the user schema,
334401
# therefore it is kept in the reduced need and validated

0 commit comments

Comments
 (0)