Support IncludeCondition in ParameterRefEntry elements
Description
Implements XTCE 5.3.4 IncludeCondition support for conditional parameter parsing based on previously-parsed values.
Implementation
-
New
ParameterRefEntryclass wraps parameter references with optionalIncludeConditionandRepeatEntry(placeholder)- Evaluates conditions against partially-parsed packet state using existing
MatchCriteriainfrastructure - Skips parameter parsing when condition evaluates false, leaving bit position unchanged
- Raises
NotImplementedErrorfor RepeatEntry during parse
- Evaluates conditions against partially-parsed packet state using existing
-
Updated
SequenceContainer- Creates
ParameterRefEntryobjects only when IncludeCondition/RepeatEntry present (backward compatible) - Stores
_parameter_lookupfor runtime parameter resolution - Warns on unrecognized EntryList element types
- Updated type hints:
entry_list: list[Union[ParameterRefEntry, Parameter, SequenceContainer]]
- Creates
Example
# XTCE with conditional parameter
<ParameterRefEntry parameterRef="CheckSum">
<IncludeCondition>
<Comparison parameterRef="CSFlag" value="1" comparisonOperator="=="/>
</IncludeCondition>
</ParameterRefEntry>
# CheckSum parsed only when CSFlag == 1
packet = SpacePacket(binary_data=b"\x01\x04\xd2...") # CSFlag=1
container.parse(packet)
assert "CheckSum" in packet
packet = SpacePacket(binary_data=b"\x00...") # CSFlag=0
container.parse(packet)
assert "CheckSum" not in packet # Skipped, no position advance
Limitations
ComparisonList with multiple comparisons evaluates only first element (warns user). Full AND logic requires architectural changes to support multiple MatchCriteria per condition.
Checklist
- [x] Changes are fully implemented without dangling issues or TODO items
- [x] Deprecated/superseded code is removed or marked with deprecation warning
- [x] Current dependencies have been properly specified and old dependencies removed
- [x] New code/functionality has accompanying tests and any old tests have been updated to match any new assumptions
- [ ] The changelog.md has been updated
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
www.omg.org
- Triggering command:
/usr/bin/python3 /home/REDACTED/.local/bin/pytest --color=yes --cov --cov-report=term-missing(dns block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to the custom allowlist in this repository's Copilot coding agent settings (admins only)
Original prompt
This section details on the original issue you should resolve
<issue_title>Support IncludeCondition in ParameterRefEntry elements</issue_title>
<issue_description>## Summary
Space Packet Parser supports much of the XTCE XML schema but the IncludeCondition element within ParameterRefEntry is not yet handled.
XTCE Reference: Section 5.3.4 (p. 235) of CCSDS 660.1-G-2
IncludeCondition elements allow conditional inclusion of a ParameterRefEntry in the EntryList of a SequenceContainer. The condition can only reference previously parsed parameters in the packet. During parsing, the partially-parsed packet object is available to look up these values.
XTCE Example
<xtce:SequenceContainer name="ConditionalExample">
<xtce:EntryList>
<xtce:ParameterRefEntry parameterRef="CSFlag"/>
<xtce:ParameterRefEntry parameterRef="CheckSum">
<xtce:IncludeCondition>
<xtce:Comparison value="1" parameterRef="CSFlag"/>
</xtce:IncludeCondition>
</xtce:ParameterRefEntry>
</xtce:EntryList>
</xtce:SequenceContainer>
In this example, CheckSum is only parsed if the previously-parsed CSFlag parameter equals 1.
Implementation
Current Architecture Limitation
Currently in containers.py lines 111-131, we parse SequenceContainer/EntryList elements into a simple entry_list of Parameter and SequenceContainer objects. This doesn't support:
- Conditional inclusion (via
IncludeCondition) - Repeated parameters (via
RepeatEntry) - Other ParameterRefEntry attributes
Create New ParameterRefEntry Class
Create a new class in containers.py to represent the ParameterRefEntry XML element with its optional child elements.
Attributes:
parameter_ref: str- Name reference to the Parameterrepeat_entry: Optional[RepeatEntry]- Repeat information (raise NotImplementedError for now)include_condition: Optional[MatchCriteria]- Condition for inclusion (use existing MatchCriteria types from comparisons.py)
Inheritance:
- Must inherit from
common.XmlObjectandcommon.Parseable - Implement
from_xml()to parse the XML structure - Implement
to_xml()for serialization - Implement
parse()to handle conditional parsing logic
Parse Logic:
- If
include_conditionexists, evaluate it using the current packet state - If condition is False (or None and parameter should be skipped), return early without parsing
- If
repeat_entryexists, raiseNotImplementedErrorwith message: "RepeatEntry is not currently supported in parsing" - Otherwise, resolve the parameter reference and parse it normally
Scope Constraint (XTCE 5.8.4):
The IncludeCondition can only reference parameters that have already been parsed in the current container (previous entries in the EntryList). References to "future" parameters in the same container must be rejected or produce a warning.
Update SequenceContainer.from_xml()
Modify the loop at lines 111-131 to create ParameterRefEntry objects instead of directly referencing Parameter objects:
elif entry_tag_name == "ParameterRefEntry":
parameter_name = entry.attrib["parameterRef"]
# Parse optional IncludeCondition
include_condition = None
if (include_cond_elem := entry.find("IncludeCondition")) is not None:
# Use existing MatchCriteria parsing logic from comparisons module
include_condition = cls._parse_include_condition(include_cond_elem)
# Parse optional RepeatEntry
repeat_entry = None
if entry.find("RepeatEntry") is not None:
repeat_entry = ... # Parse but will raise NotImplementedError during parse()
# Create ParameterRefEntry object with parameter reference and conditions
param_ref_entry = ParameterRefEntry(
parameter_ref=parameter_name,
include_condition=include_condition,
repeat_entry=repeat_entry
)
entry_list.append(param_ref_entry)
Add Warning for Unrecognized EntryList Elements
At the end of the if-elif chain (after line 131 in current code), add:
else:
warnings.warn(
f"Unrecognized entry type '{entry_tag_name}' in EntryList for container "
f"'{element.attrib['name']}'. Supported types: ParameterRefEntry, ContainerRefEntry. "
f"Skipping this entry.",
category=UserWarning
)
continue
Change Type of entry_list
The entry_list attribute in SequenceContainer should be updated to:
entry_list: list[Union[ParameterRefEntry, SequenceContainer]]
This replaces the current list[Union[parameters.Parameter, SequenceContainer]].
Backward Compatibility: The SequenceContainer.parse() method must be updated to handle ParameterRefEntry objects, which will need to resolve their parameter references and evaluate conditions during parsing.
Test Cases
- Simple condition: Parameter included only when flag=1, exclud...
- Fixes lasp/space_packet_parser#28
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.
Codecov Report
:x: Patch coverage is 96.72619% with 11 lines in your changes missing coverage. Please review.
:white_check_mark: Project coverage is 94.11%. Comparing base (4dec594) to head (f015995).
| Files with missing lines | Patch % | Lines |
|---|---|---|
| space_packet_parser/xtce/containers.py | 82.81% | 11 Missing :warning: |
Additional details and impacted files
@@ Coverage Diff @@
## main #216 +/- ##
==========================================
+ Coverage 93.87% 94.11% +0.23%
==========================================
Files 46 48 +2
Lines 3594 3924 +330
==========================================
+ Hits 3374 3693 +319
- Misses 220 231 +11
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
pre-commit.ci autofix