Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion requirements-testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ pytest-cov == 6.0.*
pytest-timeout == 2.3.*
pytest-xdist == 3.6.*
types-PyYAML ~= 6.0
black == 24.*
black == 25.*
ruff == 0.9.*
mypy == 1.15.*
6 changes: 5 additions & 1 deletion src/openjd/model/_internal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
from ._combination_expr import Parser as CombinationExpressionParser
from ._combination_expr import ProductNode as CombinationExpressionProductNode
from ._create_job import instantiate_model
from ._param_space_dim_validation import validate_step_parameter_space_dimensions
from ._param_space_dim_validation import (
validate_step_parameter_space_chunk_constraint,
validate_step_parameter_space_dimensions,
)
from ._variable_reference_validation import prevalidate_model_template_variable_references

__all__ = (
"instantiate_model",
"prevalidate_model_template_variable_references",
"validate_step_parameter_space_chunk_constraint",
"validate_step_parameter_space_dimensions",
"validate_unique_elements",
"CombinationExpressionAssociationNode",
Expand Down
46 changes: 42 additions & 4 deletions src/openjd/model/_internal/_param_space_dim_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,42 @@ def validate_step_parameter_space_dimensions(
ExpressionError if the combination expression violates constraints.
"""
parse_tree = Parser().parse(combination)
_validate_expr_tree(parse_tree, parameter_range_lengths)
_validate_expr_tree_dimensions(parse_tree, parameter_range_lengths)


def _validate_expr_tree(root: Node, parameter_range_lengths: dict[str, int]) -> int:
def validate_step_parameter_space_chunk_constraint(chunk_parameter: str, parse_tree: Node) -> bool:
"""This validates that the task parameter of type CHUNK[INT] never appears
within scope of an associative expression. A single chunk consists of
individual values from the non-chunk parameters, and a set of values from the
chunk parameter. With this restriction, the session script code can interpret
these parameters easily, while without it the specification would need to define
how the associations are represented and provided to the script.

Raises:
ExpressionError if the combination expression violates the chunk constraint.
"""
# Returns True if the subtree includes the chunk parameter, otherwise False
if isinstance(parse_tree, IdentifierNode):
return parse_tree.parameter == chunk_parameter
elif isinstance(parse_tree, AssociationNode):
for child in parse_tree.children:
if validate_step_parameter_space_chunk_constraint(chunk_parameter, child):
raise ExpressionError(
(
f"CHUNK[INT] parameter {chunk_parameter} must not be part of an associative expression. "
)
)
return False
else:
# For type hinting
assert isinstance(parse_tree, ProductNode)
return any(
validate_step_parameter_space_chunk_constraint(chunk_parameter, child)
for child in parse_tree.children
)


def _validate_expr_tree_dimensions(root: Node, parameter_range_lengths: dict[str, int]) -> int:
# Returns the length of the subtree while recursively validating it.
if isinstance(root, IdentifierNode):
name = root.parameter
Expand All @@ -35,7 +67,8 @@ def _validate_expr_tree(root: Node, parameter_range_lengths: dict[str, int]) ->
# Association requires that all arguments are the exact same length.
# Ensure that is the case
arg_lengths = tuple(
_validate_expr_tree(child, parameter_range_lengths) for child in root.children
_validate_expr_tree_dimensions(child, parameter_range_lengths)
for child in root.children
)
if len(set(arg_lengths)) > 1:
raise ExpressionError(
Expand All @@ -49,5 +82,10 @@ def _validate_expr_tree(root: Node, parameter_range_lengths: dict[str, int]) ->
# For type hinting
assert isinstance(root, ProductNode)
return reduce(
mul, (_validate_expr_tree(child, parameter_range_lengths) for child in root.children), 1
mul,
(
_validate_expr_tree_dimensions(child, parameter_range_lengths)
for child in root.children
),
1,
)
4 changes: 4 additions & 0 deletions src/openjd/model/v2023_09/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
CancelationMethodNotifyThenTerminate,
CancelationMethodTerminate,
CancelationMode,
ChunkIntTaskParameterDefinition,
CombinationExpr,
CommandString,
DataString,
Expand Down Expand Up @@ -73,6 +74,7 @@
StepTemplateList,
StringRangeList,
StringTaskParameterDefinition,
TaskChunksDefinition,
TaskParameterList,
TaskParameterStringValue,
TaskParameterStringValueAsJob,
Expand Down Expand Up @@ -101,6 +103,7 @@
"CancelationMethodNotifyThenTerminate",
"CancelationMethodTerminate",
"CancelationMode",
"ChunkIntTaskParameterDefinition",
"CombinationExpr",
"CommandString",
"DataString",
Expand Down Expand Up @@ -153,6 +156,7 @@
"StepTemplateList",
"StringRangeList",
"StringTaskParameterDefinition",
"TaskChunksDefinition",
"TaskParameterList",
"TaskParameterStringValue",
"TaskParameterStringValueAsJob",
Expand Down
Loading