Skip to content

Commit c6d4eb9

Browse files
authored
👌 Improve schema validation performance (improve reduce_needs) (#1583)
1 parent 43ee1e6 commit c6d4eb9

2 files changed

Lines changed: 33 additions & 34 deletions

File tree

‎sphinx_needs/need_item.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,15 @@ def items(self) -> Iterable[tuple[str, Any]]:
669669
self._computed.items(),
670670
)
671671

672+
def iter_core_items(self) -> Iterable[tuple[str, Any]]:
673+
"""Return the core items of the need item."""
674+
return chain(
675+
self._core.items(),
676+
self._source.dict_repr.items(),
677+
self._content.dict_repr.items(),
678+
self._computed.items(),
679+
)
680+
672681
def __setitem__(self, key: str, value: Any) -> None:
673682
"""Set an item by key."""
674683
if key in self._immutable_core:

‎sphinx_needs/schema/core.py‎

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,21 @@ def validate_type_schema(
101101
"""Validate needs against a type schema."""
102102
need_2_warnings: dict[str, list[OntologyWarning]] = {}
103103

104+
schema_name = get_schema_name(schema)
104105
validator = (
105106
compile_validator(cast(NeedFieldsSchemaType, schema["select"]))
106107
if schema.get("select")
107108
else None
108109
)
110+
user_severity = SeverityEnum[schema["severity"]] if "severity" in schema else None
111+
local_network_schema: ValidateSchemaType = {}
112+
if "local" in schema["validate"]:
113+
local_network_schema["local"] = schema["validate"]["local"]
114+
if "network" in schema["validate"]:
115+
local_network_schema["network"] = schema["validate"]["network"]
109116

110117
for need in needs.values():
111118
# maintain state for nested network validation
112-
schema_name = get_schema_name(schema)
113119
if validator is not None:
114120
new_warnings_select = get_ontology_warnings(
115121
need,
@@ -126,14 +132,6 @@ def validate_type_schema(
126132
# need is not selected
127133
continue
128134

129-
user_severity = (
130-
SeverityEnum[schema["severity"]] if "severity" in schema else None
131-
)
132-
local_network_schema: ValidateSchemaType = {}
133-
if "local" in schema["validate"]:
134-
local_network_schema["local"] = schema["validate"]["local"]
135-
if "network" in schema["validate"]:
136-
local_network_schema["network"] = schema["validate"]["network"]
137135
_, new_warnings_recurse = recurse_validate_schemas(
138136
config,
139137
need,
@@ -450,43 +448,35 @@ def reduce_need(
450448
- if they are links and the list is not empty
451449
- if they are part of the user provided schema
452450
453-
The function coerces extra option strings to their specified JSON schema types:
454-
-> integer -> int
455-
-> number -> float
456-
-> boolean -> bool
457-
458451
:param need: The need to reduce.
459452
:param json_schema: The user provided and merged JSON merge.
460453
"""
461454
reduced_need: dict[str, Any] = {}
462-
for field, value in need.items():
463-
keep = False
464-
schema_field = field_properties[field]
465455

466-
if schema_field["field_type"] == "extra" and not (
467-
"default" in schema_field and value == schema_field["default"]
468-
):
456+
for field, value in need.iter_extra_items():
457+
if value is None:
458+
# value is not provided
459+
continue
460+
schema_field = field_properties[field]
461+
if not ("default" in schema_field and value == schema_field["default"]):
469462
# keep explicitly set extra options
470-
keep = True
463+
reduced_need[field] = value
471464

472-
if schema_field["field_type"] == "links" and value:
465+
for field, value in need.iter_links_items():
466+
if value:
473467
# keep non-empty link fields
474-
keep = True
468+
reduced_need[field] = value
475469

476-
if (
477-
schema_field["field_type"] == "core"
478-
and field in schema_properties
479-
and not ("default" in schema_field and value == schema_field["default"])
470+
for field, value in need.iter_core_items():
471+
if value is None:
472+
# value is not provided
473+
continue
474+
schema_field = field_properties[field]
475+
if field in schema_properties and not (
476+
"default" in schema_field and value == schema_field["default"]
480477
):
481478
# keep core field, it has no default or differs from the default and
482479
# is part of the user provided schema
483-
keep = True
484-
485-
if value is None:
486-
# value is not provided
487-
keep = False
488-
489-
if keep:
490480
reduced_need[field] = value
491481

492482
return reduced_need

0 commit comments

Comments
 (0)