-
Notifications
You must be signed in to change notification settings - Fork 8
Support IncludeCondition in ParameterRefEntry elements #216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
76a933d
86d67e8
53ce595
f2c5983
f58ee97
4cac7d7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,6 @@ | ||||||||
| """Module with XTCE models related to SequenceContainers""" | ||||||||
|
|
||||||||
| import warnings | ||||||||
| from dataclasses import dataclass, field | ||||||||
| from typing import Any, Union | ||||||||
|
|
||||||||
|
|
@@ -12,6 +13,171 @@ | |||||||
| from space_packet_parser.xtce import comparisons, parameter_types, parameters | ||||||||
|
|
||||||||
|
|
||||||||
| @dataclass | ||||||||
| class ParameterRefEntry(common.Parseable, common.XmlObject): | ||||||||
| """<xtce:ParameterRefEntry> | ||||||||
|
|
||||||||
| Represents a reference to a parameter in an EntryList, with optional conditional inclusion | ||||||||
| and repeat logic. | ||||||||
|
|
||||||||
| Parameters | ||||||||
| ---------- | ||||||||
| parameter_ref : str | ||||||||
| Name reference to the Parameter | ||||||||
| include_condition : Optional[comparisons.MatchCriteria] | ||||||||
| Condition for inclusion. If None, parameter is always included. | ||||||||
| repeat_entry : Optional[Any] | ||||||||
| Repeat information. Not currently supported - will raise NotImplementedError during parse. | ||||||||
| """ | ||||||||
|
|
||||||||
| parameter_ref: str | ||||||||
| include_condition: Optional[comparisons.MatchCriteria] = None | ||||||||
| repeat_entry: Optional[Any] = None | ||||||||
|
|
||||||||
| def parse(self, packet: spp.SpacePacket, parameter_lookup: dict[str, parameters.Parameter]) -> None: | ||||||||
| """Parse the parameter reference entry, handling conditional inclusion. | ||||||||
|
|
||||||||
| Parameters | ||||||||
| ---------- | ||||||||
| packet : spp.SpacePacket | ||||||||
| The packet being parsed | ||||||||
| parameter_lookup : dict[str, parameters.Parameter] | ||||||||
| Dictionary to look up parameter objects by name | ||||||||
|
|
||||||||
| Raises | ||||||||
| ------ | ||||||||
| NotImplementedError | ||||||||
| If RepeatEntry is specified | ||||||||
| KeyError | ||||||||
| If the referenced parameter is not found in parameter_lookup | ||||||||
| """ | ||||||||
| # Check if repeat_entry is specified | ||||||||
| if self.repeat_entry is not None: | ||||||||
| raise NotImplementedError("RepeatEntry is not currently supported in parsing") | ||||||||
|
|
||||||||
| # Evaluate include condition if it exists | ||||||||
| if self.include_condition is not None: | ||||||||
| if not self.include_condition.evaluate(packet): | ||||||||
| # Condition is False, skip this parameter | ||||||||
| return | ||||||||
|
|
||||||||
| # Parse the parameter | ||||||||
| try: | ||||||||
| parameter = parameter_lookup[self.parameter_ref] | ||||||||
| except KeyError as err: | ||||||||
| raise KeyError( | ||||||||
| f"Parameter '{self.parameter_ref}' referenced in ParameterRefEntry not found in parameter lookup. " | ||||||||
| f"Available parameters: {list(parameter_lookup.keys())}" | ||||||||
| ) from err | ||||||||
| parameter.parse(packet) | ||||||||
|
|
||||||||
| @classmethod | ||||||||
| def from_xml( | ||||||||
| cls, | ||||||||
| element: ElementTree.Element, | ||||||||
| *, | ||||||||
| tree: Optional[ElementTree.ElementTree] = None, | ||||||||
| parameter_lookup: Optional[dict[str, parameters.Parameter]] = None, | ||||||||
| parameter_type_lookup: Optional[dict[str, parameter_types.ParameterType]] = None, | ||||||||
| container_lookup: Optional[dict[str, Any]] = None, | ||||||||
| ) -> "ParameterRefEntry": | ||||||||
| """Create a ParameterRefEntry from an XML element. | ||||||||
|
|
||||||||
| Parameters | ||||||||
| ---------- | ||||||||
| element : ElementTree.Element | ||||||||
| The ParameterRefEntry XML element | ||||||||
| tree : Optional[ElementTree.ElementTree] | ||||||||
| Full XTCE tree | ||||||||
| parameter_lookup : Optional[dict[str, parameters.Parameter]] | ||||||||
| Ignored | ||||||||
| parameter_type_lookup : Optional[dict[str, parameter_types.ParameterType]] | ||||||||
| Ignored | ||||||||
| container_lookup : Optional[dict[str, Any]] | ||||||||
| Ignored | ||||||||
|
|
||||||||
| Returns | ||||||||
| ------- | ||||||||
| : ParameterRefEntry | ||||||||
| """ | ||||||||
| parameter_ref = element.attrib["parameterRef"] | ||||||||
|
|
||||||||
| # Parse optional IncludeCondition | ||||||||
| include_condition = None | ||||||||
| if (include_cond_elem := element.find("IncludeCondition")) is not None: | ||||||||
| # IncludeCondition contains a single MatchCriteria element (Comparison, ComparisonList, or BooleanExpression) | ||||||||
| if (comparison_list_elem := include_cond_elem.find("ComparisonList")) is not None: | ||||||||
| # ComparisonList contains multiple Comparison elements with AND semantics per XTCE spec | ||||||||
| # Note: The existing restriction_criteria uses the same pattern (iterfind("*")) | ||||||||
| # to iterate over Comparison elements in a ComparisonList | ||||||||
| comparisons_list = [ | ||||||||
| comparisons.Comparison.from_xml(comp) for comp in comparison_list_elem.iterfind("*") | ||||||||
| ] | ||||||||
| # LIMITATION: MatchCriteria interface expects a single object, but ComparisonList | ||||||||
| # requires AND logic across multiple comparisons. For now, we only support single | ||||||||
| # comparisons in ComparisonList. Full AND logic would require a new MatchCriteria | ||||||||
| # subclass or modifying include_condition to accept a list of MatchCriteria. | ||||||||
| # This follows the same limitation pattern used in restriction_criteria where | ||||||||
| # multiple MatchCriteria are stored in a list on the SequenceContainer itself. | ||||||||
|
Comment on lines
+116
to
+121
|
||||||||
| if len(comparisons_list) == 1: | ||||||||
| include_condition = comparisons_list[0] | ||||||||
| else: | ||||||||
| # For multiple comparisons, warn and use only the first one | ||||||||
| warnings.warn( | ||||||||
| f"ComparisonList with {len(comparisons_list)} comparisons in IncludeCondition " | ||||||||
| f"for parameter '{parameter_ref}'. Only the first comparison will be evaluated. " | ||||||||
| f"Full AND logic for ComparisonList in IncludeCondition requires architectural " | ||||||||
|
||||||||
| f"Full AND logic for ComparisonList in IncludeCondition requires architectural " | |
| f"This may result in incorrect packet parsing if the XTCE definition relies on multiple comparisons " | |
| f"being evaluated with AND logic. Full AND logic for ComparisonList in IncludeCondition requires architectural " |
Copilot
AI
Nov 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The warning is issued during serialization but doesn't indicate whether this could cause issues when the XML is read back. Consider adding information about whether round-tripping (parse XML -> serialize -> parse again) will preserve the RepeatEntry information or if it will be lost.
| "The RepeatEntry element will not be included in the XML output.", | |
| "The RepeatEntry element will not be included in the XML output. " | |
| "If you parse XML containing RepeatEntry and then serialize it again, the RepeatEntry information will be lost.", |
Uh oh!
There was an error while loading. Please reload this page.